栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Jdk8,Stream流collect方法:处理集合方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Jdk8,Stream流collect方法:处理集合方法

Jdk8,Stream流collect方法:处理集合方法

前提

需要了解@FunctionalInterface:函数式接口,很多方法参数都是函数式接口,需要了解的可以看下这篇文章 数据转换

1:转List2:转Set3:转Collection4:转Map

1.基础转化2.处理key值重复3.指定Map类型4.并发转化 数据分组

1:普通分组

1.基础分组2.分组后,操作组内数据3.指定Map类型4.并发分组 2:Boolean分组

1.基础分组2.分组后,操作组内数据 数据统计

1:统计数量2:统计和3:统计平均数4:统计最小值5:统计最大值6:组合统计 其他操作

1:处理集合里的每个元素,然后进行二次操作2:获取第一次操作结果,进行第二次操作3:将集合数据进行字符串拼接

1.无拼接符拼接2.根据拼接符进行拼接3.根据拼接符进行拼接,并对开始前和结束后拼接自定义的字符串 4:聚合操作

1.基础聚合2.指定初始值聚合3.处理集合每个元素再聚合

前提 需要了解@FunctionalInterface:函数式接口,很多方法参数都是函数式接口,需要了解的可以看下这篇文章

通俗易懂,jdk8-@FunctionalInterface:函数式接口

比如转化Map的toMap方法

比如对集合分组的groupingBy方法

比如获取最大值的maxBy方法

数据转换 1:转List
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void toList() {
        List collect = list.stream().map(t -> t + "*").collect(Collectors.toList());
        System.out.println("collect = " + collect);
    }

输出:对集合每个元素拼接"*",然后将拼接结果转为List

collect = [5*, 2*, 4*, 1*, 6*, 3*, 10*, 8*, 7*, 9*]
2:转Set
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void toSet() {
        Set collect = list.stream().collect(Collectors.toSet());
        System.out.println("collect = " + collect);
    }

输出

collect = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
3:转Collection
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void toCollection() {
        Set collect = list.stream().collect(Collectors.toCollection(TreeSet::new));
        System.out.println("collect.getClass().getName() = " + collect.getClass().getName());
    }

输出:将List转成了TreeSet

collect.getClass().getName() = java.util.TreeSet
4:转Map 1.基础转化
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void toMap() {
        Map collect = list.stream().collect(Collectors.toMap(Function.identity(), v -> v * 10));
        System.out.println("collect = " + collect);
    }

这里使用到了Function.identity(),其实对应的就是我们平时的写法:t -> t,意思就是传入对象t,然后把这个传入的对象直接返回

	
    static  Function identity() {
        return t -> t;
    }

输出:key为对象自身,value为对象自身 * 10

collect = {1=10, 2=20, 3=30, 4=40, 5=50, 6=60, 7=70, 8=80, 9=90, 10=100}
2.处理key值重复
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9, 9);

    @Test
    public void toMapWithMergeFunction() {
        Map collect = list.stream().collect(Collectors.toMap(Function.identity(), v -> v * 10, (first, second) -> second));
        System.out.println("collect = " + collect);
    }

这里使用到了mergeFunction,也就是:(first, second) -> second,意思就是key值重复的话,使用重复的这个做为key

	public static 
    Collector> toMap(Function keyMapper,
                                    Function valueMapper,
                                    BinaryOperator mergeFunction) {
        return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
    }

如果key值重复不使用这个mergeFunction对象,代码会报错!!!

输出:key为对象自身,value为对象自身 * 10

collect = {1=10, 2=20, 3=30, 4=40, 5=50, 6=60, 7=70, 8=80, 9=90, 10=100}
3.指定Map类型
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void toMapWithMapSupplier() {
        Map collect = list.stream().collect(Collectors.toMap(Function.identity(), v -> v * 10, (first, second) -> second, linkedHashMap::new));
        System.out.println("collect.getClass().getName() = " + collect.getClass().getName());
    }

这里使用到了mapSupplier,也就是:linkedHashMap::new,意思就是使用linkedHashMap类型的Map

	public static 
    Collector> toMap(Function keyMapper,
                                    Function valueMapper,
                                    BinaryOperator mergeFunction) {
        return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
    }

输出:

