文章目录
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());
- ObjectToInteget:
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()方法实现的无序流。
- 祛除重复元素:List< String> list = userList
.stream().distinct().collect(Collector.toList())
; - 延伸:Java 8 Stream.distinct() 列表去重示例
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)); } }
参考资料: