举个例子吧,目前的业务需要把取到的数据,进行分组,然后好用另一个方法进行数据处理。
用到的方法就是 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>`。