Java8 Lambda Collection 的常见用法

java8,lambda,collection,常见,用法 · 浏览次数 : 114

小编点评

```java // 5.取两个List的交集 - 若为对象数组, 在流中使用map即可 List intersect = listA .stream() .filter(a -> listB.stream().anyMatch(b -> Objects.equals(a, b))) .collect(Collectors.toList()); // 6.取差集 换成noneMatch即可 List intersect1 = listA .stream() .filter(a -> listB.stream().noneMatch(b -> Objects.equals(a, b))) .collect(Collectors.toList()); // 7.求和 long sum = listA.stream().collect(Collectors.summarizingInt(u -> u)).getSum(); // 8.取两个List中的值组成map, 要求list大小相等 Map collect = IntStream.range(0, list.size()).boxed().collect(Collectors.toMap(list.stream().map(DemoEntity::getId).collect(Collectors.toList())::get, list1.stream().map(DemoEntity::getName).collect(Collectors.toList())::get)); // 9.其他用法如: filter(过滤掉不想要的数据), forEach, remove, removeIf, merge, distinct等未做整理 // 参考: // https://stackoverflow.com/questions/46873916/java-8-merge-2-string-lists-into-map // https://blog.csdn.net/a646705816/article/details/111927462 // https://objcoding.com/2019/03/04/lambda/ // https://blog.51cto.com/u_14479502/3115693 // https://blog.csdn.net/u014231523/article/details/102535902 // 10.扩展List对象分组取分组list中的一个字段成list // 用id1分组(结果是键id, 值是对象list), 取值(对象list)中的id2成List<Integer>Map<Integer, List<Integer>> id1Id2ListMap = list\t.stream()\t.collect(Collectors.groupingBy(Entity::getId1, Collectors.mapping(Entity::getId2, Collectors.toList()))); ``` **扩展 List对象分组取分组list中的一个字段成list** ```java Map> id1Id2ListMap = list\t.stream()\t.collect(Collectors.groupingBy(Entity::getId1, Collectors.mapping(Entity::getId2, Collectors.toList()))); ```

正文

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import lombok.Builder;
import lombok.Data;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author wangXiaoMing
 * @date 2022/04/27 10:46
 */
public class LambdaTest {

    @Data
    @Builder
    private static class DemoEntity {
        private Integer id;
        private String name;
    }

