Stream的使用
1 package com.javanew; 2 3 import com.javanew.model.Department; 4 import com.javanew.model.Users; 5 6 import java.util.*; 7 import java.util.stream.Collectors; 8 9 /** 10 * Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。 11 * <p> 12 * Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。 13 * <p> 14 * Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。 15 * <p> 16 * 这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。 17 */ 18 public class StreamTest { 19 20 public static void main(String[] args) { 21 System.out.println("==========生成流==============="); 22 /** 23 * 生成流 24 * 在 Java 8 中, 集合接口有两个方法来生成流: 25 * 26 * stream() − 为集合创建串行流。 27 * 28 * parallelStream() − 为集合创建并行流。 29 */ 30 List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl"); 31 strings.forEach(s -> System.out.println(s)); 32 List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); 33 filtered.forEach(s -> System.out.println(s)); 34 35 System.out.println("============forEach============="); 36 37 /** 38 * forEach 39 * Stream 提供了新的方法 'forEach' 来迭代流中的每个数据。以下代码片段使用 forEach 输出了10个随机数: 40 */ 41 Random random = new Random(); 42 random.ints().limit(10).forEach(System.out::println); 43 44 System.out.println("============map============="); 45 46 /** 47 * map 48 * map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数: 49 */ 50 List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); 51 // 获取对应的平方数 52 List<Integer> collect = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList()); 53 collect.forEach(integer -> System.out.println(integer)); 54 55 System.out.println("============filter============="); 56 57 /** 58 * filter 59 * filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤出空字符串: 60 */ 61 List<String> strings1 = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl"); 62 // 获取空字符串的数量 63 long count = strings1.stream().filter(s -> s.isEmpty()).count(); 64 System.out.println("空字符串的数量" + count); 65 66 System.out.println("============limit============="); 67 68 /** 69 * limit 70 * limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据: 71 */ 72 Random random1 = new Random(); 73 random1.ints().limit(10).forEach(System.out::println); 74 75 System.out.println("============sorted============="); 76 77 /** 78 * sorted 79 * sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序: 80 */ 81 Random random2 = new Random(); 82 random2.ints().limit(10).sorted().forEach(System.out::println); 83 84 System.out.println("============并行(parallel)程序============="); 85 /** 86 * 并行(parallel)程序 87 * parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量: 88 */ 89 List<String> strings2 = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl"); 90 // 获取空字符串的数量 91 Long count2 = strings.parallelStream().filter(string -> string.isEmpty()).count(); 92 System.out.println("并行(parallel)程序空字符串的数量" + count2); 93 94 System.out.println("============Collectors============="); 95 /** 96 * Collectors 97 * Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串: 98 */ 99 List<String> strings3 = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl"); 100 List<String> filtered1 = strings3.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList()); 101 System.out.println("筛选列表: " + filtered1); 102 103 String mergedString = strings3.stream().filter(s -> !s.isEmpty()).collect(Collectors.joining(",")); 104 System.out.println("合并字符串: " + mergedString); 105 106 System.out.println("============统计============="); 107 108 /** 109 * 统计 110 * 另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。 111 */ 112 List<Integer> numbers2 = Arrays.asList(3, 2, 2, 3, 7, 3, 5); 113 IntSummaryStatistics stats = numbers2.stream().mapToInt((x) -> x).summaryStatistics(); 114 System.out.println("列表中最大的数 : " + stats.getMax()); 115 System.out.println("列表中最小的数 : " + stats.getMin()); 116 System.out.println("所有数之和 : " + stats.getSum()); 117 System.out.println("平均数 : " + stats.getAverage()); 118 119 List<Users> list = new ArrayList<>(); 120 Department department = new Department(); 121 department.setDeptName("开发部"); 122 department.setDeptNo(001); 123 124 125 Users users1 = new Users(); 126 users1.setName("aaa"); 127 users1.setMoney(100); 128 users1.setDepartment(Arrays.asList(department)); 129 Users users2 = new Users(); 130 users2.setName("bbb"); 131 users2.setMoney(300); 132 users2.setDepartment(Arrays.asList(department)); 133 list.add(users1); 134 list.add(users2); 135 136 List<Integer> collect1 = list.stream().map(users -> users.getMoney()).collect(Collectors.toList()); 137 List<Integer> collect2 = list.stream().map(Users::getMoney).collect(Collectors.toList()); 138 139 //Users对象名字的集合 140 List<String> names = list.stream().map(users -> users.getName()).collect(Collectors.toList()); 141 142 //Users对象money的求和 143 int sum = list.stream().mapToInt(Users::getMoney).sum(); 144 145 //获取List对象中money最多的一个人 146 Users users3 = list.stream().max(Comparator.comparing(users -> users.getMoney())).get(); 147 148 //获取List对象中money最少的一个人 149 Users users4 = list.stream().min(Comparator.comparing(users -> users.getMoney())).get(); 150 151 //获取名字为xxx的user 152 List<Users> collect3 = list.stream().filter(users -> "xxx".equals(users.getName())).collect(Collectors.toList()); 153 154 //List集合去重 155 List<Users> collect4 = list.stream().distinct().collect(Collectors.toList()); 156 157 //List按照money从小到大排序(顺序) 158 List<Users> collect5 = list.stream().sorted(Comparator.comparing(Users::getMoney)).collect(Collectors.toList()); 159 160 //List按照money从大到小排序(倒序) 161 List<Users> collect6 = list.stream().sorted(Comparator.comparing(Users::getMoney).reversed()).collect(Collectors.toList()); 162 163 //List集合按照名字进行分组 164 Map<String, List<Users>> collect7 = list.stream().collect(Collectors.groupingBy(Users::getName)); 165 166 //获取List集合user对象的所有部门编号 167 List<Integer> deptNos = new ArrayList<>(); 168 list.stream().forEach(users -> deptNos.addAll(users.getDepartment().stream().map(Department::getDeptNo).distinct().collect(Collectors.toList()))); 169 170 //判断list集合中所有user的money是否都是100,是就返回true,否则返回false 171 boolean allMatch1 = list.stream().allMatch(users -> users.getMoney() == 100); 172 173 //判断list集合中所有user名字为aaa的所有user的money是否都是100,是就返回true,否则返回false 174 boolean allMatch = list.stream().filter(users -> users.getName().equals("aaa")).allMatch(users -> users.getMoney() == 100); 175 176 //在list集合数量大时才有并行流处理parallelStream 177 /** 178 * stream or parallelStream? 179 * 1. 是否需要并行? 180 * 2. 任务之间是否是独立的?是否会引起任何竞态条件? 181 * 3. 结果是否取决于任务的调用顺序? 182 */ 183 boolean allMatch2 = list.parallelStream().filter(users -> users.getName().equals("aaa")).allMatch(users -> users.getMoney() == 100); 184 185 System.out.println("allMatch1->:" + allMatch1); 186 System.out.println("allMatch->" + allMatch); 187 188 System.out.println("collect1输出"); 189 collect1.forEach(System.out::println); 190 System.out.println("collect2输出"); 191 collect2.forEach(i -> System.out.println(i)); 192 193 LongSummaryStatistics statistics = collect1.stream().mapToLong((x) -> x).summaryStatistics(); 194 System.out.println("列表中最大的数 : " + statistics.getMax()); 195 System.out.println("列表中最小的数 : " + statistics.getMin()); 196 System.out.println("所有数之和 : " + statistics.getSum()); 197 System.out.println("平均数 : " + statistics.getAverage()); 198 199 200 } 201 202 }