Java 8 Lambda表达式使用总结

Lambda表达式

示例实体类

@Data
public class User{
	private int id;  //id
	private Double score;  //成绩
	private String name;  //姓名
	private String sex;  //性别
	private BigDecimal property;//财产
	private Date birthDay;  //生日
}

示例Map<String,object> map

Map<String,object> map = new HashMap<>();
map.put("id",1);
map.put("name","hucong");
map.put("age",23);
map.put("score",100.0);

1、通过条件过滤filter()

  • 获取男性用户集合:List< User> list = userList.stream().filter(t->t.getSex().equals("female")).collect(Collectors.toList());
    其他参考:list中快速进行数据筛选
  • 补充List<Map<String,Object>> listMap处理:
    • ObjectToInteget:
      获取年龄大于18岁的用户的集合:listMap = listMap.stream().filter(t->StringUtils.toInteger(t.get("age"))>18).collect(Collectors.toList());
    • ObjectToString:
      获取姓名为“hucong”的用户的集合::listMap = listMap.stream().filter(t->t.get("name").equals("hucong")).collect(Collectors.toList());

2、获取list某个字段组装新list方法map()

  • 得到用户姓名组装成新的集合:List< String> list = userList.stream().map(User::getName).collect(Collectors.toList());
  • 补充List<Map<String,Object>> listMap处理:
    获取用户姓名的集合的集合:List< String> list = listMap.map(t->t.get("name").toString).collect(Collectors.toList());

3、去重distinct() [指定条件去重见标号9]

distinct()返回由该流的不同元素组成的流。distinct()是Stream接口的方法。distinct()使用hashCode()和equals()方法来获取不同的元素。因此,我们的类必须实现hashCode()和equals()方法。如果distinct()正在处理有序流,那么对于重复元素,将保留以遭遇顺序首先出现的元素,并且以这种方式选择不同元素是稳定的。在无序流的情况下,不同元素的选择不一定是稳定的,是可以改变的。distinct()执行有状态的中间操作。在有序流的并行流的情况下,保持distinct()的稳定性是需要很高的代价的,因为它需要大量的缓冲开销。如果我们不需要保持遭遇顺序的一致性,那么我们应该可以使用通过BaseStream.unordered()方法实现的无序流。

4、单字段多字段排序sort()和stream.sorted()

  • sort()

  • 按成绩单字段排序:List< User> list = userList.sort(Comparator.comparing(User::getScore));
  • 按成绩和id多字段排序:List< User> list = userList.sort(Comparator.comparing(User::getScore).thenComparing(User::getId));
  • 按成绩,如果成绩中有null值则倒序排列:List< User> list = userList.sort(Comparator.comparing(User::getScore,Comparator.nullsLast(Comparator.naturalOrder())));
  • stream.sorted()

  • 按成绩升序排列:List< User> list = userList.stream().sorted(Comparator.comparing(User::getScore)).collect(toList());
  • 按成绩降序排列:List< User> list = userList.stream().sorted(Comparator.comparing(User::getScore)).reversed().collect(toList());
  • 补充List<Map<String,Object>> listMap处理:
    按用户的年龄从大到小排序:
    • 排序:listMap = listMapstream().sorted(Comparator.comparing(t->StringUtils.toInteger(t.get("age")))).collect(Collectors.toList());
    • 反转:(因为默认是从下到大排,所以需要颠倒):Collections.reverse(listMap);
  • 延伸:Java 8 Comparator nullsFirst naturalOrder困惑

5、汇总求和sum()

  • 基本数据类型,如int:int sumScore = userList.strem().mapToInt(User::getScore).sum();
  • 其他数据类型,如BigDecimal:BigDecimal totalProperty = userList.stream().map(User::getProperty).reduce(BigDecimal.ZERO,BigDecimal::add);
  • 补充List<Map<String,Object>> listMap处理:
    求用户总分:Double total = materialByYear.stream().mapToDouble(t->StringUtils.toDouble(t.get("score"))).sum();

6、找最值.min

  • 找到年龄最大的学生生日:Date maxBirthDay = userList.stream().map(User::getBirthday).max(Date::compareTo).get();
  • 找到最低分:Double minScore = userList.stream().min(Comparator.comparingDouble(User::getScore)).get();

7、list转map

  • 将User中的姓名作为键名,对应实体作为键值,组成新的Map:Map< String,User> map = list.stream().collect(Collectors.toMap(User::getName,t->t));
  • 将User中的姓名作为键名,对应实体作为键值,组成新的Map,如果有重复键名则保留先进入map的那一个:Map< String,User> map = list.stream().collect(Collectors.toMap(User::getName,t -> t,(k1,k2)->k1));
    //注:toMap 如果集合对象有重复的key,会报错Duplicate key …Name可能重复。可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
    //如果想得到姓名的键值列表:Set< String> userNames = map.keySet();
    //如果想比对某一个名称是否在已存在map中:if(map.containKey(user.getName())){printf("已存在该用户")}
  • 补充List<Map<String,Object>> listMap处理:
    将map中“id”字段作为键名,对应的map作为键值:
    Map<String,Map<String,Object>> newMap = mapList.stream().collect(Collectors.toMap(t->t.get("id").toString(),t->t));

8、通过指定字段进行分组Collectors.groupingBy()

  • 根据性别进行分组:Map<String, List< User>> groupBySex = userList.stream().collect(Collectors.groupingBy(User::getSex));
  • 补充List<Map<String,Object>> listMap处理:
    根据性别分组:Map<String,List<Map<String,Object>>> groupBy = listMap.stream().collect(Collectors.groupingBy(t->t.get("sex").toString()));

9、指定字段或者条件进行去重

  • 根据分数去重实体:List< User> list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getScore))),ArrayList::new));
  • 如果两个对象分数和性别一致,则去重:List< User> list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<>(Comparator.comparing(t->t.getName()+t.getSex()))),ArrayList::new));

10、其他:

  • List< Integer>转成List< String>
    List< String> list = intList.stream().map(t->String.format("%s",t)).collect(toList());
  • List< Integer>正、倒序
    正序排列:Collections.sort(list);
    倒序排列:list.sort(Comparator.revseOrder());
  • List< String>中保存的为成绩信息,对成绩信息进行求和计数等操作
    IntSummaryStatistics stats = list.stream().mapToDouble((t)->t).summaryStatustics();
    最大值:stats.getMax();
    最小值:stats.getMin();
    求和:stats.getSum();
    平均数:stats.getAverage();
    计数:stats.getCount();
    toString():stats.toString();
    
  • 通过复杂条件过滤list中的元素
    需求:有一个用户信息List< User>list集合和一个Id集合List< Integer>listInt,需要将在list中id在集合listInt中的对象去除:
    //首先将list转成id-entity的键值对(id不可能重复,所以不考虑键名重复的情况)
    Map< Integer,User> map = list.stream().collect(Collectors.toMap(User::getId,t->t));
    //得到键值集合
    Set< Integer> ids = map.keySet();
    //通过set的contains()方法判定
    for(Integer i:listInt){
    	if(ids.contains(i)){
    		list.remove(map.get(i));
    	}
    }
    

参考资料:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章