2017-08-09 56 views
3

我正在尝试将我们的传统循环转换为流的框架。我的问题是我写了两个独立的逻辑来获得价格和颜色,但我想合并这两个在一起,这将是像样形成地图问题的Java流

代码来获取价值

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"))); 

我harcoded价格在上面的部分,以获得颜色,相反,我想获得,作为从价格值列表输入和在

01得到的输出

我试图合并这两个都没有成功,任何帮助将appriciated。

+1

看起来像某种'groupingBy',你需要......因为你需要一个'Map'作为结果 – Eugene

+2

作为一个附注,*从不*使用'double'来表示货币价值。你会在网上找到大量关于它的文章...... – Holger

回答

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

您可以先打开你的第二个流成获得的产品(设为过滤/按价格分类)一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(即美分)。