专栏名称: LitongZero
目录
相关文章推荐
研之成理  ·  ACS Central ... ·  6 天前  
研之成理  ·  北京大学齐利民课题组Adv. Funct. ... ·  4 天前  
PaperWeekly  ·  NeurIPS 2024 | ... ·  6 天前  
51好读  ›  专栏  ›  LitongZero

Java8 Lambda 使用总结

LitongZero  · CSDN  ·  · 2020-01-22 10:16

正文

一、演示示例

1.遍历

List<Integer> integerList = new ArrayList<>();
integerList.add(1);
integerList.add(2);
integerList.add(3);
integerList.stream().forEach(integer -> {
	System.out.println(integer);  // 1,2,3
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.去重

List<Integer> integerList = new ArrayList<>();
integerList.add(1);
integerList.add(1);
integerList.add(3);
integerList = integerList.stream().distinct().collect(Collectors.toList());
integerList.stream().forEach(integer -> {
	System.out.println(integer);  // 1,3
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3.获取对象中的某个参数为一个新的List

List<UserInfo> userInfos = new ArrayList<>();
userInfos.add(UserInfo.builder().uid("1").build());
userInfos.add(UserInfo.builder().uid("2").build());
userInfos.add(UserInfo.builder().uid("3").build());
List<String> uidList = userInfos.stream().map(UserInfo::getUid).collect(Collectors.toList());
uidList.stream().forEach(uid -> {
	System.out.println(uid);  // 1,2,3
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4.获取对象中的某个参数为一个新的Map

List<UserInfo> userInfos = new ArrayList<>();
userInfos.add(UserInfo.builder().uid("1").build());
userInfos.add(UserInfo.builder().uid("2").build());
userInfos.add(UserInfo.builder().uid("3").build());
Map<String, String> uidMap = userInfos.stream().map(UserInfo::getUid).collect(Collectors.toMap(String::toString, String::toString));
uidMap.forEach((key, value) -> {
	System.out.println(key + ":" + value);
});
//1:1
//2:2
//3:3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

5.过滤器

List<UserInfo> userInfos = new ArrayList<>();
userInfos.add(UserInfo.builder().uid("1").build());
userInfos.add(UserInfo.builder().uid("2").build());
userInfos.add(UserInfo.builder().uid("3").build());
List<UserInfo> userInfoList = userInfos.stream().
		// 过滤操作
		filter(userInfo -> userInfo.getUid().equals("1")).
		// 对象重组
		map(userInfo -> UserInfo.builder().uid(userInfo.getUid()).build()).
	    //收集结果
		collect(Collectors.toList());
// 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

6.排序

List<UserInfo> userInfos = new ArrayList<>();
userInfos.add(UserInfo.builder().uid("1").username("1").build());
userInfos.add(UserInfo.builder().uid("2").username("1").build());
userInfos.add(UserInfo.builder().uid("3").username("1").build());
userInfos.add(UserInfo.builder().uid("1").username("2").build());
userInfos.stream()
		// 排序(可设置第二排序规则.thenComparing())    reversed:翻转
		.sorted(Comparator.comparing(UserInfo::getUid).reversed())
		.collect(Collectors.toList())
		.forEach(userInfo -> {
			System.out.println(userInfo.getUid());  // 3,2,1,1
		});


userInfos.stream()
		  // 排序:先根据uid正向排序,再反排,相同uid再根据username正向排序
         .sorted(Comparator.comparing(UserInfo::getUid).reversed().thenComparing(UserInfo::getUsername))
		 .collect(Collectors.toList())
		 .forEach(userInfo -> {
		    System.out.println(userInfo.getUid()+"+"+userInfo.getUsername());
            // 3+1
			// 2+1
			// 1+1
			// 1+2
		 });

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

二、方法总结

1.1 .forEach(v ->{ })

遍历,的顺序不一定(并行流处理、效率更高)

1.2 .forEachOrdered(v ->{ })

遍历,的顺序严格按照元素顺序(效率更低)

2.1 .map()

可以看做是一个“处理器”,可以对list中的对象做一些操作,然后 return 任意类型,最后得到这个任意类型的list。
如,获取对象中的uid为一个list

List<UserInfo> userInfos = new ArrayList<>();
userInfos.add(UserInfo.builder().uid("1").build());
userInfos.add(UserInfo.builder().uid("2").build());
userInfos.add(UserInfo.builder().uid("3").build());
// 两种写法
List<String> uidList = userInfos.stream().map(UserInfo::getUid).collect(Collectors.toList());
List<String> uidList1 = userInfos.stream().map(userInfo -> {return userInfo.getUid();}).collect(Collectors.toList());
uidList.stream().forEach(uid -> {
	System.out.println(uid);  // 1,2,3
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.2 .peek()

功能与 .map() 类似,不过,不会改变list的对象,一般作为 中间操作 调式Lambda,查看当前list的属性 使用。
如:

List<UserInfo> userInfos = new ArrayList<>();
userInfos.add(UserInfo.builder().uid("1").username("1").build());
userInfos.add(UserInfo.builder().uid("2").username("1").build());
userInfos.add(UserInfo.builder().uid("1").username("1").build());
userInfos.add(UserInfo.builder().uid("1").username("2").build());
userInfos.stream().peek(System.out::println).forEach(userInfo -> {
	System.out.println(userInfo.getUid());
});

// 输出结果:
UserInfo(uid=1, username=1)
1
UserInfo(uid=2, username=1)
2
UserInfo(uid=1, username=1)
1
UserInfo(uid=1, username=2)
1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可以看到,每个参数在执行 forEach() 中的方法前,都先执行了 .peek() 中的方法。
这样,既可以在 .peek() 中查看每个元素的动态,又可以在 .peek() 中做一些对象处理操作。
但是要注意,与 .map() 不同的是, .peek() 不是链式调用的终结,不能单独使用。后面必须要跟 收集器,遍历器等
userInfos.stream().peek(System.out::println); 这样是不会有输出的。

3 .collect()

收集器,可将结果收集为List或Map,如: .collect(Collectors.toList())

4 .sorted()

排序,可接受函数式参数 .sorted(Comparator.comparing(UserInfo::getUid))

一般参数 .sorted((v1, v2) -> {return v1.getUid().compareTo(v2.getUid());})

不做复杂处理的情况下,推荐使用第一种。

5 .filter()

过滤器,接受一个布尔条件,如过滤uid为1的对象, .filter(userInfo -> userInfo.getUid().equals("1"))

6 .limit()

接受一个Long类型,获取list中的前几项。如,获取前两项 userInfos.stream().limit(2).collect(Collectors.toList())

7 .count()

获取list的大小

8 .toArray()

转化list为Object数组 Object[] objects = userInfos.stream().toArray();

9 .max()\.min()

根据条件获取最大值\最小值,接受参数与 3.sorted() 一致

如,获取uid最小的对象

UserInfo userInfo = userInfos.stream().min(Comparator.comparing(UserInfo::getUid)).get();

10 .reduce()

根据给定算法计算,返回结果

如,计算一个1,2,3,4的合。

List<Integer> integerList = new ArrayList<>();
integerList.add(1);
integerList.add(2);
integerList.add(3);
integerList.add(4);
// 两种写法, 两种参数
Integer reduce1 = integerList.stream().reduce((v1, v2) -> v1 + v2);
// 这里传了两个参数,第一个参数是一个默认值,最后结果会加上这个值,可以不传
Integer reduce2 = integerList.stream().reduce(1, (v1, v2) -> v1 + v2);
Integer reduce3 = integerList.stream().reduce(1, Integer::sum);
System.out.println(reduce1); // 10
System.out.println(reduce2); // 11
System.out.println(reduce3); // 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

11 .distinct()

去掉重复的对象

userInfos.stream().distinct().forEach(userInfo -> {
   System.out.println(userInfo.getUid() + "+" + userInfo.getUsername());
});
  • 1
  • 2
  • 3

12. .anyMatch()\.allMatch()\.noneMatch()

anyMatch表示,判断的条件里,任意一个元素成功,返回true

allMatch表示,判断条件里的元素,所有的都是,返回true

noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true

如,

List<Integer> strs = Arrays.asList(1, 2, 1, 4, 1);
boolean a = strs.stream().anyMatch(str -> str.equals(1));
boolean b = strs.stream().allMatch(str -> str.equals(2));
boolean c = strs.stream().noneMatch(str -> str.equals(3));
System.out.println(a);// true
System.out.println(b);// false
System.out.println(c);// true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

13 .findFirst()

获取当前list中的第一个对象,如

UserInfo userInfo = userInfos.stream().findFirst().get();
  • 1

三、单体操作

.findFirst() 取出的对象并不能直接使用,还需要使用单体操作,如: .get()\.orElse()

1.1 .get()

获取其中的元素

1.2 .orElse()

.get() 类似,不过可以设置一个默认值,当对象为空时,返回默认值

Stream.of("one", "two", "three", "four").findFirst().orElse("five");

2 .isPresent()

返回布尔值,判断对象是否为空。