Java8 Stream 使用
filter(过滤)
该操作n的函数,当返回false的元素将会被排除掉。
举例:假如我们100个客户,需要筛选出年龄大于18岁的客户。
List<SysUser> collect = userList.stream()
.filter(user -> user.getAge() > 18)
.collect(Collectors.toList());
去重
distinct
该操作将会排除掉重复的元素。
List<SysUser> collect = userList.stream()
.distinct()
.collect(Collectors.toList());
也可结合别的方法使用。如下:去掉集合中大于5的重复值。
List<Integer> collect = Stream.of(1, 2, 5, 6, 7, 8, 9, 7, 2)
.filter(num -> num > 5)
.distinct()
.collect(Collectors.toList());
输出:
[6, 7, 8, 9]
使用 collectingAndThen() 和 toCollection() 方法
这个方法可以根据元素的某个属性或者多个属性来去重,比如 name 或者 name+address。这个方法会使用 TreeSet 来排序元素,所以不能保持原来的顺序。
//根据name属性去重
List<User> lt = list.stream().collect(
collectingAndThen(
toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))),
ArrayList::new)
);
System.out.println("去重后的:" + lt);
Map
List<KnowledgeQuest> distinctList = knowledgeQuestList.stream()
.collect(Collectors.toMap(
KnowledgeQuest::getKnowkey, // 使用 knowkey 作为 Map 的键
Function.identity(), // 使用 KnowledgeQuest 对象自身作为值
(existing, replacement) -> replacement)) // 如果出现重复的 knowkey,用新值替换旧值
.values()
.stream()
.collect(Collectors.toList());
limit(限量)
该方法限制流只返回指定个数的元素。
List<Integer> collect = Stream.of(1, 2, 5, 6, 7, 8, 9, 7, 2)
.limit(5)
.collect(Collectors.toList());
输出:
[1, 2, 5, 6, 7]
skip(跳过)
扔掉前指定个数的元素;配合limit使用可以达到翻页的效果。
List<Integer> collect = Stream.of(1, 2, 5, 6, 7, 8, 9, 7, 2)
.skip(2)
.limit(5)
.collect(Collectors.toList());
输出:
[5, 6, 7, 8, 9]
map
该方法提供一个函数,流中的每个元素都会应用到这个函数上,返回的结果将形成新类型的流继续后续操作。
将一个元素映射成一个新的元素。
举例:假如我们100个客户,需要筛选出年龄大于18岁的客户,打印出他们的名字
userList.stream().filter(user-> user.getRoleId()>18).map(SysUser::getName).forEach(System.out::println);
相当于
for (SysUser sysUser : userList) {
if (sysUser.getAge() > 18) {
String name = sysUser.getName();
System.out.println(name);
}
}
在调用map之前流的类型是Stream
过滤并获取名字列表
List<String> userNameList = userList.stream().filter(user-> user.getRoleId()>18).map(SysUser::getName)..collect(Collectors.toList());
获取Id和名字的map
Map<Long, String> userIdNameMap = userList.stream().collect(Collectors.toMap(SysUser::getId, SysUser::getName));
统计
# 统计
IntSummaryStatistics statistics = userList.stream().mapToInt(SysUser::getAge).summaryStatistics();
// 获取和值
long totalAge= statistics.getSum();
// 获取平均值
double avaAge= statistics.getAverage();
# 求和
int totalAge = userList.stream().mapToInt(SysUser::getAge).sum();
flatMap
它可以将一个流中的元素转换成多个元素,并将这些元素“扁平化”到一个流中。
将一个元素映射成一个流(Stream),然后将多个流合并成一个流。
扁平化元素合并到一个。
List<String> existList = questList.stream()
.flatMap(quest -> Stream.of(quest.getDxh(), quest.getSid())) // 扁平化 dxh 和 sid
.collect(Collectors.toList()); // 收集到 list 中
groupingBy(分组)
对元素按照条件进行分组。
List<String> list = Arrays.asList("apple", "banana", "orange");
Map<Integer, List<String>> grouped = list.stream().collect(Collectors.groupingBy(fruit -> fruit.length()));
分组计数
List<User> userList = new ArrayList<>();
userList.add(new User("张","张三"));
userList.add(new User("张","张四"));
userList.add(new User("张","张五"));
userList.add(new User("李","李一"));
userList.add(new User("李","李二"));
Map<String, Integer> groupCount = userList.stream()
.collect(Collectors.toMap(User::getFirstName, el -> 1, Integer::sum));
System.out.println(groupCount);
// {张=3, 李=2}
即姓张的有3个,姓李的有两个。
详解: 将该集合的stream流用Collectors对象转成Map,用User对象的firstName作为Key,默认键值为1,在处理键冲突的函数中,将上一次的值与默认值1相加。比如处理第一个姓张的人的时候,默认值为1,处理第二个也是姓张的人的时候默认值也是1,将1和1相加得2,(即有两个姓张的人了),处理第三个姓张的人的时候,将上次的结果2与第三个姓张返回的默认值1相加,得3,以此类推...得到处理结果。
sorted(排序)
对所有的元素进行排序。
List<Integer> collect5 = Stream.of(1, 2, 5, 6, 7, 8, 9, 7, 2)
.sorted(Integer::compareTo)
.collect(Collectors.toList());
输出:
[1, 2, 2, 5, 6, 7, 7, 8, 9]
排序方式
自然序排序:
list.stream().sorted()
自然序逆序:
list.stream().sorted(Comparator.reverseOrder())
Comparator排序:
list.stream().sorted(Comparator.comparing(Student::getAge))
Comparator逆序:
list.stream().sorted(Comparator.comparing(Student::getAge).reversed())
JSONArray按字段排序:
jsonArray.sort(Comparator.comparing(obj -> ((JSONObject) obj).getString("cdn").length()).reversed());
倒序写法:
jsonArray.sort(Comparator.comparing(obj -> obj.getIntValue("count")).reversed());
这样写 reversed 会报错,需要指定类型,如下:
jsonArray.sort(Comparator.comparing((JSONObject obj) -> obj.getIntValue("count")).reversed());
使用list的排序方式:
list.sort(Comparator.comparing(Integer::intValue));
list.sort(Comparator.comparing(Integer::intValue).reversed());
list.sort(Comparator.comparing(Student::getAge));
list.sort(Comparator.comparing(Student::getAge).reversed());
Map排序
Map<String, List<EditionInfo>> collect = list.stream()
.collect(Collectors.groupingBy(EditionInfo::getPinyinKey))
.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
使用 Collectors.groupingBy 方法将 list 按照 pinyinKey 分组。
将分组后的 Map 转换为 entrySet 的流。
使用 sorted(Map.Entry.comparingByKey()) 对 entrySet 按键进行自然升序排序。
使用 Collectors.toMap 方法将排序后的 entrySet 收集到一个新的 LinkedHashMap 中,以保证键的顺序。
MAX(取最大值)
传统写法
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer max = list.stream().max((a, b) -> {
if (a > b) {
return 1;
} else return -1;
}).get();
System.out.println(max);
}
stream 简化写法
int max = list.stream().max((a, b) -> a > b ? 1 : -1).get();
JSON List 取最大值
List<JSONObject> list= new ArrayList<>();
int max = list.stream().max((a, b) -> a.getIntValue("count") > b.getIntValue("count") ? 1 : -1).get().getIntValue("count");
工具类
## 计算list去重后的数量
/**
* 计算list去重后的数量
*
* @param list
* @param keyExtractor
* @param filters
* @param <T>
* @return
*/
public static <T> long countDistinctByKey(List<T> list, Function<T, ?> keyExtractor, Predicate<T>... filters) {
Predicate<T> combinedFilter = t -> true; // 默认条件是 always true
for (Predicate<T> filter : filters) {
combinedFilter = combinedFilter.and(filter); // 组合多个条件
}
return list.stream()
.filter(combinedFilter) // 应用组合后的过滤条件
.collect(Collectors.toMap(
keyExtractor, // 提取键
Function.identity(), // 取值为自身
(existing, replacement) -> replacement)) // 如果出现重复的键,使用新值替换旧值
.size(); // 计算去重后的数量
}
使用
long knowSize = countDistinctByKey(knowledgeQuestList, KnowledgeQuest::getKnowkey, kq -> kq.getRight()==1);
参考
https://blog.csdn.net/qq_38989725/article/details/109313270
https://blog.csdn.net/qq_20009015/article/details/90634905
https://blog.csdn.net/qq_30312047/article/details/114583063
https://blog.csdn.net/weixin_45313494/article/details/130801973
想想你的文章写的特别好www.jiwenlaw.com