- 各种数据结构转流
- 高级收集器,返回各种数据类型
- 流的拼接
- 排序
- 分区与分组
- 归约
- 其他
1 package stream; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.Collection; 6 import java.util.Comparator; 7 import java.util.HashMap; 8 import java.util.HashSet; 9 import java.util.IdentityHashMap; 10 import java.util.Iterator; 11 import java.util.LinkedHashMap; 12 import java.util.List; 13 import java.util.Map; 14 import java.util.Map.Entry; 15 import java.util.Random; 16 import java.util.Set; 17 import java.util.StringJoiner; 18 import java.util.function.Function; 19 import java.util.stream.Collectors; 20 import java.util.stream.IntStream; 21 import java.util.stream.Stream; 22 import java.util.stream.StreamSupport; 23 24 public class Test10 { 25 26 static Listnumbers = Arrays.asList(1, 5, 3, 2, 4); 27 28 static List strs = Arrays.asList("b2", "b1", "a2", "c", "b", "a"); 29 30 static List > strsList = Arrays.asList(strs); 31 32 static Person p1 = new Person(GenderEnum.MALE, 20, "Jack"); 33 static Person p2 = new Person(GenderEnum.FEMALE, 20, "Lily"); 34 static Person p3 = new Person(GenderEnum.MALE, 10, "John"); 35 static Person p4 = new Person(GenderEnum.FEMALE, 10, "Lucy"); 36 static Person p5 = new Person(GenderEnum.MALE, 20, "Eason"); 37 38 static List
persons = Arrays.asList(p1, p2, p3, p4, p5); 39 40 static void method1() { 41 // 常用数据结构转流的方式 42 43 // Collection接口 提供了stream()方法 44 45 // 1. List转流 46 List list = new ArrayList<>(); 47 Stream streamA = list.stream(); 48 49 // ------------------------------------------------------------ 50 51 // 2. Set转流 52 Set set = new HashSet<>(); 53 Stream streamB = set.stream(); 54 55 // ------------------------------------------------------------ 56 57 // 3. Map转流 58 Map map = new HashMap<>(); 59 Stream > streamC = map.entrySet().stream(); 60 Stream streamD = map.values().stream(); 61 62 // ------------------------------------------------------------ 63 64 // 4. 数组转流 65 String[] arr = { "A", "B", "C" }; 66 Arrays.stream(arr); 67 68 // ------------------------------------------------------------ 69 70 // 5. Iterable转流 71 Iterable iterable = new ArrayList<>(); 72 StreamSupport.stream(iterable.spliterator(), false); 73 } 74 75 static void method2() { 76 // 流的拼接 77 78 List listA = Arrays.asList("s1", "s2", "s3"); 79 List listB = Arrays.asList("t1", "t2", "t3"); 80 81 // Stream.concat()实现多个流拼接 82 Stream streamA = Stream.concat(listA.stream(), listB.stream()); 83 84 // Stream.of()实现拼接 85 // 多个元素 86 Stream streamB = Stream.of("A", "B", "C"); 87 // 多个List 88 Stream streamC = Stream.of(listA, listB).flatMap(Collection::stream); 89 // 多个Stream 90 Stream streamD = Stream.of(listA.stream(), listB.stream()).flatMap(Function.identity()); 91 92 // flatMap实现子元素拼接 93 List - items = new ArrayList<>(); 94 Stream
streamE = items.stream().flatMap(i -> i.getSubItems().stream()); 95 } 96 97 static void method3() { 98 // 高级收集器 99 100 // 1. 字符串拼接 101 102 List strs = Arrays.asList("s1", "s2", "s3"); 103 104 // 无分隔符 105 String str1 = strs.stream().collect(Collectors.joining()); 106 // 单个分隔符 107 String str2 = strs.stream().collect(Collectors.joining(",")); 108 // 前后缀及分隔符 109 String str3 = strs.stream().collect(Collectors.joining(",", "[", "]")); 110 111 // ---------------------------------------------------------------------------------------------------- 112 113 // 返回集合 114 115 // 2. 返回数组 116 117 // Object数据(无参默认) 118 Object[] arr1 = strs.stream().toArray(); 119 // 特定类型数据 120 String[] arr2 = strs.stream().toArray(String[]::new); 121 // 数组指定长度 122 String ids = "1, 2, 3, 4"; 123 String[] arr3 = Arrays.asList(ids.split(",")).stream().map(String::trim).toArray(size -> new String[size]); 124 125 // ---------------------------------------------------------------------------------------------------- 126 127 // 3. 返回List 128 // 默认List 129 List list1 = strs.stream().filter(str -> str.length() > 5).map(String::toUpperCase).collect(Collectors.toList()); 130 // 返回特定类型如ArrayList 131 List list2 = strs.stream().filter(str -> str.length() > 5).map(String::toUpperCase).collect(Collectors.toCollection(ArrayList::new)); 132 133 // ---------------------------------------------------------------------------------------------------- 134 135 // 4. 返回Map 136 137 // List转Map 138 List - items = Arrays.asList(new Item("0001", "name"), new Item("0002", "name2")); 139 // 成员作为value 140 Map
map1 = items.stream().collect(Collectors.toMap(Item::getItemId, Item::getName)); 141 // 元素作为value 142 Map map2 = items.stream().collect(Collectors.toMap(Item::getItemId, Function.identity())); 143 // value重复取第一个 144 Map map3 = items.stream().collect(Collectors.toMap(Item::getItemId, Function.identity(), (n1, n2) -> n1)); 145 // value重复自定义异常,指定返回类型 146 Map map4 = items.stream() 147 .collect(Collectors.toMap(Item::getItemId, Function.identity(), (a, b) -> { 148 throw new IllegalStateException("cannot add duplicate key: " + a); 149 }, IdentityHashMap::new)); 150 151 // Map转Map 152 Map map = new HashMap<>(); 153 Map map_ = map.entrySet().stream().filter(e -> e.getValue() > 10).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 154 } 155 156 static void method4() { 157 // 排序 sorted 158 159 // 数字排序 160 161 List numbers = Arrays.asList(1, 5, 3, 2, 4); 162 163 // 1. 升序(默认) 164 numbers.stream().sorted(); 165 // 1, 2, 3, 4, 5 166 167 // 2. 降序 168 numbers.stream().sorted(Comparator.reverseOrder()); 169 // 5, 4, 3, 2, 1 170 171 // -------------------------------------------------------------------------------- 172 173 // 字符排序 174 175 List strs = Arrays.asList("b2", "b1", "a2", "c", "b", "a"); 176 177 // 1. 默认 178 List strSorted1 = strs.stream().sorted().collect(Collectors.toList()); 179 // a, a2, b, b1, b2, c 180 181 // 2. 自定义:先比较长度 182 strs.stream().sorted((s1, s2) -> s1.length() - s2.length()); 183 List strSorted2 = strs.stream() 184 .sorted(Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder())) 185 .collect(Collectors.toList()); 186 // a, b, c, a2, b1, b2 187 188 // -------------------------------------------------------------------------------- 189 190 // 自定义类型排序 191 192 193 // 1. 可实现Comparable 接口 194 ListpVal = persons.stream().sorted().collect(Collectors.toList()); 195 /* 196 * Person [gender=MALE, age=10, name=John] 197 * Person [gender=MALE, age=20, name=Eason] 198 * Person [gender=MALE, age=20, name=Jack] 199 * Person [gender=FEMALE, age=10, name=Lucy] 200 * Person [gender=FEMALE, age=20, name=Lily] 201 * 202 */ 203 204 // List可直接排序,传入compareTo方法引用 205 List personsNew = new ArrayList<>(persons); 206 personsNew.sort(Person::compareTo); 207 208 // 2. 使用比较器链,排序方式更灵活 209 persons.sort(Comparator.comparing(Person::getAge).thenComparing(Person::getGender).thenComparing(Person::getName)); 210 /* 211 * Person [gender=MALE, age=10, name=John] 212 * Person [gender=FEMALE, age=10, name=Lucy] 213 * Person [gender=MALE, age=20, name=Eason] 214 * Person [gender=MALE, age=20, name=Jack] 215 * Person [gender=FEMALE, age=20, name=Lily] 216 * 217 */ 218 } 219 220 static void method5() { 221 // 分组与分区 222 223 // 分组 224 Map > grouped1 = persons.stream().collect(Collectors.groupingBy(Person::getGender)); 225 // 子分组,多个分组 226 Map >> grouped2 = persons.stream() 227 .collect(Collectors.groupingBy(Person::getGender, LinkedHashMap::new, 228 Collectors.groupingBy(Person::getAge, LinkedHashMap::new, Collectors.toList()))); 229 230 // -------------------------------------------------------------------------------- 231 232 // 分区 233 Map > partitioned1 = persons.stream().collect(Collectors.partitioningBy(person -> person.getAge() <= 6)); 234 // 分区并计数 235 Map partitioned2 = persons.stream().collect(Collectors.partitioningBy(person -> person.getAge() <= 6, Collectors.counting())); 236 } 237 238 static void method6() { 239 // 归约 reduce 240 241 // 数字 242 Integer reduced1 = numbers.stream().reduce((x, y) -> x + y).get(); 243 // 数字,指定初始值 244 Integer reduced2 = numbers.stream().reduce(0, (x, y) -> x + y); 245 246 // 字符串拼接 247 String reduced3 = strs.stream().reduce((s1, s2) -> s1 + s2).get(); 248 // 字符串拼接,指定前缀 249 String reduced4 = strs.stream().reduce("prefix", (s1, s2) -> s1 + s2); 250 251 // -------------------------------------------------------------------------------- 252 253 // 数字,求最小值 254 Integer min = numbers.stream().reduce(Math::min).get(); 255 // 数字,求最大值 256 Integer max = numbers.stream().reduce(Math::max).get(); 257 // 数字,求和 258 Integer sum = numbers.stream().reduce(Integer::sum).get(); 259 260 // -------------------------------------------------------------------------------- 261 262 // 实现流的拼接 263 Stream reduced5 = strsList.stream().map(list -> list.stream()).reduce(Stream::concat).get(); 264 265 Iterable [] inputs = null; 266 Iterator iterator = Stream.of(inputs).map(it -> StreamSupport.stream(it.spliterator(), false)).reduce(Stream::concat).orElseGet(Stream::empty).iterator(); 267 268 } 269 270 static void method7() { 271 // findFirst 返回第一个符合条件 272 strs.stream().filter(str -> str.length() > 10).findFirst().get(); 273 // findAny 返回任意一个符合条件,串行流和findFirst相同,并行流返回最先有值的线程 274 strs.stream().filter(str -> str.length() > 10).findAny().get(); 275 // anyMatch 任意符合 276 boolean flag1 = strs.stream().anyMatch(str -> str.length() > 10); 277 // allMatch 全部符合 278 boolean flag2 = strs.stream().allMatch(str -> str.length() > 10); 279 // noneMatch 全不符合 280 boolean flag3 = strs.stream().noneMatch(str -> str.length() > 10); 281 282 // -------------------------------------------------------------------------------- 283 284 // distinct 去重 285 strs.stream().distinct(); 286 // count 计数 287 strs.stream().filter(str -> str.length() > 10).count(); 288 // skip 跳过 289 strs.stream().filter(str -> str.length() > 10).skip(3); 290 // limit 限定数量 291 strs.stream().filter(str -> str.length() > 10).limit(3); 292 293 // -------------------------------------------------------------------------------- 294 295 // 遍历 296 strs.stream().forEach(System.out::println); 297 298 } 299 300 static void method8() { 301 // IntStream 302 303 // 使用IntStream生成50个连续字符 304 305 IntStream.range(0, 50).mapToObj(s -> "*").collect(Collectors.joining()); 306 IntStream.range(0, 50).mapToObj(s -> "*").collect(Collectors.joining("")); 307 IntStream.rangeClosed(1, 50).mapToObj(s -> "*").reduce((s1, s2) -> s1 + s2).get(); 308 IntStream.rangeClosed(1, 50).mapToObj(s -> "*").reduce(new StringJoiner("", "[", "]"), StringJoiner::add, StringJoiner::merge); 309 310 // 生成随机数 311 Random random = new Random(); 312 IntStream.generate(random::nextInt); 313 314 // 生成特定元素 315 IntStream.iterate(1, i -> i * 2); 316 } 317 318 static class Person implements Comparable { 319 private GenderEnum gender; 320 private int age; 321 private String name; 322 323 public Person(GenderEnum gender, int age, String name) { 324 this.gender = gender; 325 this.age = age; 326 this.name = name; 327 } 328 329 public GenderEnum getGender() { 330 return gender; 331 } 332 333 public void setGender(GenderEnum gender) { 334 this.gender = gender; 335 } 336 337 public int getAge() { 338 return age; 339 } 340 341 public void setAge(int age) { 342 this.age = age; 343 } 344 345 public String getName() { 346 return name; 347 } 348 349 public void setName(String name) { 350 this.name = name; 351 } 352 353 @Override 354 public int compareTo(Person o) { 355 if (this.gender != o.gender) { 356 return this.gender.compareTo(o.gender); 357 } 358 if (this.age != o.age) { 359 return this.age - o.age; 360 } 361 362 return this.name.compareTo(o.name); 363 } 364 365 @Override 366 public String toString() { 367 return "Person [gender=" + gender + ", age=" + age + ", name=" + name + "]"; 368 } 369 } 370 371 enum GenderEnum { 372 MALE, FEMALE 373 } 374 375 static class Item { 376 private String itemId; 377 private String name; 378 private String value; 379 private List subItems; 380 381 public Item(String itemId, String name) { 382 this.itemId = itemId; 383 this.name = name; 384 } 385 386 public String getItemId() { 387 return itemId; 388 } 389 390 public void setItemId(String itemId) { 391 this.itemId = itemId; 392 } 393 394 public String getName() { 395 return name; 396 } 397 398 public void setName(String name) { 399 this.name = name; 400 } 401 402 public String getValue() { 403 return value; 404 } 405 406 public void setValue(String value) { 407 this.value = value; 408 } 409 410 public List getSubItems() { 411 return subItems; 412 } 413 414 public void setSubItems(List subItems) { 415 this.subItems = subItems; 416 } 417 418 @Override 419 public String toString() { 420 return "Item [itemId=" + itemId + ", name=" + name + ", value=" + value + ", subItems=" + subItems + "]"; 421 } 422 } 423 424 public static void main(String[] args) { 425 method5(); 426 } 427 }