collect.getClass().getName() = java.util.linkedHashMap
4.并发转化
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void toConcurrentMapWithMergeFunction() {
        Map collect = list.parallelStream().collect(Collectors.toConcurrentMap(Function.identity(), v -> {
            System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
            return v * 10;
        }, (first, second) -> second));
        System.out.println("collect = " + collect);
        System.out.println("collect.getClass().getName() = " + collect.getClass().getName());
    }

    @Test
    public void toConcurrentMapWithMergeFunction() {
        Map collect = list.parallelStream().collect(Collectors.toConcurrentMap(Function.identity(), v -> v * 10, (first, second) -> second));
        System.out.println("collect = " + collect);
        System.out.println("collect.getClass().getName() = " + collect.getClass().getName());
    }

输出:这里使用到了parallelStream,也就是并发流,默认使用系统自带的ForkJoinPool线程池进行多线程处理,可以看到主线程和线程池线程都参与了处理,使用了线程线程安全的ConcurrentHashMap

Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-2
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-5
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-1
Thread.currentThread().getName() = main
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-6
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-2
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
collect = {1=10, 2=20, 3=30, 4=40, 5=50, 6=60, 7=70, 8=80, 9=90, 10=100}
collect.getClass().getName() = java.util.concurrent.ConcurrentHashMap

数据分组 1:普通分组 1.基础分组
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void groupingBy() {
        Map> collect = list.stream().collect(Collectors.groupingBy(k -> k % 2));
        System.out.println("collect = " + collect);
    }

输出:根据除以2的余数进行分组,共两组,key为0和1

collect = {0=[2, 4, 6, 10, 8], 1=[5, 1, 3, 7, 9]}
2.分组后,操作组内数据
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void groupingByWithDownstream() {
        Map>> collect = list.stream().collect(Collectors.groupingBy(k -> k % 2, Collectors.groupingBy(k -> k % 3)));
        System.out.println("collect = " + collect);
    }

这里使用到了downstream,也就是:Collectors.groupingBy(k -> k % 3),意思就是根据除以3的余数进行分组

	public static 
    Collector> groupingBy(Function classifier,
                                          Collector downstream) {
        return groupingBy(classifier, HashMap::new, downstream);
    }

输出:根据除以2的余数进行分组,共两组,key为0和1。分完组后再对组内数据进行二次分组,二次分组根据除以3的余数进行分组,共三组,key为0,1和2

collect = {0={0=[6], 1=[4, 10], 2=[2, 8]}, 1={0=[3, 9], 1=[1, 7], 2=[5]}}
3.指定Map类型
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void groupingByWithMapFactory() {
        Map>> collect = list.stream().collect(Collectors.groupingBy(k -> k % 2, linkedHashMap::new, Collectors.groupingBy(k -> k % 3)));
        System.out.println("collect.getClass().getName() = " + collect.getClass().getName());
    }

这里使用到了mapFactory,也就是:linkedHashMap::new,意思就是使用linkedHashMap类型的Map

	public static >
    Collector groupingBy(Function classifier,
                                  Supplier mapFactory,
                                  Collector downstream)

输出:

collect.getClass().getName() = java.util.linkedHashMap
4.并发分组
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void groupingByConcurrent() {
        Map> collect = list.parallelStream().collect(Collectors.groupingByConcurrent(k -> {
            System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
            return k % 2;
        }));
        System.out.println("collect = " + collect);
        System.out.println("collect.getClass().getName() = " + collect.getClass().getName());
    }

    @Test
    public void groupingByConcurrentWithDownstream() {
        Map>> collect = list.parallelStream().collect(Collectors.groupingByConcurrent(k -> k % 2, Collectors.groupingBy(k -> k % 3)));
        System.out.println("collect = " + collect);
        System.out.println("collect.getClass().getName() = " + collect.getClass().getName());
    }

输出:这里使用到了parallelStream,也就是并发流,默认使用系统自带的ForkJoinPool线程池进行多线程处理,可以看到主线程和线程池线程都参与了处理,使用了线程线程安全的ConcurrentHashMap

Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-6
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-3
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-4
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-2
Thread.currentThread().getName() = main
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-1
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-1
Thread.currentThread().getName() = ForkJoinPool.commonPool-worker-5
collect = {0=[8, 2, 10, 4, 6], 1=[9, 3, 7, 5, 1]}
collect.getClass().getName() = java.util.concurrent.ConcurrentHashMap

