使用自定义函数从多个源Java 8构造对象

时间:2019-04-12 13:13:46

标签: java design-patterns java-8 java-stream

我有多个来源(地图),我在其中存储与旨在构造具有ID的最终对象的不同属性有关的数据。这些地图根据此模式具有不同的结构:

地图

  • id是我的最终对象FinalObject的标识符
  • X1,X2是我的最终对象FinalObject的属性

在真实代码中,我有以下几张地图:

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

我可以将集合的流与Stream.of()合并,但是我要处理两个问题,即异构映射的结构以及我想以Java8方式创建Final对象的每个条目的问题。 / p>

我将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 个答案:

答案 0 :(得分:6)

获取ID码流...

descriptions.keySet().stream()

...然后在四个地图中查找ID:

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的每个ID都有一个条目。如果没有,请根据自己的喜好进行调整。

如果愿意,可以通过遍历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);
    });

答案 1 :(得分:2)

让我们假设FinalObject是不可变的,并且具有以下结构:

public static class FinalObject {

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

    // constructor

首先使用地图中的所有ID创建一个集合。通过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());