Построить объект из нескольких источников Java 8 с пользовательской функцией - PullRequest
4 голосов
/ 12 апреля 2019

У меня есть несколько источников (Карты), где я храню данные, относящиеся к различным атрибутам, предназначенным для создания конечного объекта с идентификатором.Эти карты имеют различные структуры в соответствии с этим шаблоном:

Карта

  • id - это идентификатор моего конечного объекта. FinalObject
  • X1, X2 - атрибуты моего конечного объекта. FinalObject

в реальном коде у меня есть несколько карт следующим образом:

Map<Integer, String> descriptions;
Map<Integer, Double> prices;
Map<Integer, Double> quantities;
Map<Integer, String> currencies;

Я могу объединить поток своих коллекций с Stream.of(), но у меня есть две проблемы,структура разнородных карт, а также для каждой записи я хочу создать объект Final способом Java8.

Я считаю, что мой MultipleFunction как BiFunction, мои определенные атрибуты для FinalObject - аргументы.Это нормально, как дизайн?

Какие-либо мнения или советы?

Результат слияния будет выглядеть так:

Stream.of(descriptions.entrySet(), prices.entrySet(), quantities.entrySet(), currencies.entrySet())
        .flatMap(Set::stream)
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> new FinalObject(description, price, quantity, currency)));

Этот код не компилируется идля моей проблемы лучшее понимание.

Ответы [ 2 ]

6 голосов
/ 12 апреля 2019

Получить поток номеров ID ...

descriptions.keySet().stream()

... затем найдите идентификаторы на четырех картах:

descriptions.keySet().stream()
    .map(id -> {
         String description = descriptions.get(id);
         Double price       = prices      .get(id);
         Double quantity    = quantities  .get(id);
         String currency    = currencies  .get(id);

         return new FinalObject(description, price, quantity, currency);
    });

Предполагается, что descriptions имеет запись для каждого идентификатора. Если нет, отрегулируйте его так, как считаете нужным.

Если хотите, вы можете сохранить один поиск, выполнив итерации по entrySet() вместо keySet().

descriptions.entrySet().stream()
    .map(e -> {
         int id = e.getKey();

         String description = e.getValue();
         Double price       = prices    .get(id);
         Double quantity    = quantities.get(id);
         String currency    = currencies.get(id);

         return new FinalObject(description, price, quantity, currency);
    });
2 голосов
/ 12 апреля 2019

Предположим, что FinalObject является неизменным и имеет следующую структуру:

public static class FinalObject {

    private final String description;
    private final Double price;
    private final Double quantity;
    private final String currency;

    // constructor

Сначала создайте набор со всеми идентификаторами из карт.По характеристикам Set значения различны:

final Set<Integer> idSet = new HashSet<>();
idSet.addAll(descriptions.keySet());
idSet.addAll(prices.keySet());
idSet.addAll(quantities.keySet());
idSet.addAll(currencies.keySet());

Тогда вы можете использовать довольно аккуратным и простым способом для создания объектов:

final List<FinalObject> list = idSet.stream()
    .map(id -> new FinalObject(
            descriptions.get(id),
            prices.get(id),
            quantities.get(id),
            currencies.get(id)))
    .collect(Collectors.toList());
...