Java 8 Stream
1、关于Java8部分新特性介绍
Java8的新特性很多,在此就不一一介绍了,这里只说一下我自己在工作用用得比较多的几点:
1.1、Lambda表达式
Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)
- 语法格式:
(parameters) -> expression 或者 (parameters) -> {statements;}
- PS:
(1)如果参数只有一个,可以不加圆括号
(2)不需要声明参数类型
(3)如果只有一条语句,可以不加花括号
(4)如果只有一条语句,编译器会自动将值返回;如果多条的话,需要手动return
1.2、方法引用
方法引用通过方法的名字来指向一个方法
- 语法格式:
方法引用使用一对冒号 ::
构造方法引用: 类::new
静态方法引用:类::静态方法
实例方法引用:类::实例方法 或者 对象::实例方法
1.3、Stream API
这个有点像Strom的处理方法(Spout和Blot),又有点像MapReduce(map和reduce)。用流的方式去处理,把一个集合元素转成一个一个的流,然后分别处理,最后再汇总。
1.4、接口中可以定义默认方法和静态方法
2、Stream API
1 private List<CouponInfo> couponInfoList; 2 3 private List<String> strList; 4 5 private List<Integer> intList; 6 7 @Before 8 public void init() { 9 CouponInfo couponInfo1 = new CouponInfo(123L, 10001, "5元现金券"); 10 CouponInfo couponInfo2 = new CouponInfo(124L, 10001, "10元现金券"); 11 CouponInfo couponInfo3 = new CouponInfo(125L, 10002, "全场9折"); 12 CouponInfo couponInfo4 = new CouponInfo(126L, 10002, "全场8折"); 13 CouponInfo couponInfo5 = new CouponInfo(127L, 10003, "全场7折"); 14 15 couponInfoList = new ArrayList<>(); 16 couponInfoList.add(couponInfo1); 17 couponInfoList.add(couponInfo2); 18 couponInfoList.add(couponInfo3); 19 couponInfoList.add(couponInfo4); 20 couponInfoList.add(couponInfo5); 21 22 couponInfoList = new ArrayList<>(); 23 couponInfoList.add(couponInfo1); 24 couponInfoList.add(couponInfo2); 25 couponInfoList.add(couponInfo3); 26 couponInfoList.add(couponInfo4); 27 couponInfoList.add(couponInfo5); 28 29 strList = Arrays.asList(new String[]{"A", "S", "D", "F", "X", "C", "Y", "H", "", null}); 30 31 intList = Arrays.asList(new Integer[]{1, 2, 3, 4, 5, 6, 6, 2, 3}); 32 }
2.1、forEach
1 /** 2 * 迭代 forEach 3 */ 4 @Test 5 public void testForEach() { 6 strList.stream().forEach(System.out::println); 7 strList.stream().forEach(e->System.out.print(e)); 8 System.out.println(); 9 strList.forEach(System.out::print); 10 }
A S D F X C Y H null ASDFXCYHnull ASDFXCYHnull
2.2、filter
1 /** 2 * 过滤 filter 3 */ 4 @Test 5 public void testFilter() { 6 List<String> list = strList.stream().filter(x-> StringUtils.isNotBlank(x)).collect(Collectors.toList()); 7 System.out.println(list); 8 List<Integer> list2 = intList.stream().distinct().collect(Collectors.toList()); 9 System.out.println(list2); 10 List<CouponInfo> list3 = couponInfoList.stream().filter(x->x.getMerchantId() != 10001).collect(Collectors.toList()); 11 System.out.println(list3); 12 }
[A, S, D, F, X, C, Y, H] [1, 2, 3, 4, 5, 6] [CouponInfo{id=125, merchantId=10002, couponName='全场9折'}, CouponInfo{id=126, merchantId=10002, couponName='全场8折'}, CouponInfo{id=127, merchantId=10003, couponName='全场7折'}]
2.3、limit
1 /** 2 * limit 3 */ 4 @Test 5 public void testLimit() { 6 List<String> list = strList.stream().limit(3).collect(Collectors.toList()); 7 System.out.println(list); 8 }
[A, S, D]
2.4、sorted
1 /** 2 * 排序 sorted 3 */ 4 @Test 5 public void testSorted() { 6 List<Integer> list = intList.stream().sorted().collect(Collectors.toList()); 7 System.out.println(list); 8 // 倒序 9 List<Integer> list2 = intList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()); 10 System.out.println(list2); 11 12 List<String> list3 = strList.stream().sorted(Comparator.nullsLast(Comparator.naturalOrder())).collect(Collectors.toList()); 13 List<String> list4 = strList.stream().sorted(Comparator.nullsLast(Comparator.reverseOrder())).collect(Collectors.toList()); 14 System.out.println(list3); 15 System.out.println(list4); 16 17 List<CouponInfo> list5 = couponInfoList.stream().sorted(Comparator.comparing(CouponInfo::getId)).collect(Collectors.toList()); 18 List<CouponInfo> list6 = couponInfoList.stream().sorted(Comparator.comparing(CouponInfo::getId).reversed()).collect(Collectors.toList()); 19 List<Long> list51 = list5.stream().map(e->e.getId()).collect(Collectors.toList()); 20 List<Long> list61 = list6.stream().map(e->e.getId()).collect(Collectors.toList()); 21 System.out.println(list51); 22 System.out.println(list61); 23 }
[1, 2, 2, 3, 3, 4, 5, 6, 6] [6, 6, 5, 4, 3, 3, 2, 2, 1] [, A, C, D, F, H, S, X, Y, null] [Y, X, S, H, F, D, C, A, , null] [123, 124, 125, 126, 127] [127, 126, 125, 124, 123]
2.5、map
1 /** 2 * map 3 * 对每个元素进行处理,相当于MapReduce中的map阶段 4 * Collectors.mapping()类似 5 */ 6 @Test 7 public void testMap() { 8 List<Integer> list = intList.stream().map(e->2*e).collect(Collectors.toList()); 9 System.out.println(list); 10 }
[2, 4, 6, 8, 10, 12, 12, 4, 6]
2.6、toMap
1 /** 2 * 转成Map<K,V> 3 * 4 * 特别注意,key不能重复,如果重复的话默认会报错,可以指定key重复的时候怎么处理 5 * 6 * 例如:Map<String, Student> studentIdToStudent = students.stream().collect(toMap(Student::getId, Functions.identity()); 7 */ 8 @Test 9 public void testToMap() { 10 // 因为ID不重复,所以这里这么写没问题;但如果key换成CouponInfo::getMerchantId就有问题了 11 Map<Long, CouponInfo> map = couponInfoList.stream().collect(Collectors.toMap(CouponInfo::getId, Function.identity())); 12 // 这里重复的处理方式就是用后者覆盖前者 13 Map<Integer, CouponInfo> map2 = couponInfoList.stream().collect(Collectors.toMap(CouponInfo::getMerchantId, Function.identity(), (c1, c2)->c2)); 14 Map<Integer, CouponInfo> map3 = couponInfoList.stream().collect(Collectors.toMap(CouponInfo::getMerchantId, Function.identity(), 15 (c1, c2)->{if (c1.getId() > c2.getId()) { 16 return c2; 17 }else { 18 return c1; 19 } 20 })); 21 System.out.println(map); 22 System.out.println(map2); 23 System.out.println(map3); 24 }
{123=CouponInfo{id=123, merchantId=10001, couponName='5元现金券'}, 124=CouponInfo{id=124, merchantId=10001, couponName='10元现金券'}, 125=CouponInfo{id=125, merchantId=10002, couponName='全场9折'}, 126=CouponInfo{id=126, merchantId=10002, couponName='全场8折'}, 127=CouponInfo{id=127, merchantId=10003, couponName='全场7折'}} {10001=CouponInfo{id=124, merchantId=10001, couponName='10元现金券'}, 10002=CouponInfo{id=126, merchantId=10002, couponName='全场8折'}, 10003=CouponInfo{id=127, merchantId=10003, couponName='全场7折'}} {10001=CouponInfo{id=123, merchantId=10001, couponName='5元现金券'}, 10002=CouponInfo{id=125, merchantId=10002, couponName='全场9折'}, 10003=CouponInfo{id=127, merchantId=10003, couponName='全场7折'}}
2.6、groupingBy
1 /** 2 * 分组 groupingBy 3 */ 4 @Test 5 public void testGroupBy() { 6 Map<Integer, List<CouponInfo>> map = couponInfoList.stream().collect(Collectors.groupingBy(CouponInfo::getMerchantId)); 7 Map<Integer, Long> map2 = couponInfoList.stream().collect(Collectors.groupingBy(CouponInfo::getMerchantId, Collectors.counting())); 8 Map<Integer, Set<String>> map3 = couponInfoList.stream().collect(Collectors.groupingBy(CouponInfo::getMerchantId, Collectors.mapping(CouponInfo::getCouponName, Collectors.toSet()))); 9 System.out.println(map); 10 System.out.println(map2); 11 System.out.println(map3); 12 }
{10001=[CouponInfo{id=123, merchantId=10001, couponName='5元现金券'}, CouponInfo{id=124, merchantId=10001, couponName='10元现金券'}], 10002=[CouponInfo{id=125, merchantId=10002, couponName='全场9折'}, CouponInfo{id=126, merchantId=10002, couponName='全场8折'}], 10003=[CouponInfo{id=127, merchantId=10003, couponName='全场7折'}]} {10001=2, 10002=2, 10003=1} {10001=[10元现金券, 5元现金券], 10002=[全场9折, 全场8折], 10003=[全场7折]}
2.7、summary
1 /** 2 * 数值统计 3 */ 4 @Test 5 public void testSum() { 6 IntSummaryStatistics summaryStatistics = intList.stream().mapToInt(x->x).summaryStatistics(); 7 System.out.println(summaryStatistics.getMax()); 8 System.out.println(summaryStatistics.getMin()); 9 System.out.println(summaryStatistics.getAverage()); 10 System.out.println(summaryStatistics.getSum()); 11 }
6 1 3.5555555555555554 32
3、完整代码
1 package com.cjs.boot.demo; 2 3 import com.cjs.boot.domain.entity.CouponInfo; 4 import org.apache.commons.lang3.StringUtils; 5 import org.junit.Before; 6 import org.junit.Test; 7 8 import java.util.*; 9 import java.util.function.Function; 10 import java.util.stream.Collectors; 11 12 public class StreamDemoTest { 13 14 private List<CouponInfo> couponInfoList; 15 16 private List<String> strList; 17 18 private List<Integer> intList; 19 20 @Before 21 public void init() { 22 CouponInfo couponInfo1 = new CouponInfo(123L, 10001, "5元现金券"); 23 CouponInfo couponInfo2 = new CouponInfo(124L, 10001, "10元现金券"); 24 CouponInfo couponInfo3 = new CouponInfo(125L, 10002, "全场9折"); 25 CouponInfo couponInfo4 = new CouponInfo(126L, 10002, "全场8折"); 26 CouponInfo couponInfo5 = new CouponInfo(127L, 10003, "全场7折"); 27 28 couponInfoList = new ArrayList<>(); 29 couponInfoList.add(couponInfo1); 30 couponInfoList.add(couponInfo2); 31 couponInfoList.add(couponInfo3); 32 couponInfoList.add(couponInfo4); 33 couponInfoList.add(couponInfo5); 34 35 couponInfoList = new ArrayList<>(); 36 couponInfoList.add(couponInfo1); 37 couponInfoList.add(couponInfo2); 38 couponInfoList.add(couponInfo3); 39 couponInfoList.add(couponInfo4); 40 couponInfoList.add(couponInfo5); 41 42 strList = Arrays.asList(new String[]{"A", "S", "D", "F", "X", "C", "Y", "H", "", null}); 43 44 intList = Arrays.asList(new Integer[]{1, 2, 3, 4, 5, 6, 6, 2, 3}); 45 } 46 47 /** 48 * 迭代 forEach 49 */ 50 @Test 51 public void testForEach() { 52 strList.stream().forEach(System.out::println); 53 strList.stream().forEach(e->System.out.print(e)); 54 System.out.println(); 55 strList.forEach(System.out::print); 56 } 57 58 /** 59 * 过滤 filter 60 */ 61 @Test 62 public void testFilter() { 63 List<String> list = strList.stream().filter(x-> StringUtils.isNotBlank(x)).collect(Collectors.toList()); 64 System.out.println(list); 65 List<Integer> list2 = intList.stream().distinct().collect(Collectors.toList()); 66 System.out.println(list2); 67 List<CouponInfo> list3 = couponInfoList.stream().filter(x->x.getMerchantId() != 10001).collect(Collectors.toList()); 68 System.out.println(list3); 69 } 70 71 /** 72 * limit 73 */ 74 @Test 75 public void testLimit() { 76 List<String> list = strList.stream().limit(3).collect(Collectors.toList()); 77 System.out.println(list); 78 } 79 80 /** 81 * 排序 sorted 82 */ 83 @Test 84 public void testSorted() { 85 List<Integer> list = intList.stream().sorted().collect(Collectors.toList()); 86 System.out.println(list); 87 // 倒序 88 List<Integer> list2 = intList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()); 89 System.out.println(list2); 90 91 List<String> list3 = strList.stream().sorted(Comparator.nullsLast(Comparator.naturalOrder())).collect(Collectors.toList()); 92 List<String> list4 = strList.stream().sorted(Comparator.nullsLast(Comparator.reverseOrder())).collect(Collectors.toList()); 93 System.out.println(list3); 94 System.out.println(list4); 95 96 List<CouponInfo> list5 = couponInfoList.stream().sorted(Comparator.comparing(CouponInfo::getId)).collect(Collectors.toList()); 97 List<CouponInfo> list6 = couponInfoList.stream().sorted(Comparator.comparing(CouponInfo::getId).reversed()).collect(Collectors.toList()); 98 List<Long> list51 = list5.stream().map(e->e.getId()).collect(Collectors.toList()); 99 List<Long> list61 = list6.stream().map(e->e.getId()).collect(Collectors.toList()); 100 System.out.println(list51); 101 System.out.println(list61); 102 } 103 104 /** 105 * map 106 * 对每个元素进行处理,相当于MapReduce中的map阶段 107 * Collectors.mapping()类似 108 */ 109 @Test 110 public void testMap() { 111 List<Integer> list = intList.stream().map(e->2*e).collect(Collectors.toList()); 112 System.out.println(list); 113 } 114 115 /** 116 * 转成Map<K,V> 117 * 118 * 特别注意,key不能重复,如果重复的话默认会报错,可以指定key重复的时候怎么处理 119 * 120 * 例如:Map<String, Student> studentIdToStudent = students.stream().collect(toMap(Student::getId, Functions.identity()); 121 */ 122 @Test 123 public void testToMap() { 124 // 因为ID不重复,所以这里这么写没问题;但如果key换成CouponInfo::getMerchantId就有问题了 125 Map<Long, CouponInfo> map = couponInfoList.stream().collect(Collectors.toMap(CouponInfo::getId, Function.identity())); 126 // 这里重复的处理方式就是用后者覆盖前者 127 Map<Integer, CouponInfo> map2 = couponInfoList.stream().collect(Collectors.toMap(CouponInfo::getMerchantId, Function.identity(), (c1, c2)->c2)); 128 Map<Integer, CouponInfo> map3 = couponInfoList.stream().collect(Collectors.toMap(CouponInfo::getMerchantId, Function.identity(), 129 (c1, c2)->{if (c1.getId() > c2.getId()) { 130 return c2; 131 }else { 132 return c1; 133 } 134 })); 135 System.out.println(map); 136 System.out.println(map2); 137 System.out.println(map3); 138 } 139 140 /** 141 * 分组 groupingBy 142 */ 143 @Test 144 public void testGroupBy() { 145 Map<Integer, List<CouponInfo>> map = couponInfoList.stream().collect(Collectors.groupingBy(CouponInfo::getMerchantId)); 146 Map<Integer, Long> map2 = couponInfoList.stream().collect(Collectors.groupingBy(CouponInfo::getMerchantId, Collectors.counting())); 147 Map<Integer, Set<String>> map3 = couponInfoList.stream().collect(Collectors.groupingBy(CouponInfo::getMerchantId, Collectors.mapping(CouponInfo::getCouponName, Collectors.toSet()))); 148 System.out.println(map); 149 System.out.println(map2); 150 System.out.println(map3); 151 } 152 153 /** 154 * 数值统计 155 */ 156 @Test 157 public void testSum() { 158 IntSummaryStatistics summaryStatistics = intList.stream().mapToInt(x->x).summaryStatistics(); 159 System.out.println(summaryStatistics.getMax()); 160 System.out.println(summaryStatistics.getMin()); 161 System.out.println(summaryStatistics.getAverage()); 162 System.out.println(summaryStatistics.getSum()); 163 } 164 165 }
参考
http://ifeve.com/java-8-tutorial-2/
https://www.cnblogs.com/justcooooode/p/7701260.html