JDK8新特性(十一)之流(Stream)收集器(Collectors)

本文详细介绍了JDK8中Stream流的数据收集操作,包括收集到集合、数组,进行聚合计算,以及分组、转换为Map集合、分区和数据拼接等实用功能。通过实例展示了各种Collectors的用法,如分组到List和Set,自定义分组,转换为Map时处理key重复等常见场景。

1.Stream流中的数据收集到集合中

Stream流提供collect方法,其参数需要一个java.util.stream.Collector<T,A,R>接口对象来指定收集到哪种集合中。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo {

    public static void main(String[] args) {
        Stream<String> stream=Stream.of("aa","bb","cc");
        //1.将流中数据收集到list集合中
        //List<String> list=stream.collect(Collectors.toList());
        //System.out.println("list ="+list.toString());

        //2.将流中数据收集到set集合中
        //Set<String> set=stream.collect(Collectors.toSet());
        //System.out.println("set ="+set.toString());

        //3.收集到指定的集合中ArrayList
        //ArrayList<String> arrayList=stream.collect(Collectors.toCollection(ArrayList::new));
        //System.out.println("arrayList = " + arrayList);

        //4.收集到指定的集合中HashSet
        HashSet<String> hashSet=stream.collect(Collectors.toCollection(HashSet::new));
        System.out.println("hashSet = " + hashSet);
    }
}

执行上述代码,其输出结果为:

hashSet = [aa, bb, cc]

2.Stream流中的数据收集到数组中

import java.util.stream.Stream;

public class Demo {

    public static void main(String[] args) {
        Stream<String> stream=Stream.of("aa","bb","cc");
        // 转成Object数组不方便
        //Object[] objects=stream.toArray();
        //for(Object o:objects){
        //    System.out.println("0 = "+o);
        //}
        String[] strings=stream.toArray(String[]::new);
        for(String string:strings){
            System.out.println("string = "+string+",长度:"+string.length());
        }
    }
}

执行上述代码,其输出结果为:

string = aa,长度:2
string = bb,长度:2
string = cc,长度:2

3.Stream流中的数据进行聚合计算

当我们使用Stream流处理数据后,可以像数据库的聚合函数一样对某个字段进行操作。比如获取最大值,获取最小值,求总和,平均值,统计数量。

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String name;
    private int age;
    private int socre;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", socre=" + socre +
                '}';
    }
}
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo {

    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 25, 95),
                new Student("杨颖", 25, 88),
                new Student("迪丽热巴", 26, 99),
                new Student("柳岩", 26, 77));

        // 获取最大值
        // Optional<Student> max = studentStream.collect(Collectors.maxBy((s1, s2) -> s1.getSocre() - s2.getSocre()));
        // System.out.println("最大值: " + max.get());

        // 获取最小值
        // Optional<Student> min = studentStream.collect(Collectors.minBy((s1, s2) -> s1.getSocre() - s2.getSocre()));
        // System.out.println("最小值: " + min.get());

        // 求总和
        // Integer sum = studentStream.collect(Collectors.summingInt(s -> s.getAge()));
        // System.out.println("总和: " + sum);

        // 平均值
        // Double avg = studentStream.collect(Collectors.averagingInt(s -> s.getSocre()));
        // Double avg = studentStream.collect(Collectors.averagingInt(Student::getSocre));
        // System.out.println("平均值: " + avg);

        // 统计数量
        Long count = studentStream.collect(Collectors.counting());
        System.out.println("统计数量: " + count);
    }
}

执行上述代码,其输出结果为:

统计数量: 4

4.Stream流中的数据进行分组

例如当前存在一些学生信息(Student类),我们可以对其进行分组处理。

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
@AllArgsConstructor
public class Student {

    private int classId;
    private String name;

    public static List<Student> buildData(){
        List<Student> studentList = new ArrayList<>();
        Student student1 = new Student(1,"张三");
        Student student2 = new Student(1,"李四");
        Student student3 = new Student(2,"王五");
        studentList.add(student1);
        studentList.add(student3);
        studentList.add(student2);
        return studentList;
    }
}

4.1 默认情况下,分组之后的子集合是List列表

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GroupingByDemo {

    public static void main(String[] args) {
        List<Student> studentList = Student.buildData();
        // 默认情况下,分组之后的子集合是List列表
        Map<Integer,List<Student>> map= studentList.stream().collect(Collectors.groupingBy(Student::getClassId));
        System.out.println(map);
    }
}

执行上述代码,其输出结果为:

{1=[Student(classId=1, name=张三), Student(classId=1, name=李四)], 2=[Student(classId=2, name=王五)]}

4.2 指定分组之后的子集合为Set集合

如果想让分组之后的子集合是一个Set集合,则可以使用Collectors.toSet()进行指定:

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class GroupingByDemo {

    public static void main(String[] args) {
        List<Student> studentList = Student.b
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值