测试 Collectors 类中相关 API,以及 Collector 接口中 Characteristics 的枚举值

  1     public static void main(String [] args) {
  2         //Stream API
  3         List<String> arrList1 = Arrays.asList("predicate1", "collect1", "map1", "flatmap1", "reduce1", "collect1");
  4         List<String> arrList2 = Arrays.asList("predicate2", "collect2", "map2", "flatmap2", "reduce2", "collect2");
  5         List<List<String>> arrAll = Arrays.asList(arrList1, arrList2);
  6         System.out.println(arrList1.stream().filter(i -> i.length() > 5).collect(Collectors.toList()));
  7         System.out.println(arrList1.stream().map(i -> i.toUpperCase()).collect(Collectors.toList()));
  8         //flatmap 将流中数据扁平化处理,其中参数二是一个 Stream 对象。本例中将所有字符数组扁平化到一个流中
  9         arrList1.stream().map(i -> i).flatMap(i -> Stream.of(i.toCharArray())).forEach(i -> System.out.println(Arrays.toString(i)));
 10         //flatmap 将流中数据扁平化处理,其中参数二是一个 Stream 对象。本例针对的是 List<List<String>> 结构数据,将多个 List 中的数据扁平化到一个流中
 11         System.out.println(arrAll.stream().flatMap(i -> i.stream()).collect(Collectors.toList()));
 12         //流元素去重
 13         System.out.println(arrList1.stream().distinct().collect(Collectors.toList()));
 14         //流元素排序
 15         System.out.println(arrList1.stream().sorted(String::compareTo).collect(Collectors.toList()));
 16         //peek 不影响最终 collect 操作。类似数据预览效果
 17         System.out.println(arrList1.stream().peek(i -> {
 18             i += "suffix";
 19             System.out.println(i);
 20         }).collect(Collectors.toList()));
 21         //类似数据库分页查询操作
 22         System.out.println(arrList1.stream().skip(1).limit(3).collect(Collectors.toList()));
 23         //遍历消费流中元素
 24         arrList1.stream().forEach(System.out::println);
 25         //流转数组
 26         Object[] objects = arrList1.stream().toArray();
 27         //通过 i,可以显示的创建一个大小固定的数组
 28         Object[] strings = arrList1.stream().toArray(i -> {
 29             System.out.println("i = " + i);
 30             return new Object[i];
 31         });
 32         System.out.println(Arrays.toString(strings));
 33         //精简写法,并且可以免去泛型强转的问题
 34         String[] strings1 = arrList1.stream().toArray(String[]::new);
 35         System.out.println(Arrays.toString(strings1));
 36         //reduce,汇聚操作,对流中的每个元素按一定规则计算,最终输出一个值,内置的汇聚操作有求和、求平均值、最大值等
 37         arrList1.stream().reduce((a, b) -> a.concat(b)).ifPresent(i -> System.out.println(i));
 38         System.out.println(arrList1.stream().reduce("prefix", (a, b) -> a.concat(b)));
 39         //reduce 的重载形式,计算流中字符的总个数,参数一是一个初始值
 40         System.out.println(arrList1.stream().reduce(0, (a, b) -> a += b.length(), (a, b) ->  a+= b));
 41         //求最大值和最小值,本质上使用的就是 reduce
 42         arrList1.stream().min((a, b) -> a.length() - b.length()).ifPresent(i -> System.out.println(i));
 43         arrList1.stream().max((a, b) -> a.length() - b.length()).ifPresent(i -> System.out.println(i));
 44         //求个数(可以使用 peek 配合 reduce,可以同时得出多个汇聚后的值,而不是一个)
 45         System.out.println(arrList1.stream().count());
 46         //任意匹配返回 true
 47         System.out.println(arrList1.stream().anyMatch(i -> "map1".equals(i)));
 48         //全部匹配返回 true
 49         System.out.println(arrList1.stream().allMatch(i -> i.length() > 0));
 50         //全部都不匹配返回 true
 51         System.out.println(arrList1.stream().noneMatch(i -> i.length() < 0));
 52         //找出流中第一个元素
 53         arrList1.stream().findFirst().ifPresent(i -> System.out.println(i));
 54         //找出流中任意一个元素
 55         arrList1.stream().findAny().ifPresent(i -> System.out.println(i));
 56     }
 57 
 58 
 59     public static void main1(String[] args) {
 60 
 61 
 62         //Collectors API
 63         StringBuilder builder = Stream.of("supplier", "consumer", "producer")
 64                 .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
 65         System.out.println(builder);
 66         int[] intArr = Arrays.asList(1, 2, 3, 4, 5).stream()
 67                 .collect(() -> new int[1], (a, b) -> a[0] += b, (a, b) -> a[0] += b[0]);
 68         System.out.println(Arrays.toString(intArr));
 69         Collectors collectors;
 70         Stream.<String>of().collect(Collectors.<String>toList());
 71         StringJoiner joiner = new StringJoiner(";", "pre", "suf");
 72         joiner.add("supplier").add("consumer").add("producer");
 73         System.out.println("merge : " + joiner.toString());
 74         List<String> list = Arrays.asList("supplier", "consumer", "producer");
 75         //在应用一个下游收集器之前,对流中的元素做一次 map 转换
 76         System.out.println(list.stream().collect(Collectors.mapping(String::toUpperCase, Collectors.toList())));
 77         //先应用了一个下游收集器,然后对下游收集器的结果应用一个 Function 进行转换。理解 Charactristic 的几个枚举值
 78         String collect = list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), r -> StringUtils.join(r, ";")));
 79         System.out.println(collect);
 80         List<Integer> nums = Arrays.asList(1, 3, 5, 7, 9, 11);
 81         System.out.println("couting1 : " + nums.stream().collect(Collectors.counting()));
 82         Integer collect1 = nums.stream().parallel().collect(new Collector<Integer, int[], Integer>() {
 83             @Override
 84             public Supplier supplier() { return () -> new int[1]; }
 85 
 86             @Override
 87             public BiConsumer<int [], Integer> accumulator() { return (a, b) -> a[0] = 1; }
 88 
 89             @Override
 90             public BinaryOperator<int []> combiner() {
 91                 return (a, b) -> {
 92                     System.out.println("a = " + a + " , b = " + b);
 93                     System.out.println(Thread.currentThread().getName() + ":" + a[0] + ":" + b[0]);
 94                     a[0] = a[0] + b[0];
 95                     return a;
 96                 };
 97             }
 98             @Override
 99             public Function<int [], Integer> finisher() { return (a) -> a[0];}
100 
101             @Override
102             public Set<Characteristics> characteristics() { return Collections.emptySet();}
103         });
104         System.out.println("couting2 : " + collect1);
105         //其实本质上也是 reduce 的调用,也符合下面的规则,流中元素 -> 输出为一个值
106         nums.stream().collect(Collectors.minBy((a, b) -> a - b)).ifPresent(System.out::println);
107         nums.stream().collect(Collectors.maxBy((a, b) -> a - b)).ifPresent(System.out::println);
108         System.out.println(nums.stream().collect(Collectors.summingInt(a -> a * 2)));
109         //reduce 函数的作用是将流中的多个元素,按照某种规则,输出为一个值。比如统计 Count、求和、元素转 String 等
110         System.out.println(nums.stream().collect(Collectors.<Integer, String>reducing("", a -> "{" + a + "}", (a, b) -> a + b)));
111         Map<String, Object> m1 = new HashMap<>();
112         m1.put("a", 123);
113         m1.put("b", 456);
114         m1.put("c", 789);
115         //HashMap 中的这个方法,将新值和旧值合并;旧值就是通过 get("a") 获取,新值就是 111。合并规则由 BinaryOperator 指定
116         m1.merge("d", 111, (a, b) -> a + "-" + b);
117         System.out.println(m1);
118         m1.replaceAll((k, v) -> k + '-' + v);
119         System.out.println("after replace All : " + m1);
120         for(Map.Entry<String, Object> entry : m1.entrySet()) {
121             m1.merge(entry.getKey(), "111", (a, b) -> a + "-" + b);
122         }
123         System.out.println(m1);
124         List<String> list1 = Arrays.asList("aaSupplier11", "ccComsumer12", "ccProducer13", "ccEntry14", "aaMap15", "ccProducer16");
125         Map<String, List<String>> result1 = list1.stream().collect(Collectors.groupingBy(a -> a.startsWith("aa") ? "aa" : "bb"));
126         System.out.println(result1);
127         Map<String, List<String>> result2 = list1.stream().collect(
128                 Collectors.<String, String, List<String>, List<String>>groupingBy(
129                 a -> a.startsWith("aa") ? "aa" : "cc", (Collector<? super String, List<String>, List<String>>) Collectors.<String>toList()));
130         System.out.println(result2);
131         //最底层的 groupBy,需要提供的有:键的分类器、保存结果的 Map 容器、容器中值对应的类型(一般是 List)
132         Map<String, Set<String>> result3 = list1.stream().collect(Collectors.<String, String, Set<String>, Set<String>, Map<String, Set<String>>>groupingBy(
133                 a -> a.startsWith("aa") ? "aa" : "ee",
134                 () -> new HashMap<String, Set<String>>()
135                 , (Collector<? super String, Set<String>, Set<String>>) Collectors.<String>toSet()));
136         System.out.println(result3);
137 
138         //分区,里面有一个对象 Partition,Partition 本质上是一个 Map,并且它的 Key 是 Boolean 类型,该 Map 中仅有两个元素。值是泛型 T,可以是任意类型
139         Map<Boolean, List<String>> result = list1.stream().collect(Collectors.partitioningBy(i -> i.startsWith("cc"), Collectors.toList()));
140         System.out.println(result);
141 
142         //toMap,将流中每个元素按照指定规则,转为 map,但要确保流中的元素不会有重复,否则异常
143         Map<String, Integer> result4 = list1.stream().collect(Collectors.toMap(i -> i.toUpperCase(), i -> i.length()));
144         System.out.println(result4);
145 
146         List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9);
147         //这个例子也演示了如何通过自定义类的方式来制作一个容器
148         IntSummaryStatistics collect2 = intList.parallelStream().collect(Collectors.summarizingInt(i -> i));
149         System.out.println(collect2);
150 
151         List<String> list0 = new ArrayList<>();
152         List<String> list2 = Arrays.asList("aaSupplier21", "ccComsumer22", "ccProducer23", "ccEntry24", "aaMap25", "ccProducer26");
153         List<String> list3 = Arrays.asList("aaSupplier31", "ccComsumer32", "ccProducer33", "ccEntry34", "aaMap35", "ccProducer36");
154         list0.addAll(list1);
155         list0.addAll(list2);
156         list0.addAll(list3);
157         System.out.println("-------------");
158         Thread.currentThread().setName("ForkJoinPool.commonPool-worker-M");
159         //三个枚举值的使用
160         for(int i = 0; i < 1; i++) {
161             List<String> collect3 = list0.parallelStream().collect(new Collector<String, List<String>, List<String>>() {
162                 @Override
163                 public Supplier<List<String>> supplier() {
164                     return () -> {
165                         System.out.println("do supplier " + Thread.currentThread().getName());
166                         return new ArrayList<>();
167                     };
168                 }
169 
170                 @Override
171                 public BiConsumer<List<String>, String> accumulator() {
172                     return (a, b) -> {
173                         a.add(b);
174                         //在获取并行流的情况下,如果多线程处理的是一个结果容器,这里不能遍历读取容器中的内容,否则很有可能抛出异常 ConcurrentModificationException
175                         //在获取并行流的情况下,除上述情况外,不会有异常出现
176                         //System.out.println("do accumulator " + Thread.currentThread().getName() + " " + a);
177                     };
178                 }
179 
180                 @Override
181                 public BinaryOperator<List<String>> combiner() {
182                     return (a, b) -> {
183                         a.addAll(b);
184                         System.out.println("do combiner " + Thread.currentThread().getName() + " " + a);
185                         return a;
186                     };
187                 }
188 
189                 @Override
190                 public Function<List<String>, List<String>> finisher() {
191                     return a -> {
192                         System.out.println("do finisher " + Thread.currentThread().getName());
193                         return a;
194                     };
195                 }
196 
197                 @Override
198                 public Set<Characteristics> characteristics() {
199                     System.out.println("do characteristics " + Thread.currentThread().getName());
200                     //在获取了并行流的前提下,当且仅当同时设置了 UNORDERED 和 CONCURRENT 时,combiner 才不会执行,这是因为多线程中,多线程操作的是同一个结果容器
201                     //在获取了并行流的情况下,除上述情况外,其他情况都会执行 combiner,这是因为多线程中,每个线程处理一个结果容器,最后会将多个结果容器汇总起来
202                     return Collections.unmodifiableSet(EnumSet.of(Characteristics.CONCURRENT, Characteristics.UNORDERED));
203                     //return Collections.emptySet();
204                 }
205             });
206             System.out.println(collect3);
207         }
208     }

 

posted @ 2020-11-24 14:48  zhangjieatbky  阅读(155)  评论(0编辑  收藏  举报