    @Test
    public void baseTest() {
        List<DemoEntity> list = new ArrayList<>();

        // 1.取list中的两个值成map - 注意键不能重复和null
        Map<Integer, String> stringMap = list.stream().collect(Collectors.toMap(DemoEntity::getId, DemoEntity::getName));

        // 2.取list中的某个值成list或set
        List<Integer> integers = list.stream().map(DemoEntity::getId).collect(Collectors.toList());
        Set<String> strings = list.stream().map(DemoEntity::getName).collect(Collectors.toSet());

        // 3.groupBy操作
        list.add(DemoEntity.builder().id(2).name("a").build());
        list.add(DemoEntity.builder().id(3).name("a").build());
        list.add(DemoEntity.builder().id(1).name("b").build());
        // {a=[LambdaTest.DemoEntity(id=2, name=a), LambdaTest.DemoEntity(id=3, name=a)], b=[LambdaTest.DemoEntity(id=1, name=b)]}
        Map<String, List<DemoEntity>> stringListMap = list.stream().collect(Collectors.groupingBy(DemoEntity::getName));
        // [[LambdaTest.DemoEntity(id=2, name=a), LambdaTest.DemoEntity(id=3, name=a)], [LambdaTest.DemoEntity(id=1, name=b)]]
        // 注: CollUtil 为hutool中的工具类
        List<List<DemoEntity>> groupByField = CollUtil.groupByField(list, "name");

        // 4.对list排序
        // 4.1 按照name从小到大排序
        // [LambdaTest.DemoEntity(id=2, name=a), LambdaTest.DemoEntity(id=3, name=a), LambdaTest.DemoEntity(id=1, name=b)]
        List<DemoEntity> sortedStringList = list.stream().sorted(Comparator.comparing(DemoEntity::getName)).collect(Collectors.toList());
        // 4.2 按照id从小到大
        // [LambdaTest.DemoEntity(id=1, name=b), LambdaTest.DemoEntity(id=2, name=a), LambdaTest.DemoEntity(id=3, name=a)]
        List<DemoEntity> sortedIntegerList = list.stream().sorted(Comparator.comparing(DemoEntity::getId)).collect(Collectors.toList());
        // 4.3 自定义顺序(id降序)
        // [LambdaTest.DemoEntity(id=3, name=a), LambdaTest.DemoEntity(id=2, name=a), LambdaTest.DemoEntity(id=1, name=b)]
        List<DemoEntity> orderSortedIntegerList = list.stream().sorted(Comparator.comparing(DemoEntity::getId).reversed()).collect(Collectors.toList());
        List<DemoEntity> orderSortedIntegerList1 = list.stream().sorted((i, j) -> j.getId().compareTo(i.getId())).collect(Collectors.toList());
        // 4.4 使用hutool工具类排序
        List<DemoEntity> hutoolSortList = ListUtil.sort(list, Comparator.comparing(DemoEntity::getId).reversed());

        // 4.5 补充对map排序
        Map<String, Integer> map = new HashMap<String, Integer>() {{
            put("d", 4);
            put("e", 6);
            put("f", 5);
        }};
        // 4.5.1 map转集合排序
        //{d=4, f=5, e=6}
        final Map<String, Integer> sortedMap = new LinkedHashMap<>();
        map.entrySet().stream().sorted(Map.Entry.comparingByValue())
                .collect(Collectors.toList()).forEach(u -> sortedMap.put(u.getKey(), u.getValue()));
        // 4.5.2 hutool对map排序
        // {d=4, f=5, e=6}
        LinkedHashMap<String, Integer> sortByEntry = CollUtil.sortByEntry(map, Map.Entry.comparingByValue());
        // {e=6, f=5, d=4}
        Map<String, Integer> sortByEntry1 = MapUtil.sortByValue(map, true);
        // 4.5.3 当按照值排序, 且值中有null值时
        map.put("a", null);
        // {a=null, d=4, f=5, e=6}
        LinkedHashMap<String, Integer> sortByEntry2 = CollUtil.sortByEntry(map, Map.Entry.comparingByValue(Comparator.nullsFirst(Integer::compareTo)));

        // 5.取两个list的交集 - 若为对象数组, 在流中使用map即可
        // 参考: https://blog.csdn.net/a646705816/article/details/111927462
        List<Integer> listA = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> listB = Arrays.asList(1, 4, 5, 6, 2);
        // [1, 2, 4, 5]
        List<Integer> intersect = listA
                .stream()
                .filter(a -> listB.stream().anyMatch(b -> Objects.equals(a, b)))
                .collect(Collectors.toList());

        // 6.取差集 换成noneMatch即可
        // [3]
        List<Integer> intersect1 = listA
                .stream()
                .filter(a -> listB.stream().noneMatch(b -> Objects.equals(a, b)))
                .collect(Collectors.toList());

        // 7.求和
        // 15
        long sum = listA.stream().collect(Collectors.summarizingInt(u -> u)).getSum();
        // 6
        long sum1 = list.stream().collect(Collectors.summarizingInt(DemoEntity::getId)).getSum();
        // 6
        int sum2 = list.stream().mapToInt(DemoEntity::getId).sum();

        // 8.取两个List中的值组成map, 要求list大小相等
        // 使用hutool工具类深拷贝
        List<DemoEntity> list1 = BeanUtil.copyToList(list, DemoEntity.class);
        // 对于对象的性能未作测试 !!! 可能时间会长
        // {1=b, 2=a, 3=a}
        Map<Integer, String> collect = IntStream.range(0, list.size()).boxed().collect(Collectors.toMap(list.stream().map(DemoEntity::getId).collect(Collectors.toList())::get,
                list1.stream().map(DemoEntity::getName).collect(Collectors.toList())::get));


        // 9.其他用法如: filter(过滤掉不想要的数据), forEach, remove, removeIf, merge, distinct等未做整理

        // 参考:
        // https://stackoverflow.com/questions/46873916/java-8-merge-2-string-lists-into-map
        // https://blog.csdn.net/a646705816/article/details/111927462
        // https://objcoding.com/2019/03/04/lambda/
        // https://blog.51cto.com/u_14479502/3115693
        // https://blog.csdn.net/u014231523/article/details/102535902
        // https://copyfuture.com/blogs-details/202202120151292216  - 其中对排序有第二排序位的样例
    }
}

