形成映射问题的Java流
我正在开发一个框架,在这个框架中,我们试图将传统的循环转换为流。我的问题是,我写了两个独立的逻辑,以获得价格和颜色,但我想合并在一起,所以它将是体面的 获取价格值的代码形成映射问题的Java流,java,java-8,java-stream,Java,Java 8,Java Stream,我正在开发一个框架,在这个框架中,我们试图将传统的循环转换为流。我的问题是,我写了两个独立的逻辑,以获得价格和颜色,但我想合并在一起,所以它将是体面的 获取价格值的代码 List<Double> productPrices = product.getUpcs() .stream() .map(e -> e.getUpcDetails().getPrice().getRetail().getPriceValue())
List<Double> productPrices = product.getUpcs()
.stream()
.map(e -> e.getUpcDetails().getPrice().getRetail().getPriceValue())
.distinct()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
我在上面的部分中对价格进行了编码以获得颜色,相反,我希望从价格值列表中获得颜色作为输入,并在中获得输出
Map<Double,List<colors>
output Map<75.4, {blue,black,orange}>
Map我建议您检查一下,了解一下它是如何工作的
解决方案的关键是了解收集器.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())))
));
Map productPrices=产品
.stream()
.map(e->e.getUpcDetails())
.收集(
Collectors.groupingBy(详细信息::getPrice,
Collectors.mapping(详细信息::getColors,Collectors.collectingand then(
Collectors.toList(),
(集合)->集合
.stream()
.flatMap(集合::流)
.collect(收集器.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; }
}
类详细信息{
私人双价;
私有列表颜色;
double getPrice(){返回价格;}
List getColors(){返回颜色;}
}
类产品{
私人资料;
详细信息getUpcDetails(){return Details;}
}
```
优化上面的代码是可能的,但我特别保留了在MappingCollector中过滤和映射颜色的可能性 您可以首先将第二个流转换为一种方法,该方法获取产品的列表(假定按价格过滤/分组),并将其转换为颜色的列表:
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
创建一个TreeMap
,这样颜色映射将按价格排序
作为一个旁注,请注意不要像这样比较相等的双值。你可能想先把它们围起来。或者使用长变量乘以100(即美分) 看起来像是某种你需要的groupingBy
。。。由于您需要一张地图
作为旁注,因此切勿使用double
来表示货币价值。你会在网上找到很多关于它的文章…
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());
}
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())));