举个例子吧,目前的业务需要把取到的数据,进行分组,然后好用另一个方法进行数据处理。
用到的方法就是 Collectors.groupingBy,Collectors.counting(), Collectors.reducing()。
然后,就以下面的为例子,将取到的list集合,将取到的数据以性别分组,以性别为K,以性别数量为v,。
代码示例:
package Lx; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class StreamLiu { public static void main(String[] args) { // 假设有三个包含对象的list链表 List<Person> list1 = new ArrayList<>(); Person person = new Person(); person.setIdCard("100001"); person.setName("张三"); person.setAge("M"); list1.add(person); // 向list1中添加一些Person对象 List<Person> list2 = new ArrayList<>(); // 向list2中添加一些Person对象 Person person2 = new Person(); person2.setIdCard("100002"); person2.setName("李四"); person2.setAge("M"); list2.add(person2); List<Person> list3 = new ArrayList<>(); // 向list3中添加一些Person对象 Person person3 = new Person(); person3.setIdCard("100003"); person3.setName("赵芳"); person3.setAge("W"); list3.add(person3); // 将这三个链表合并成一个总的链表 List<Person> totalList = new ArrayList<>(); totalList.addAll(list1); totalList.addAll(list2); totalList.addAll(list3); //要求:将totalList转变成以性别为主键,性别数量为value的集合 /***方法一--start***/ Map<String, Integer> result = totalList.stream().collect(Collectors.groupingBy( Person::getAge, Collectors.reducing(0, e -> 1, Integer::sum) )); System.out.println("reult "+result); /***方法二--start***/ Map<String, Long> result2 = totalList.stream().collect(Collectors.groupingBy( Person::getAge, Collectors.counting() )); System.out.println("reult "+result); } } class Person { private String idCard; // 其他属性和方法 private String name; //性别1男2女 private String age; public String getIdCard() { return idCard; } public void setIdCard(String idCard) { this.idCard = idCard; } // 其他getter和setter方法 public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "idCard='" + idCard + '\'' + // 其他属性 '}'; } }
打印结果:
关键代码分析:
方法一:
/***方法一--start***/ Map<String, Integer> result = totalList.stream().collect(Collectors.groupingBy( Person::getAge, Collectors.reducing(0, e -> 1, Integer::sum) ));
这段代码使用Java 8中的Stream API将一个`List`中的对象按照`Person`对象的`age`属性进行分组,并计算每个分组中的元素个数,并将结果存储在一个`Map`中返回。具体来说,代码中使用了`Collectors.groupingBy`方法和`Collectors.reducing`方法,分别表示对列表进行分组和规约(计算)操作。
以下是详细的解析:
1. `totalList.stream()`:将`totalList`转换为`Stream`对象,以便使用Stream API进行操作。
2. `Collectors.groupingBy(Person::getAge, Collectors.reducing(0, e -> 1, Integer::sum))`:对`totalList`中的元素按照`Person`对象的`age`属性进行分组,并计算每个分组中的元素个数。
* `Person::getAge` 指定了按照`Person`对象的`age`属性进行分组,即将具有相同`age`属性的元素分为同一组。
* `Collectors.reducing`方法指定每个分组中元素的计算方式。在本例中,将每个分组中的元素规约(计算)为它们数量的和。 具体来说,`Collectors.reducing(0, e -> 1, Integer::sum)`中:
* `0` 表示初始值,即每个分组的元素数量的初始值为0。
* `e -> 1` 是一个Lambda表达式,表示将每个元素映射为`1`,即对每个元素计数。
* `Integer::sum` 指定了将所有映射为`1`的元素相加的操作,即将每个分组中的元素数量相加。
通过这样的规约操作,将每个分组的元素数量计算出来。
3. 由于`Collectors.groupingBy`方法的返回值为`Map<K,List<V>>`类型,即一个分组名和分组元素列表的映射关系。而在本例中,分组名为`String`类型,表示`Person`对象的`age`属性的取值,元素数量为`Integer`类型,表示每个分组中元素的数量。因此,最终返回的类型为`Map<String, Integer>`。
方法二:(因为方法二value是Long类型,所以直接用Collectors.counting()可以)
/***方法二--start***/ Map<String, Long> result2 = totalList.stream().collect(Collectors.groupingBy( Person::getAge, Collectors.counting() ));
这段代码使用Java 8中的Stream API将一个`List`中的对象按照`Person`对象的`age`属性进行分组,并计算每个分组中的元素个数,并将结果存储在一个`Map`中返回。具体来说,代码中使用了`Collectors.groupingBy`方法和`Collectors.counting`方法,分别表示对列表进行分组和计数操作。
以下是详细的解析:
1. `totalList.stream()`:将`totalList`转换为`Stream`对象,以便使用Stream API进行操作。
2. `Collectors.groupingBy(Person::getAge, Collectors.counting())`:对`totalList`中的元素按照`Person`对象的`age`属性进行分组,并计算每个分组中的元素个数。
* `Person::getAge` 指定了按照`Person`对象的`age`属性进行分组,即将具有相同`age`属性的元素分为同一组。
* `Collectors.counting()` 方法用于计算每个分组中的元素个数。
通过这样的操作,将每个分组的元素数量计算出来。
3. 由于`Collectors.groupingBy`方法的返回值为`Map<K,List<V>>`类型,即一个分组名和分组元素列表的映射关系。而在本例中,分组名为`String`类型,表示`Person`对象的`age`属性的取值,元素数量为`Long`类型,表示每个分组中元素的数量。因此,最终返回的类型为`Map<String, Long>`。