image


扩展

  • List对象分组取分组list中的一个字段成list
    // 用id1分组(结果是键id, 值是对象list), 取值(对象list)中的id2成List<Integer>
    Map<Integer, List<Integer>> id1Id2ListMap = list
    	.stream()
    	.collect(Collectors.groupingBy(Entity::getId1, Collectors.mapping(Entity::getId2, Collectors.toList())));
    

与Java8 Lambda Collection 的常见用法相似的内容:

Java8 Lambda Collection 的常见用法

``` java import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.map.MapUtil; import lombok.Builde

Java Lambda Stream

java list 中的字符是否包括在另一个 list 中 ,::方法使用

Stream流处理快速上手最佳实践

一 引言 JAVA1.8得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种数据结构,不保存数据,而是对数据进行加工处理。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成

Java 方法引用

目录定义使用条件使用方式匿名类lambda 表达式::引用已有方法总结 定义 将方法作为参数传递即为方法引用。 以@FunctionalInterface 修饰的接口 其中只能有一个抽象方法。 这个抽象方法的形参和返回值便是对所引用方法的约束。 使用条件 引用方法的返回值类型和形参需要与函数式接口的

CompletableFuture学习总结

CompletableFuture 简介 在Java8中,CompletableFuture提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合 CompletableFuture 的方法。 Java

[转帖]20191022-从Jenkins NativeOOM到Java8内存

我把老掉牙的Jenkins升级了,它跑了几天好好的;后来我有一个python脚本使用JenkinsAPI 0.3.9每隔2.5分钟发送约300余get请求,结果过了3天,它就挂了;当我开两个脚本时,40.5小时就挂了。(可以通过搜索Jenkins日志/var/log/jenkins/* 中字符Jen

Java Stream 必须掌握的几种用法

Stream 是 Java8 推出的一套简化集合、数组操作的 API,掌握 Stream 的用法将极大的提升我们的编程能力。 流的获取 通过 Stream 自带的 API 获取: // 通过传入可变参数构造 static Stream of(T... values); // 指定一个常量

JDK8升级JDK11最全实践干货来了

截至目前(2023年),Java8发布至今已有9年,2018年9月25日,Oracle发布了Java11,这是Java8之后的首个LTS版本。那么从JDK8到JDK11,到底带来了哪些特性呢?值得我们升级吗?而且升级过程会遇到哪些问题呢?带着这些问题,本篇文章将带来完整的JDK8升级JDK11最全实践。

[转帖]聊聊HotSpot VM的Native Memory Tracking

https://cloud.tencent.com/developer/article/1406522 序 本文主要研究一下HotSpot VM的Native Memory Tracking Native Memory Tracking java8给HotSpot VM引入了Native Memor

我有点想用JDK17了

大家好呀,我是summo,JDK版本升级的非常快,现在已经到JDK20了。JDK版本虽多,但应用最广泛的还得是JDK8,正所谓“他发任他发,我用Java8”。 其实我也不太想升级JDK版本,感觉投入高,收益小,不过有一次我看到了一些使用JDK17新语法写的代码,让我改变了对升级JDK的看法,因为这些