2:Boolean分组 1.基础分组
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void partitioningBy() {
        Map> collect = list.stream().collect(Collectors.partitioningBy(k -> k % 2 == 0));
        System.out.println("collect = " + collect);
    }

输出:根据除以2的余数是否等于0进行分组,共两组,key为true和false

collect = {false=[5, 1, 3, 7, 9], true=[2, 4, 6, 10, 8]}
2.分组后,操作组内数据
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void partitioningByWithDownstream() {
        Map>> collect = list.stream().collect(Collectors.partitioningBy(k -> k % 2 == 0, Collectors.partitioningBy(k -> k % 3 == 0)));
        System.out.println("collect = " + collect);
    }

这里使用到了downstream,也就是:Collectors.groupingBy(k -> k % 3 == 0),意思就是根据除以3的余数是否等于0进行分组

	public static 
    Collector> partitioningBy(Predicate predicate,
                                                    Collector downstream)

输出:根据除以2的余数是否等于0进行分组,共两组,key为true和false。分完组后再对组内数据进行二次分组,二次分组根据除以3的余数是否等于0进行分组,共两组,key为true和false

collect = {false={false=[5, 1, 7], true=[3, 9]}, true={false=[2, 4, 10, 8], true=[6]}}
数据统计 1:统计数量
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void counting() {
        Long collect = list.stream().collect(Collectors.counting());
        System.out.println("collect = " + collect);
    }

输出

collect = 10
2:统计和
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void summingInt() {
        Integer collect = list.stream().collect(Collectors.summingInt(t -> t));
        System.out.println("collect = " + collect);
    }

    @Test
    public void summingLong() {
        Long collect = list.stream().collect(Collectors.summingLong(t -> t));
        System.out.println("collect = " + collect);
    }

    @Test
    public void summingDouble() {
        Double collect = list.stream().collect(Collectors.summingDouble(t -> t));
        System.out.println("collect = " + collect);
    }

输出:三个方法都是统计和,区别只在于统计结果的数据类型,分别为 Integer ,Long ,和Double

collect = 55
collect = 55
collect = 55.0
3:统计平均数
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void averagingInt() {
        Double collect = list.stream().collect(Collectors.averagingInt(t -> t));
        System.out.println("collect = " + collect);
    }

    @Test
    public void averagingLong() {
        Double collect = list.stream().collect(Collectors.averagingLong(t -> t));
        System.out.println("collect = " + collect);
    }

    @Test
    public void averagingDouble() {
        Double collect = list.stream().collect(Collectors.averagingDouble(t -> t));
        System.out.println("collect = " + collect);
    }

输出:三个方法都是统计平均数,区别只在于统计结果的数据类型,分别为 Integer ,Long ,和Double

collect = 5.5
collect = 5.5
collect = 5.5
4:统计最小值
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void minBy() {
        Optional collect = list.stream().collect(Collectors.minBy(Integer::compareTo));
        System.out.println("collect = " + collect);
    }

输出

collect = Optional[1]
5:统计最大值
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

   @Test
    public void maxBy() {
        Optional collect = list.stream().collect(Collectors.maxBy(Integer::compareTo));
        System.out.println("collect = " + collect);
    }

输出

collect = Optional[10]
6:组合统计
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void summarizingInt() {
        IntSummaryStatistics collect = list.stream().collect(Collectors.summarizingInt(t -> t));
        System.out.println("collect = " + collect);
    }

    @Test
    public void summarizingLong() {
        LongSummaryStatistics collect = list.stream().collect(Collectors.summarizingLong(t -> t));
        System.out.println("collect = " + collect);
    }

    @Test
    public void summarizingDouble() {
        DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(t -> t));
        System.out.println("collect = " + collect);
    }

输出:统计出数量,和,最小值,平均数,最大值

collect = IntSummaryStatistics{count=10, sum=55, min=1, average=5.500000, max=10}
collect = LongSummaryStatistics{count=10, sum=55, min=1, average=5.500000, max=10}
collect = DoubleSummaryStatistics{count=10, sum=55.000000, min=1.000000, average=5.500000, max=10.000000}
其他操作 1:处理集合里的每个元素,然后进行二次操作
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void mapping() {
        Map> collect = list.stream().collect(Collectors.mapping(t -> t * t, Collectors.groupingBy(k -> k % 2)));
        System.out.println("collect = " + collect);
    }

