Java中List一些常用处理方法

List集合中的元素是Person,字段属性如下

@Data
public static class Person {
    private String name;
    private Integer age;
    private Integer score;
    private String date;

    public Person(String name, Integer age, Integer score, String date) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.date = new SimpleDateFormat("yyyy-MM-dd").format(this.birthDay);
    }
}

1.List根据对象中某一属性去重

List<Person> arrays = personList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
						-> new TreeSet<>(Comparator.comparing(Entity :: getName))), ArrayList::new));

2.List分组排序

Map<String, List<Person>> sortedDatas = personList.stream()
		//按照getAge倒序排列
        .sorted(Comparator.comparing(Person::getAge, Comparator.nullsLast(Comparator.reverseOrder())))
        //保证分组后的有序性,容器用LinkedHashMap
        .collect(Collectors.groupingBy(Person::getDate, LinkedHashMap::new, Collectors.toList()));

3.List转Map的空值报错问题

Map<String, Integer> nameForAgeMap = 
			personList.stream().collect(HashMap::new, (m, v) -> m.put(v.getName(), v.getAge()), HashMap::putAll);

4.List实现分页

List<Person> personPageList = personList.stream()
										.sorted((o1,o2) -> o2.getAge() - o1.getAge())
										.skip((long)(pageNum - 1) * pageSize)
										.limit(pageSize).collect(toList())

5.List分组统计功能

前置数据

List<Student> students = Stream.of(
        Student.builder().name("小张").age(16).clazz("高一1班").course("历史").score(88).build(),
        Student.builder().name("小李").age(16).clazz("高一3班").course("数学").score(12).build(),
        Student.builder().name("小王").age(17).clazz("高二1班").course("地理").score(44).build(),
        Student.builder().name("小红").age(18).clazz("高二1班").course("物理").score(67).build(),
        Student.builder().name("李华").age(15).clazz("高二2班").course("数学").score(99).build(),
        Student.builder().name("小潘").age(19).clazz("高三4班").course("英语").score(100).build(),
        Student.builder().name("小聂").age(20).clazz("高三4班").course("物理").score(32).build()
).collect(Collectors.toList());
  1. Collectors.counting:计数

计数语法:
Collector<T, ?, Long> counting()

// 计数
Map<String, Long> groupCount = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.counting()));
  1. Collectors.summingInt:求和

求和语法:
Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper)
Collector<T, ?, Long> summingLong(ToLongFunction<? super T> mapper)
Collector<T, ?, Double> summingDouble(ToDoubleFunction<? super T> mapper)

// 求和
Map<String, Integer> groupSum = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.summingInt(Student::getScore)));
  1. Collectors.averagingInt:平均值

平均值语法:
Collector<T, ?, Double> averagingInt(ToIntFunction<? super T> mapper)
Collector<T, ?, Double> averagingLong(ToLongFunction<? super T> mapper)
Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper)

// 增加平均值计算
Map<String, Double> groupAverage = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.averagingInt(Student::getScore)));
  1. Collectors.minBy:最大最小值

最大最少值语法:
Collector<T, ?, Optional> minBy(Comparator<? super T> comparator)
Collector<T, ?, Optional> maxBy(Comparator<? super T> comparator)
Collectors.collectingAndThen语法:
Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher)
Function<R,RR>:提供参数类型为R,返回结果类型为RR。

// 同组最小值
Map<String, Optional<Student>> groupMin = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse,Collectors.minBy(Comparator.comparing(Student::getCourse))));
// 使用Collectors.collectingAndThen方法,处理Optional类型的数据
Map<String, Student> groupMin2 = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse,
        Collectors.collectingAndThen(Collectors.minBy(Comparator.comparing(Student::getCourse)), op ->op.orElse(null))));
// 同组最大值
Map<String, Optional<Student>> groupMax = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse,Collectors.maxBy(Comparator.comparing(Student::getCourse))));
  1. Collectors.summarizingInt:完整统计(同时获取以上的全部统计结果)

完整统计语法:
Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper)
Collector<T, ?, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper)
Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper)

// 统计方法同时统计同组的最大值、最小值、计数、求和、平均数信息
HashMap<String, IntSummaryStatistics> groupStat = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, HashMap::new,Collectors.summarizingInt(Student::getScore)));
groupStat.forEach((k, v) -> {
	// 返回结果取决于用的哪种计算方式
    v.getAverage();
    v.getCount();
    v.getMax();
    v.getMin();
    v.getSum();
});

  1. Collectors.partitioningBy:范围统计

Collectors.partitioningBy语法:
Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate)
Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate, Collector<? super T, A, D> downstream)

  • predicate:条件参数,对分组的结果划分为两个范围。
// 切分结果,同时统计大于60和小于60分的人的信息
Map<String, Map<Boolean, List<Student>>> groupPartition = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.partitioningBy(s -> s.getScore() > 60)));
// 同样的,我们还可以对上面两个分组的人数数据进行统计
Map<String, Map<Boolean, Long>> groupPartitionCount = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.partitioningBy(s -> s.getScore() > 60, Collectors.counting())));

Collectors.partitioningBy仅支持将数据划分为两个范围进行统计,如果需要划分多个,可以嵌套Collectors.partitioningBy执行,不过需要在执行完后,手动处理不需要的数据。也可以在第一次Collectors.partitioningBy获取结果后,再分别对该结果进行范围统计。

Map<String, Map<Boolean, Map<Boolean, List<Student>>>> groupAngPartitionCount = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.partitioningBy(s -> s.getScore() > 60,
                Collectors.partitioningBy(s -> s.getScore() > 90))));

  1. Collectors.reducing:合并分组结果

Collectors.reducing语法:
Collector<T, ?, Optional> reducing(BinaryOperator op)
Collector<T, ?, T> reducing(T identity, BinaryOperator op)
Collector<T, ?, U> reducing(U identity, Function<? super T, ? extends U> mapper, BinaryOperator op)

  • identity:合并标识值(因子),它将参与累加函数和合并函数的运算(即提供一个默认值,在流为空时返回该值,当流不为空时,该值作为起始值,参与每一次累加或合并计算)
  • mapper:映射流中的某个元素,并根据此元素进行合并。
  • op:合并函数,将mapper映射的元素,进行两两合并,最初的一个元素将于合并标识值进行合并。
// 合并结果,计算每科总分
Map<String, Integer> groupCalcSum = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.reducing(0, Student::getScore, Integer::sum)));
// 合并结果,获取每科最高分的学生信息
Map<String, Optional<Student>> groupCourseMax = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.reducing(BinaryOperator.maxBy(Comparator.comparing(Student::getScore)))));

  1. Collectors.joining:合并字符串

Collectors.joining语法:
Collector<CharSequence, ?, String> joining()
Collector<CharSequence, ?, String> joining(CharSequence delimiter)
Collector<CharSequence, ?, String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)

  • delimiter:分隔符
  • prefix:每个字符的前缀
  • suffix:每个字符的后缀

Collectors.joining只能对字符进行操作,因此一般会与其它downstream方法组合使用。

// 统计各科的学生姓名
Map<String, String> groupCourseSelectSimpleStudent = students.stream()
        .collect(Collectors.groupingBy(Student::getCourse, Collectors.mapping(Student::getName, Collectors.joining(","))));

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值