lambda表达式是java8中的新特性
● 数据准备
# 实体类字段
@Data
@AllArgsConstructor
public class Student {
/**姓名*/
private String name;
/** 年龄*/
private int age;
/** 班级*/
private int clazz;
/** 成绩*/
private Double score;
}
List<Student> list = new ArrayList<Student>();
Student student = new Student("小明", 18, 1, 80.5);
list.add(student);
student = new Student("小红", 26, 2, 65.5);
list.add(student);
student = new Student("小王", 19, 3, 75.5);
list.add(student);
student = new Student("小赵", 20, 1, 79.5);
list.add(student);
student = new Student("赵李", 20, 2, 10.5);
list.add(student);
student = new Student("小张", 17, 3, 90.5);
list.add(student);
- 查找过滤
查找过滤用的是stream中的filter方法, 用于查找列表中想要查找的内容 例如:
- 查找名称中带有赵字的同学
List<Student> studentList = list.stream().filter(item -> item.getName().contains("赵")).collect(Collectors.toList());
返回的内容: [Student(name=小赵, age=20, clazz=1, score=79.5), Student(name=赵李, age=20, clazz=2, score=10.5)]
2.查找班级在三班的同学
List<Student> studentList = list.stream().filter(item -> item.getClazz() == 3).collect(Collectors.toList());
返回的内容: [Student(name=小王, age=19, clazz=3, score=75.5), Student(name=小张, age=17, clazz=3, score=90.5)]
- 只返回我们需要的字段
用的是stream中的map方法,这里我们重新定义一个实体类来接受我们需要的内容
@Data
@AllArgsConstructor
public class Stu {
private String name;
private int age;
private int clazz;
}
返回name, age, clazz字段
List<Stu> studentList = list.stream().map(item -> new Stu(item.getName(), item.getAge(), item.getClazz())).collect(Collectors.toList());
返回值: [Stu(name=小明, age=18, clazz=1), Stu(name=小红, age=26, clazz=2), Stu(name=小王, age=19, clazz=3), Stu(name=小赵, age=20, clazz=1), Stu(name=赵李, age=20, clazz=2), Stu(name=小张, age=17, clazz=3)]
查找3班的学生并返回name, age, clazz字段
List<Stu> studentList = list.stream().filter(item->item.getClazz() == 3).map(item -> new Stu(item.getName(), item.getAge(), item.getClazz())).collect(Collectors.toList());
返回值: [Stu(name=小王, age=19, clazz=3), Stu(name=小张, age=17, clazz=3)]
- 只返回以name字段集合
List<String> stringList = list.stream().map(Student::getName).collect(Collectors.toList());
返回值: [小明, 小红, 小王, 小赵, 赵李, 小张]
3.分组
- 以班级来进行分组,班级做为key值, 然后列表作为map的值
Map<Integer, List<Student>> listMap = list.stream().collect(Collectors.groupingBy(Student::getClazz));
返回值: {1=[Student(name=小明, age=18, clazz=1, score=80.5), Student(name=小赵, age=20, clazz=1, score=79.5)], 2=[Student(name=小红, age=26, clazz=2, score=65.5), Student(name=赵李, age=20, clazz=2, score=10.5)], 3=[Student(name=小王, age=19, clazz=3, score=75.5), Student(name=小张, age=17, clazz=3, score=90.5)]}
- 以name为key 分数为值
Map<String, Double> collect = list.stream().collect(Collectors.toMap(Student::getName, Student::getScore));
返回值: {小明=80.5, 小王=75.5, 赵李=10.5, 小红=65.5, 小张=90.5, 小赵=79.5}
- 以班级为key,班级总分数求和
Map<Integer, Double> collect = list.stream().collect(Collectors.groupingBy(Student::getClazz, Collectors.summingDouble(Student::getScore)));
返回值: {1=160.0, 2=76.0, 3=166.0}
# 如果BigDecimal类型的则用另一种方式
Map<Integer, BigDecimal> collect = list.stream().collect(Collectors.groupingBy(Student::getClazz, Collectors.reducing(BigDecimal.ZERO, Student::getScore, BigDecimal::add)));
# Collectors.reducing()中最后一个参数为BigDecimal中的方法,可以换成其他的运算
- 以班级为key, 班级平均数为值
Map<Integer, Double> collect = list.stream().collect(Collectors.groupingBy(Student::getClazz, Collectors.averagingDouble(Student::getScore)));
返回值: {1=80.0, 2=38.0, 3=83.0}
-
stream中数据统计
- 求和分数
Double collect = list.stream().mapToDouble(Student::getScore).sum();
- 取平均值
Double collect = list.stream().mapToDouble(Student::getScore).average().getAsDouble();
- BigDecimal的求和
BigDecimal bigDecimal = list.stream().map(Student::getScore).reduce(BigDecimal.ZERO, BigDecimal::add);
5.去重
- 简单去重
# list中有1, 2, 2, 5, 3, 6, 3元素 然后去重
List<Integer> list1 = new ArrayList<Integer>( Arrays.asList(1, 2, 2, 5, 3, 6, 3));
List<Integer> collect1 = list1.stream().distinct().collect(Collectors.toList());
返回的值: [1, 2, 5, 3, 6]
- 通过班级字段去重,不需要判断其他的内容
list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()->new ConcurrentSkipListSet<>(Comparator.comparing(Student::getClazz))),ArrayList::new));
返回值: [Student(name=小明, age=18, clazz=1, score=80.5), Student(name=小红, age=26, clazz=2, score=65.5), Student(name=小王, age=19, clazz=3, score=75.5)]
- 以班级和年龄去重
list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()->new ConcurrentSkipListSet<>(Comparator.comparing(Student::getClazz).thenComparing(Student::getAge))),ArrayList::new));
返回值: [Student(name=小明, age=18, clazz=1, score=80.5), Student(name=小赵, age=20, clazz=1, score=79.5), Student(name=小红, age=20, clazz=2, score=65.5), Student(name=小张, age=17, clazz=3, score=90.5), Student(name=小王, age=19, clazz=3, score=75.5)]