我正在尝试将多个不必要的Web请求合并到一个地图中,并将密钥连接到某个位置的ID,并且该值是该位置的产品列表。
该想法是通过为每个位置创建一个请求并映射到其所需产品列表来减少对我的flask服务器的请求量。
我已经尝试使用Java 8的流功能找到遇到类似问题的其他人,但是我找不到试图将其追加到地图列表中的人。
示例;
public class Product {
public Integer productNumber();
public Integer locationNumber();
}
List<Product> products = ... (imagine many products in this list)
Map<Integer, List<Integer>> results = products.stream()
.collect(Collectors.toMap(p -> p.locationNumber, p -> Arrays.asList(p.productNumber));
此外,第二个p
参数无法访问流中的当前产品。
因此,当位置编号与现有列表匹配时,我无法测试是否可以追加到列表。我不相信可以使用Arrays.asList(),因为我相信它是不可变的。
最后,该地图的每个位置列表中应包含许多产品编号。是否可以将Integers附加到地图中预先存在的列表中?
答案 0 :(得分:7)
您可以这样做
Map<Integer, List<Integer>> res = products.stream()
.collect(Collectors.groupingBy(Product::locationNumber,
Collectors.mapping(Product::productNumber, Collectors.toList())));
答案 1 :(得分:1)
java collectors API非常强大,并且有很多不错的实用程序方法可以解决这个问题。
public class Learn {
static class Product {
final Integer productNumber;
final Integer locationNumber;
Product(Integer productNumber, Integer locationNumber) {
this.productNumber = productNumber;
this.locationNumber = locationNumber;
}
Integer getProductNumber() {
return productNumber;
}
Integer getLocationNumber() {
return locationNumber;
}
}
public static Product of(int i, int j){
return new Product(i,j);
}
public static void main(String[] args) {
List productList = Arrays.asList(of(1,1),of(2,1),of(3,1),
of(7,2),of(8,2),of(9,2));
Map> results = productList.stream().collect(Collectors.groupingBy(Product::getLocationNumber,
Collectors.collectingAndThen(Collectors.toList(), pl->pl.stream().map(Product::getProductNumber).collect(Collectors.toList()))));
System.out.println(results);
}
}
因此,我们在这里要做的是流式传输产品列表,并按location属性对流进行分组,但又有一点曲折,我们希望将收集的产品列表转换为产品编号列表。
Collectors.collectingAndThen正是为此的方法,它将使您指定一个主收集器toList()和一个转换器函数,该函数只不过是将产品映射到产品编号的流。在Java API文档中,主收集器和转换器标记为下游收集器和整理器。
请仔细阅读收集器源代码,以全面了解如何定义所有这些不同的收集器。