参考博客
https://blog.csdn.net/chenlixiao007/article/details/112752413
对以上博客内容的案例补充:
排序
注意:分页后再排序只能排当前页的数据(并不是没有生效)
/*
注意这儿排序是sorted(Comparator.comparing().thenComparing())
而不是sorted().sorted(),这样不对
*/
// 按成绩升序,再按年龄升序
List<Student> students5 = students.stream()
.sorted(Comparator.comparing(Student::getScore).thenComparing(Student::getAge))
.collect(Collectors.toList());
// 按成绩升序,再按年龄降序(自定义排序规则)
List<Student> students6 = students.stream().sorted((s1, s2) -> {
if (s1.getScore() != s2.getScore()) {
return (int) (s1.getScore() - s2.getScore());
} else {
return (s2.getAge() - s1.getAge());
}
}).collect(Collectors.toList());
// 倒序排序,元素不为空
List<Integer> integers = details.stream()
.map(ContractpriceStrategydetail::getLinenumber)
.filter(Objects::nonNull)
.sorted(Comparator.reverseOrder()).collect(Collectors.toList());
// 先按字符串长度排序,再按字符串排序
List<String> records = Arrays.asList("0001", "000003", "0000", "00000", "0002");
records = records.stream().sorted(Comparator.comparingInt(String::length).thenComparing(item -> item)).collect(Collectors.toList());
records.forEach(System.err::println);
// 输出:
// 0000
// 0001
// 0002
// 00000
// 000003
// 通过定义Comparator比较器来排序:先按客户代码ownerid的长度排序,再按客户代码自然语言规则排序
Comparator<Client> owneridLengthComparator = Comparator.comparingInt(c -> c.getOwnerid().length());
Collator collator = Collator.getInstance(Locale.getDefault());
Comparator<Client> owneridComparator = Comparator.comparing(Client::getOwnerid, collator::compare);
List<Client> records = records.stream().sorted(owneridComparator.thenComparing(owneridLengthComparator)).collect(Collectors.toList());
// 按客户代码自然语言规则排序
List<Client> records = records = records.stream().sorted(Client::getOwnerid)).collect(Collectors.toList());
去重
// 对象的集合按某个字段(分数)去重
List<Student> students = students
.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getScore))), ArrayList::new));
查找对象中 重复/不重复元素
public static void main(String[] args) {
List<OuthouseplanShip> list = new ArrayList<>();
OuthouseplanShip ship1 = new OuthouseplanShip();
ship1.setShipname("苏x00000");
OuthouseplanShip ship2 = new OuthouseplanShip();
ship2.setShipname("苏A12354");
OuthouseplanShip ship3 = new OuthouseplanShip();
ship3.setShipname("苏K66666");
OuthouseplanShip ship4 = new OuthouseplanShip();
ship4.setShipname("苏x00000");
OuthouseplanShip ship5 = new OuthouseplanShip();
ship5.setShipname("苏K66666");
OuthouseplanShip ship6 = new OuthouseplanShip();
ship6.setShipname("苏K66666");
list.add(ship1);
list.add(ship2);
list.add(ship3);
list.add(ship4);
list.add(ship5);
list.add(ship6);
System.out.println("原数据:" + list);
// 判断车号是否有重复,如果collect1.size() == 1表示列表中该字段的值没有不同的,都一样
List<String> collect1 = list.stream().map(OuthouseplanShip::getShipname).distinct().collect(Collectors.toList());
System.out.println("去除重复车号后的列表数据:" + collect1);
if (collect1.size() != list.size()) {
System.out.println("有重复");
}
// 车号的计数情况
Map<String, Long> collect2 = list.stream().collect(Collectors.groupingBy(OuthouseplanShip::getShipname, Collectors.counting()));
System.out.println("车号的计数情况:" + collect2);
// 筛出有重复的车号
List<String> collect3 = collect2.keySet().stream().filter(key -> collect2.get(key) > 1).collect(Collectors.toList());
System.out.println("筛出有重复的车号:" + collect3);
// 筛出有重复的车号并保留计数
Map<String, Long> collect4 = collect2.keySet().stream().filter(key -> collect2.get(key) > 1).collect(Collectors.toMap(key -> key, collect2::get));
System.out.println("筛出有重复的车号并保留计数:" + collect4);
}
// 查找列表中的重复/不重复元素 筛出列表中重复的值 适用于纯数字或纯字符串列表
public static <E> List<E> getDuplicateElements(List<E> list) {
return list.stream() // list 对应的 Stream
.collect(Collectors.toMap(e -> e, e -> 1, Integer::sum)) // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
.entrySet().stream() // 所有 entry 对应的 Stream
// .filter(entry -> entry.getValue() > 1) // 查找重复元素:过滤出元素出现次数大于 1 的 entry
.filter(entry -> entry.getValue() == 1) // 查找不重复元素:过滤出元素出现次数等于 1 的 entry
.map(Map.Entry::getKey) // 获得 entry 的键(重复元素)对应的 Stream
.collect(Collectors.toList()); // 转化为 List
}
归集 toMap
注意Map的key不能为空!
// 创建学生ID和学生年龄的map
Map<String, Integer> collect = students.stream().collect(Collectors.toMap(Student::getId,Student::getAge))
.forEach((key,value) -> {System.out.println(key + "->" + value);});
// 创建学生ID和学生实体的map
Map<String, Student> studentMap = students
.stream().collect(Collectors.toMap(Student::getId, student -> student));
// 先根据学生类的性别分组,再取每组最大
Map<String, Student> collect = students.parallelStream().collect(
Collectors.toMap(Student::getSex, Function.identity(), (c1, c2) -> c1.getAge() > c2.getAge() ? c1 : c2)
);
// Collectors.toMap,当value为null时报空指针异常。解决方式,自己实现collect方法:
Map<String, String> collect = zmquantityList.stream()
.filter(item -> StringUtils.isNotEmpty(item.getBillno()))
.collect(HashMap::new, (m, v) -> m.put(v.getBillno(), v.getZmquantity()), HashMap::putAll); // 自己实现collect方法
// .collect(Collectors.toMap(ZmquantityListVO::getBillno, ZmquantityListVO::getZmquantity));// 原collect方法
flatMap
参考:https://blog.csdn.net/qq_24184997/article/details/88116471
List<String> list = new ArrayList<>();
list.add("123");
list.add("78,456");
List<String> collect = list.stream().flatMap(item -> Arrays.stream((item.split(",")))).collect(Collectors.toList());
System.out.println("collect = " + collect); // collect = [123, 78, 456]
List<List<Integer>> lists = new ArrayList<>();
List<Integer> list = new ArrayList<>();
list.add(4444);
list.add(33333);
list.add(444444);
lists.add(list);
lists.forEach(System.out::println); // [4444, 33333, 444444]
lists.stream().flatMap(Collection::stream).forEach(System.out::println);
// 4444
// 33333
// 444444
map的使用
// 获取List<User>中最大年龄(age)的值
List<User> userList = // 获取List<User>的数据
int maxAge = userList.stream()
.mapToInt(User::getAge) // 将User对象映射为年龄
.max() // 获取最大值
.orElse(0); // 如果列表为空,默认返回0
System.out.println(maxAge); // 输出最大年龄