- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
Collectors.groupingBy根据一个或多个属性对集合中的项目进行分组
public Product(Long id, Integer num, BigDecimal price, String name, String category) {
this.id = id;
this.num = num;
this.price = price;
this.name = name;
this.category = category;
}
Product prod1 = new Product(1L, 1, new BigDecimal("15.5"), "面包", "零食");
Product prod2 = new Product(2L, 2, new BigDecimal("20"), "饼干", "零食");
Product prod3 = new Product(3L, 3, new BigDecimal("30"), "月饼", "零食");
Product prod4 = new Product(4L, 3, new BigDecimal("10"), "青岛啤酒", "啤酒");
Product prod5 = new Product(5L, 10, new BigDecimal("15"), "百威啤酒", "啤酒");
List<Product> prodList = Lists.newArrayList(prod1, prod2, prod3, prod4, prod5);
Map<String, List<Product>> prodMap= prodList.stream().collect(Collectors.groupingBy(Product::getCategory));
{"啤酒":[{"category":"啤酒","id":4,"name":"青岛啤酒","num":3,"price":10},{"category":"啤酒",
"id":5,"name":"百威啤酒","num":10,"price":15}],"零食":[{"category":"零食","id":1,"name":"面包",
"num":1,"price":15.5},{"category":"零食","id":2,"name":"饼干","num":2,"price":20},{"category":"零食",
"id":3,"name":"月饼","num":3,"price":30}]}
Map<String, List<Product>> prodMap = prodList.stream().collect(Collectors.groupingBy(item ->
item.getCategory() + "_" + item.getName()));
{"零食_月饼":[{"category":"零食","id":3,"name":"月饼","num":3,"price":30}],"零食_面包":
[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5}],"啤酒_百威啤酒":[{"category":"啤
酒","id":5,"name":"百威啤酒","num":10,"price":15}],"啤酒_青岛啤酒":[{"category":"啤
酒","id":4,"name":"青岛啤酒","num":3,"price":10}],"零食_饼干":[{"category":"零食","id":2,"name":"饼
干","num":2,"price":20}]}
Map<String, List<Product>> prodMap= prodList.stream().collect(Collectors.groupingBy(item -> {
if(item.getNum() < 3) {
return "3";
}else {
return "other";
}
}));
{"other":[{"category":"零食","id":3,"name":"月饼","num":3,"price":30},{"category":"啤
酒","id":4,"name":"青岛啤酒","num":3,"price":10},{"category":"啤酒","id":5,"name":"百威啤
酒","num":10,"price":15}],
"3":[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5},{"category":"零
食","id":2,"name":"饼干","num":2,"price":20}]}
多级分组
要实现多级分组,我们可以使用一个由双参数版本的Collectors.groupingBy工厂方法创 建的收集器,它除了普通的分类函数之外,还可以接受collector类型的第二个参数。那么要进 行二级分组的话,我们可以把一个内层groupingBy传递给外层groupingBy,并定义一个为流 中项目分类的二级标准。
Map<String, Map<String, List<Product>>> prodMap=
prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.groupingBy(item -> {
if(item.getNum() < 3) {
return "3";
}else {
return "other";
}
})));
{"啤酒":{"other":[{"category":"啤酒","id":4,"name":"青岛啤酒","num":3,"price":10},{"category":"啤
酒","id":5,"name":"百威啤酒","num":10,"price":15}]},"零食":{"other":[{"category":"零
食","id":3,"name":"月饼","num":3,"price":30}],
"3":[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5},{"category":"零
食","id":2,"name":"饼干","num":2,"price":20}]}}
Map<String, Long> prodMap = prodList.stream().collect(
Collectors.groupingBy(Product::getCategory, Collectors.counting()));
//{"啤酒":2,"零食":3}
Map<String, Integer> prodMap = prodList.stream().collect(
Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)));
//{"啤酒":13,"零食":6}
Map<String, Product> prodMap = prodList.stream().collect(
Collectors.groupingBy(Product::getCategory,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparingInt(Product::getNum)), Optional::get)));
{"啤酒":{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15},"零食":{"category":"零
食","id":3,"name":"月饼","num":3,"price":30}}
Map<String, Set<String>> prodMap = prodList.stream().collect(
Collectors.groupingBy(Product::getCategory, Collectors.mapping(Product::getName, Collectors.toSet())));
//{"啤酒":["青岛啤酒","百威啤酒"],"零食":["面包","饼干","月饼"]}
以下面的列表为例: List input = List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR", "BAR", "BAZ", "BAZ", "BAZ",
我有一个类似于下面的类 MyObject . public class MyObject { private String key; // not unique. multiple objec
我想获取按频率键控的数组值频率图。我能够得到相反的 - 按值键控的 map 。尝试切换参数,但 grouping by 不接受 Collector 作为第一个参数。 另一个问题,如何将 Map 实现更
我是 Java 8 Stream API 的新手,但我想用它来解决以下问题。假设我有一个名为 InputRecord 的 POJO,其中包含 name、fieldA 和 fieldB 属性,这些属性可
基准测试在 intel core i5, Ubuntu 下运行 java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.
我尝试使用流和收集器对值进行分组。我有我必须拆分的字符串列表。 我的数据: List stringList = new ArrayList<>(); stringList.add("Key:1,2,3
我想创建一个 Map来自 List的 Points并在映射中使用相同的 parentId 映射列表中的所有条目,例如 Map> . 我用了Collectors.toMap()但它没有编译: Map>
我已经实现了以下示例: Map> map = events.getItems().stream() .collect(Collectors.groupingBy(Event::getS
这个问题在这里已经有了答案: java 8 Collector is not a functional interface, who can tell why? (2 个回答) Java8: Usin
我想通过 Java 8 Stream 和 Collector 接口(interface)将 Map 转换为 ConcurrentHashMap,然后是我可以使用的两个选项。 第一个: Map mb =
如果我有一个对象列表(~200 个元素),只有几个唯一对象(~20 个元素)。 我只想拥有独特的值(value)。之间list.stream().collect(Collectors.toSet())
对于下面开发的 Java 8 代码,我收到以下错误。在此示例中,尝试将 Dish Name 的所有名称连接到一个变量中。使用下面的代码我得到了这个 "The method collect(Collec
我正在尝试使用rook在kubernetes集群上配置ceph,我已经运行了以下命令: kubectl apply -f common.yaml kubectl apply -f operator.y
这是我的流: Stream> futureStream = IntStream .iterate(1, n -> n n++) .mapToObj(pageNumber -> thi
Collector.of(Supplier 供应商、BiConsumer 累加器、BinaryOperator 组合器、Function 完成器、Characterstics...) Coll
按照常规思维,往一个map里put一个已经存在的key,会把原有的key对应的value值覆盖,然而通过一次线上问题,发现Java8中的Collectors.toMap反其道而行之,它默认给抛异常,
我想通过基于 LocalDateTime 的集合进行分组,但我只想获取小时,而不是分钟、秒... .collect(Collectors.groupingBy(cp -> getUpdateLocal
这个问题在这里已经有了答案: What is the point of "final class" in Java? (24 个答案) 关闭 3 年前。 为什么 Collectors 类在 Java
我有一个College具有嵌套静态类的类 Dept 学院 class College { private String collegeName; private Dept dept; public D
在Java库源代码中,Collectors#toList方法的定义如下: public static Collector> toList() { return new CollectorIm
我是一名优秀的程序员,十分优秀!