Java流形成了一个地图问题

时间:2017-08-09 04:02:49

标签: java java-8 java-stream

我正在研究一个框架,我们正在尝试将传统循环转换为流。我的问题是我写了两个单独的逻辑来获得价格和颜色,但我想将它们合并在一起以便它可以呈现

获取价格值的代码

List<Double> productPrices = product.getUpcs()
            .stream()
            .map(e -> e.getUpcDetails().getPrice().getRetail().getPriceValue())
            .distinct()
            .sorted(Comparator.reverseOrder())
            .collect(Collectors.toList());

获取价格下的颜色的代码

      product.getUpcs()
            .stream()
            .filter(e -> e.getUpcDetails().getPrice().getRetail().getPriceValue() == 74.5)
            .flatMap(e -> e.getUpcDetails().getAttributes().stream())
            .filter(e2 -> e2.getName().contentEquals("COLOR"))
            .forEach(e3 -> System.out.println(e3.getValues().get(0).get("value")));

我在上面的部分中对价格进行了编码以获取颜色,相反,我希望将其作为价格列表中的输入并获得输出

Map<Double,List<colors>
output Map<75.4, {blue,black,orange}> 

我尝试将这两者合并都没有成功,任何帮助都会得到满足。

2 个答案:

答案 0 :(得分:1)

我建议你检查一下this or similar tutorial,以便了解它是如何工作的。

解决方案的关键是了解Collectors.groupingBy()功能。作为旁注,它还显示了在Java中处理定价信息的更好方法。

但你需要做的是这样的事情:

 Map<Double, Set<String>> productPrices = product
            .stream()
            .map(e -> e.getUpcDetails())
            .collect(
                    Collectors.groupingBy(Details::getPrice,
                    Collectors.mapping(Details::getColors, Collectors.collectingAndThen(
                            Collectors.toList(),
                            (set) -> set
                                    .stream()
                                    .flatMap(Collection::stream)
                                    .collect(Collectors.toSet())))

            ));

由于你的问题对于所涉及的类的细节有点不清楚,我假设这个简单的类结构:

class Details {
    private double price;
    private List<String> colors;

    double getPrice() { return price; }
    List<String> getColors() { return colors; }
}

class Product {
    private Details details;

    Details getUpcDetails() { return details; }
}

```

可以优化上面的代码,但我特别留下了在映射收集器中过滤和映射颜色的可能性。

答案 1 :(得分:1)

您可以先将第二个流转换为获得List个产品的方法(假设按价格过滤/分组)并将其转换为List种颜色:

List<Color> productsToColors(final List<Product> products) {
    return products.stream()
        .flatMap(e -> e.getUpcDetails().getAttributes().stream())
        .filter(e2 -> e2.getName().contentEquals("COLOR"))
        .map(e3 -> e3.getValues().get(0).get("value"))
        .collect(toList());
}

您可以使用groupingBy收集器在List中按价格收集所有产品,然后在第二个流中创建第二个流,productsToColors方法获取您想要的地图:

Map<Double, List<Color>> colors = product.getUpcs().stream()
    .collect(groupingBy(e -> e.getUpcDetails().getPrice().getRetail().getPriceValue())
    .entrySet().stream()
    .collect(toMap(Entry::getKey, e -> productsToColors(e.getValue())));

您也可以groupingBy创建TreeMap,以便按颜色对颜色地图进行排序。

作为旁注,请注意比较等值的双重值。你可能想先把它们围绕起来。或者使用长变量乘以100(即分数)。