Java8 Stream流

参考博客
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); // 输出最大年龄
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值