Lambada表达式 示例代码

以下代码段,由猴哥提供,感谢我猴哥!

Stream 流式计算:
 Ø 一个流式处理可以分为三个部分:转换成流、中间操作、终端操作。
 流:集合流、数组流、文件流…
 中间操作:filter、distinct、limit、skip、sorted、map、flatmap…
 终端操作:allMatch、anyMatch、noneMatch、findFirst、findAny、count、reduce、Collect…

Ø 一个流式处理的操作我们首先需要调用 stream() 函数将其转换成流,然后在调用相应的中间操作达到我们需要对集合进行的操作,比如筛选、转换等,最后通过终端操作对前面的结果进行封装,返回我们需要的形式。
Ø 使用示例:

		public classUser{
			private Long id;       //主键id
			private String name;   //姓名
			private Integer age;   //年龄
			private String school; //学校
			public User(Long id, String name, Integer age, String school) {
			   this.id = id;
			   this.name = name;
			   this.age = age;
			   this.school = school;
			}
			List<User> list = new ArrayList<User>(){
			    {
			        add(new User(1l,"张三",10, "清华大学"));
			        add(new User(2l,"李四",12, "清华大学"));
			        add(new User(3l,"王五",15, "清华大学"));
			        add(new User(4l,"赵六",12, "清华大学"));
			        add(new User(5l,"田七",25, "北京大学"));
			        add(new User(6l,"小明",16, "北京大学"));
			        add(new User(7l,"小红",14, "北京大学"));
			        add(new User(8l,"小华",14, "浙江大学"));
			        add(new User(9l,"小丽",17, "浙江大学"));
			        add(new User(10l,"小何",10, "浙江大学"));
			    }
		};
		// filter 过滤:过滤筛选所有学校是清华大学的user
		List<User> userList1 = list.stream().filter(user -> "清华大学".equals(user.getSchool())).collect(Collectors.toList());
			
		// distinct 去重:我们希望获取所有user的年龄(年龄不重复)
		List<Integer> userAgeList = list.stream().map(User::getAge).distinct().collect(Collectors.toList());
			
		// limit 返回前n个元素的流,当集合的长度小于n时,则返回所有集合:取年龄是偶数的前2名user
	    List<User> userList3 = list.stream().filter(user -> user.getAge() % 2 == 0).limit(2).collect(Collectors.toList());
			
		// sorted 排序:将所有user按照age从大到小排序
	    List<User> userList4 = list.stream().sorted((s1,s2) -> s2.age - s1.age).collect(Collectors.toList());
			
		// skip 跳过 n 个元素后输出:跳过前两个元素后的list
		List<User> userList5 = list.stream().skip(2).collect(Collectors.toList());
			
		// map 将一个 List 对象精简为某个字段的集合:学校是清华大学的所有学生的姓名
		List<String> userList6 = list.stream().filter(user -> "清华大学".equals(user.school)).map(User::getName).collect(Collectors.toList());
			
		// java 还提供了 mapToDouble(ToDoubleFunction<? super T> mapper)、mapToInt(ToIntFunction<? super T> mapper)、mapToLong(ToLongFunction<? super T> mapper),这些映射分别返回对应类型的流,比如查询学校是清华大学学生的年龄总和:
		int userList7 = list.stream().filter(user -> "清华大学".equals(user.school)).mapToInt(User::getAge).sum();
			
		// flatMap flatMap 与 map 的区别是 flatMap 是将一个流中的每个值都转成一个个流,然后在将这些流扁平化成为一个流。举例说明,假设我们有一个字符串数组 String[] strs = {"hello","world"};,我们希望输出构成这一数组的所有非重复字符,那么我们用 map 和 flatMap 实现如下:
		String[] strings = {"Hello", "World"};
		List l11= Arrays.stream(strings).map(str -> str.split("")).map(str2->Arrays.stream(str2)).distinct().collect(Collectors.toList());
		List l2 = Arrays.asList(strings).stream().map(s -> s.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
		System.out.println(l11.toString());
		System.out.println(l2.toString());  
		输出结果如下:
		[java.util.stream.ReferencePipeline$Head@4c203ea1, java.util.stream.ReferencePipeline$Head@27f674d]
		[H, e, l, o, W, r, d]  
		由此可以看出 map 并不能实现我们想要的结果,而 flatMap 是可以的。这是因为在执行map操作以后,我们得到是一个包含多个字符串(构成一个字符串的字符数组)的流,此时执行distinct操作是基于在这些字符串数组之间的对比,所以达不到我们希望的目的;flatMap将由map映射得到的Stream<String[]>,转换成由各个字符串数组映射成的流Stream<String>,再将这些小的流扁平化成为一个由所有字符串构成的大流Steam<String>,从而能够达到我们的目的。
			
		// allMatch 检测是否全部满足指定的参数行为,如果全部满足则返回 true:判断是否所有的年龄都大于 9 岁的
		Boolean b = list.stream().allMatch(user -> user.age > 9);
			
		// anyMatch 检测是否存在一个或多个满足指定的参数行为,满足则返回 true :判断是否有年龄大于 15 岁的
		Boolean b = list.stream().anyMatch(user -> user.age > 15);
			
		// noneMatch 检测是否不存在满足指定行为的元素,不存在则返回 true :判断是否不存在年龄是15岁的
		Boolean boo = list.stream().noneMatch(user -> user.age == 15);
			
		// findFirst 返回满足条件的第一个元素:返回年龄大于12岁中的第一个
		Optional<User> first = list.stream().filter(u -> u.age > 10).findFirst();
		User user = first.get();
			
		// findAny findAny 与 findFirst 的区别在于,findAny 不一定返回第一个,而是返回任意一个:返回年龄大于12岁中的任意一个
		Optional<User> anyOne = list.stream().filter(u -> u.age > 10).findAny();
		User user2 = anyOne.get();
			
		// reduce 归约:现在我的目标不是返回一个新的集合,而是希望对经过参数化操作后的集合进行进一步的运算,那么我们可用对集合实施归约操作,比如我现在要查出学校是清华大学的所有user的年龄之和:
		//前面用到的方法
		Integer ages = list.stream().filter(student -> "清华大学".equals(student.school)).mapToInt(User::getAge).sum();
		System.out.println(ages);
		System.out.println("归约 - - 》 start ");
		Integer ages2 = list.stream().filter(student -> "清华大学".equals(student.school)).map(User::getAge).reduce(0,(a,c)->a+c);
		Integer ages3 = list.stream().filter(student -> "清华大学".equals(student.school)).map(User::getAge).reduce(0,Integer::sum);
		Integer ages4 = list.stream().filter(student -> "清华大学".equals(student.school)).map(User::getAge).reduce(Integer::sum).get();
		System.out.println(ages2);
		System.out.println(ages3);
		System.out.println(ages4);
		System.out.println("归约 - - 》 end ");
		输出结果为:
		49
		归约 - - 》 start 
		49
		49
		49
		归约 - - 》 end
			
		// counting 计算个数:计算总人数
		long COUNT = list.stream().count();//简化版本
		long COUNT2 = list.stream().collect(Collectors.counting());//原始版本
		System.out.println(COUNT);
		System.out.println(COUNT2);
			
		// maxBy 和 minBy 计算最大值和最小值:计算年龄的最大值和最小值
		System.out.println("user的年龄最大值和最小值");
		Integer maxAge =list.stream().collect(Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge())).get().age;
		Integer maxAge2 = list.stream().collect(Collectors.maxBy(Comparator.comparing(User::getAge))).get().age;
		Integer minAge = list.stream().collect(Collectors.minBy((S1,S2) -> S1.getAge()- S2.getAge())).get().age;
		Integer minAge2 = list.stream().collect(Collectors.minBy(Comparator.comparing(User::getAge))).get().age;
		System.out.println("maxAge = " + maxAge);
		System.out.println("maxAge2 = " + maxAge2);
		System.out.println("minAge = " + minAge);
		System.out.println("minAge2 = " + minAge2);
			
		// summingInt、summingLong、summingDouble 总和:计算年龄总和
		Integer sumAge =list.stream().collect(Collectors.summingInt(User::getAge));
			
		// averageInt、averageLong、averageDouble 平均值:计算年龄的平均值
		double averageAge = list.stream().collect(Collectors.averagingDouble(User::getAge));
			
		// summarizingInt、summarizingLong、summarizingDouble 一次性查询元素个数、总和、最大值、最小值和平均值:
		IntSummaryStatistics summaryStatistics = list.stream().collect(Collectors.summarizingInt(User::getAge));
		System.out.println("summaryStatistics = " + summaryStatistics);
		//结果:summaryStatistics = IntSummaryStatistics{count=10, sum=145, min=10, average=14.500000, max=25}
			
		// joining 字符串拼接:如输出所有user的名字,用“,”隔开
		String names = list.stream().map(User::getName).collect(Collectors.joining(","));
			
		// groupingBy 分组:将user根据学校分组、先按学校分再按年龄分、每个大学的user人数、每个大学不同年龄的人数
		Map<String, List<User>> collect1 = list.stream().collect(Collectors.groupingBy(User::getSchool));
		Map<String, Map<Integer, Long>> collect2 = list.stream().collect(Collectors.groupingBy(User::getSchool, Collectors.groupingBy(User::getAge, Collectors.counting())));
		Map<String, Map<Integer, Map<String, Long>>> collect4 = list.stream().collect(Collectors.groupingBy(User::getSchool, Collectors.groupingBy(User::getAge, Collectors.groupingBy(User::getName,Collectors.counting()))));
		Map<String, Long> collect3 = list.stream().collect(Collectors.groupingBy(User::getSchool, Collectors.counting()));
		System.out.println("collect1 = " + collect1);
		System.out.println("collect2 = " + collect2);
		System.out.println("collect3 = " + collect3);
		System.out.println("collect4 = " + collect4);
		结果:
		collect1 = {浙江大学=[User{id=8, name='小华', age=14, school='浙江大学'}, User{id=9, name='小丽', age=17, school='浙江大学'}, User{id=10, name='小何', age=10, school='浙江大学'}], 北京大学=[User{id=5, name='田七', age=25, school='北京大学'}, User{id=6, name='小明', age=16, school='北京大学'}, User{id=7, name='小红', age=14, school='北京大学'}], 清华大学=[User{id=1, name='张三', age=10, school='清华大学'}, User{id=2, name='李四', age=12, school='清华大学'}, User{id=3, name='王五', age=15, school='清华大学'}, User{id=4, name='赵六', age=12, school='清华大学'}]}
		collect2 = {浙江大学={17=1, 10=1, 14=1}, 北京大学={16=1, 25=1, 14=1}, 清华大学={10=1, 12=2, 15=1}}
		collect3 = {浙江大学=3, 北京大学=3, 清华大学=4}
		collect4 = {浙江大学={17={小丽=1}, 10={小何=1}, 14={小华=1}}, 北京大学={16={小明=1}, 25={田七=1}, 14={小红=1}}, 清华大学={10={张三=1}, 12={李四=1, 赵六=1}, 15={王五=1}}}
			
		// partitioningBy 分区,分区可以看做是分组的一种特殊情况,在分区中key只有两种情况:true或false,目的是将待分区集合按照条件一分为二:按照是否是清华大学的user将左右user分为两个部分
		Map<Boolean, List<User>> collect5 = list.stream().collect(Collectors.partitioningBy(user1 -> "清华大学".equals(user1.school)));
		System.out.println("collect5 = " + collect5);
		结果:
		collect5 = {false=[User{id=5, name='田七', age=25, school='北京大学'}, User{id=6, name='小明', age=16, school='北京大学'}, User{id=7, name='小红', age=14, school='北京大学'}, User{id=8, name='小华', age=14, school='浙江大学'}, User{id=9, name='小丽', age=17, school='浙江大学'}, User{id=10, name='小何', age=10, school='浙江大学'}], true=[User{id=1, name='张三', age=10, school='清华大学'}, User{id=2, name='李四', age=12, school='清华大学'}, User{id=3, name='王五', age=15, school='清华大学'}, User{id=4, name='赵六', age=12, school='清华大学'}]}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值