【Java】Lambda表达式在实战中的运用

167 阅读3分钟

前言

闲来无事,整理一下工作中常用的Java8 中常用的Lambda 表达式,方便自己查阅,如果能帮助到一些人那就再好不过了!
Lambda表达式,可以使我们的代码更加简洁、优雅,但也不要滥用,因为在一定程度上复杂的Lambda表达式反而降低了代码的可阅读性,所以说各位还是要灵活运用。

基础数据准备

为了方便演示,准备了一些基础数据:

List<BaseInfo> infoList = new ArrayList<>();
infoList.add(new BaseInfo(10L, "小明", "北京"));
infoList.add(new BaseInfo(11L, "小葱", "天津"));
infoList.add(new BaseInfo(10L, "小明", "济南"));
infoList.add(new BaseInfo(9L, "小刚", "青岛"));
infoList.add(new BaseInfo(18L, "小红", "海口"));
infoList.add(new BaseInfo(33L, "小李", "上海"));

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");

1. List 转 Map

Map<Long,BaseInfo> infoMap = infoList.stream().collect(Collectors.toMap(BaseInfo::getId,item ->item));

对于我们上面造的数据,上述执行结果会报错:java.lang.IllegalStateException: Duplicate key 这是因为第一条和第三条出现了重复健:10,这时候我们就需要下面的方式:

Map<Long, BaseInfo> nonRepeatInfoMap = infoList.stream().collect(Collectors.toMap(BaseInfo::getId, item -> item, (key1, key2) -> key1));

处理重复健问题 加 (key1,key2) -> key1 表示存在重复健时取key1 ,当然也可以 (key1,key2) -> key1 表示存在重复健时取key2。

从上面的输出结果我们发现重复健的问题解决了,但是输出的结果却没有按照我们添加进list的顺序进行输出(因为通过源码可以发现Collectors.toMap()源码发现其输出的Map是HashMap,而HashMap不是按顺序存的),在某些场景中我们是需要按照顺序输出的;所以也就有了下面的方法:

Map<Long, BaseInfo> orderInfoMap = infoList.stream().collect(Collectors.toMap(BaseInfo::getId, item -> item, (key1, key2) -> key1, LinkedHashMap::new));

这里稍微解释一下为什么列举了三种:因为不同的需求场景的需求,比如报错的第一种,某种场景下转Map的时候就是需要唯一健,这是出现报错我们更能发现问题,让我们去检查数据,因此各位根据自己的需求去选择用哪种方式。

2. groupingBy 分组

Map<Long, List<BaseInfo>> groupMap = infoList.stream().collect(Collectors.groupingBy(BaseInfo::getId));

同样上述的方法输出分组为乱序的,其原因同样也是:Collectors.groupingBy()输出为HashMap,因此如果对顺序有要求的话可以使用下面的方式:

Map<Long, List<BaseInfo>> orderGroupMap = infoList.stream().collect(Collectors.groupingBy(BaseInfo::getId, LinkedHashMap::new, Collectors.toList()));

3. map 转换

获取对象中某一个属性的值构成List:

List<String> nameList = infoList.stream().map(BaseInfo::getName).collect(Collectors.toList());

当然也可以做元素的转换(例子方便演示,还请各位不要纠结Long 转Integer的问题):

List<Integer> integerList = infoList.stream().map(BaseInfo::getId).map(item -> Integer.parseInt(item.toString())).collect(Collectors.toList());

4.distinct 去重

整体去重:

List<BaseInfo> distinctEntityList = infoList.stream().distinct().collect(Collectors.toList());

指定属性去重:

 List<BaseInfo> distinctAppointList = infoList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item -> item.getName()))), ArrayList::new));

取对象中某一属性去重后数据:

List<String> distinctNameList = infoList.stream().map(BaseInfo::getName).distinct().collect(Collectors.toList());

5. foreach 遍历

list 遍历:

 infoList.forEach(item -> {
     System.out.println(item.getName());
 });
 infoList.forEach(item -> System.out.println(item.getName()));

map 遍历:

  orderInfoMap.forEach((k, v) -> {
      //可以进行多个操作
      System.out.println(k + "-" + v);
  });

6.filter 过滤

 // 获取 id大于15的数据
 List<BaseInfo> filterList = infoList.stream().filter(item -> item.getId() > 15L).collect(Collectors.toList());

7. sorted + comparator 排序

 //(1) 升序
 List<BaseInfo> sortedList = infoList.stream().sorted(Comparator.comparing(BaseInfo::getId)).collect(Collectors.toList());
 //(2) 降序(reversed)
 List<BaseInfo> reversedSortedList = infoList.stream().sorted(Comparator.comparing(BaseInfo::getId).reversed()).collect(Collectors.toList());
 

8. 匹配 anyMatch & allMatch

 //1. anyMatch 是否至少匹配一个元素
 boolean match = list.stream().anyMatch(item -> item.contains("A"));
 // true
 //2. allMatch 匹配所有元素
 boolean allMatch = list.stream().allMatch(item -> item.contains("B"));
 // false

9. 统计 max & min & findFirst & count & sum

   // (1) max
   Optional<BaseInfo> max = infoList.stream().max(Comparator.comparing(BaseInfo::getId));
   max.ifPresent(item -> System.out.println(item.getName()));
   //(2) min
   Optional<BaseInfo> min = infoList.stream().min(Comparator.comparing(BaseInfo::getId));
   min.ifPresent(item -> System.out.println(item.getName()));
   //(3) count
   long count = infoList.stream().filter(item -> item.getId() > 15L).count();
   //(4) sum
   Long sum = infoList.stream().mapToLong(BaseInfo::getId).sum();
   //(5) findFirst
   Optional<BaseInfo> firstInfo = infoList.stream().findFirst();
   infoList.stream().findFirst().ifPresent(item -> System.out.println(item.getAddress()));

总结

以上只是简单的列举了Java 8 中 Lambda的部分简单用法,希望能在日常的开发中助你一臂之力!!!