输出:这里先对集合的每个元素进行平方操作,然后对平方的结果除以2的余数进行分组

collect = {0=[4, 16, 36, 100, 64], 1=[25, 1, 9, 49, 81]}
2:获取第一次操作结果,进行第二次操作
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void collectingAndThen() {
        Map> collect = list.stream().collect(Collectors.collectingAndThen(Collectors.groupingBy(k -> k % 2), d -> {
            Map> map = new HashMap<>((int) (d.size() / 0.75F));
            d.forEach((key, value) -> map.put(key + 10, value.stream().map(t -> t * 10).collect(Collectors.toList())));
            return map;
        }));
        System.out.println("collect = " + collect);
    }

输出:这里第一次操作是根据除以2的余数进行分组,第二次操作对分组后的结果进行遍历,对key + 10 ,对value * 10,组成一个新的map并返回

collect = {10=[20, 40, 60, 100, 80], 11=[50, 10, 30, 70, 90]}
3:将集合数据进行字符串拼接 1.无拼接符拼接
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void joining() {
        String collect = list.stream().map(Objects::toString).collect(Collectors.joining());
        System.out.println("collect = " + collect);
    }

输出

collect = 52416310879
2.根据拼接符进行拼接
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void joiningWithDelimiter() {
        String collect = list.stream().map(Objects::toString).collect(Collectors.joining(","));
        System.out.println("collect = " + collect);
    }

输出

collect = 5,2,4,1,6,3,10,8,7,9
3.根据拼接符进行拼接,并对开始前和结束后拼接自定义的字符串
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void joiningWithStartAndEnd() {
        String collect = list.stream().map(Objects::toString).collect(Collectors.joining(",", "[", "]"));
        System.out.println("collect = " + collect);
    }

输出

collect = [5,2,4,1,6,3,10,8,7,9]
4:聚合操作 1.基础聚合
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

   @Test
    public void reducing() {
        Optional collect = list.stream().collect(Collectors.reducing((t, u) -> {
            System.out.println("t = " + t);
            System.out.println("u = " + u);
            System.out.println("--------");
            return t - u;
        }));
        System.out.println("collect = " + collect);
    }

输出:对集合元素进行累减,从第二个参数t可以看出, t为上一次操作的结果。在这里第一个t = 5,u = 2,t - u = 3赋值到第二个t,所以二个t = 3

t = 5
u = 2
--------
t = 3
u = 4
--------
t = -1
u = 1
--------
t = -2
u = 6
--------
t = -8
u = 3
--------
t = -11
u = 10
--------
t = -21
u = 8
--------
t = -29
u = 7
--------
t = -36
u = 9
--------
collect = Optional[-45]
2.指定初始值聚合
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void reducingWithIdentity() {
        Integer collect = list.stream().collect(Collectors.reducing(100, (t, u) -> {
            System.out.println("t = " + t);
            System.out.println("u = " + u);
            System.out.println("--------");
            return t - u;
        }));
        System.out.println("collect = " + collect);
    }

输出:第一个参数t,跟上面例子对比,发现不是5,而是指定的初始值100

t = 100
u = 5
--------
t = 95
u = 2
--------
t = 93
u = 4
--------
t = 89
u = 1
--------
t = 88
u = 6
--------
t = 82
u = 3
--------
t = 79
u = 10
--------
t = 69
u = 8
--------
t = 61
u = 7
--------
t = 54
u = 9
--------
collect = 45
3.处理集合每个元素再聚合
	private List list = Arrays.asList(5, 2, 4, 1, 6, 3, 10, 8, 7, 9);

    @Test
    public void reducingWithMapper() {
        Integer collect = list.stream().collect(Collectors.reducing(100, t -> t + 10, (t, u) -> {
            System.out.println("t = " + t);
            System.out.println("u = " + u);
            System.out.println("--------");
            return t - u;
        }));
        System.out.println("collect = " + collect);
    }

输出:从参数可以看到,这里执行了 t -> t + 10 操作,对集合的每个元素进行自增10

t = 100
u = 15
--------
t = 85
u = 12
--------
t = 73
u = 14
--------
t = 59
u = 11
--------
t = 48
u = 16
--------
t = 32
u = 13
--------
t = 19
u = 20
--------
t = -1
u = 18
--------
t = -19
u = 17
--------
t = -36
u = 19
--------
collect = -55

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号