关于Stream-流的基本操作
concat:合并两个流
distinct:去重
limit:限制从流中获得前n个数据
skip:跳过前n个数据
iterate(1, x -> x + 2):无限流,一个起始值和一个生成下一个值的函数
sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).reversed()排序
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | <br> public static void main(String[] args) { StreamTest test = new StreamTest(); test.streamTest19(); } /** * 提取/组合 * 流也可以进行合并、去重、限制、跳过等操作。 */ public void streamTest19() { String[] arr1 = { "a" , "b" , "c" , "d" }; String[] arr2 = { "d" , "e" , "f" , "g" }; Stream<String> stream1 = Stream.of(arr1); Stream<String> stream2 = Stream.of(arr2); // concat:合并两个流 distinct:去重 List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList()); // limit:限制从流中获得前n个数据 List<Integer> collect = Stream.iterate( 1 , x -> x + 2 ).limit( 10 ).collect(Collectors.toList()); // skip:跳过前n个数据 List<Integer> collect2 = Stream.iterate( 1 , x -> x + 2 ).skip( 1 ).limit( 5 ).collect(Collectors.toList()); System.out.println( "流合并:" + newList); System.out.println( "limit:" + collect); System.out.println( "skip:" + collect2); } /** * 排序(sorted) * 将员工按工资由高到低(工资一样则按年龄由大到小)排序 */ public void streamTest18() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Sherry" , 9000 , 24 , "female" , "New York" )); personList.add( new Person( "Tom" , 8900 , 22 , "male" , "Washington" )); personList.add( new Person( "Jack" , 9100 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 8800 , 26 , "male" , "New York" )); personList.add( new Person( "Alisa" , 9100 , 26 , "female" , "New York" )); // 按工资升序排序(自然排序) List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName) .collect(Collectors.toList()); // 按工资倒序排序 List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed()) .map(Person::getName).collect(Collectors.toList()); // 先按工资再按年龄升序排序 List<String> newList3 = personList.stream() .sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName) .collect(Collectors.toList()); // 先按工资再按年龄自定义排序(降序) List<String> newList4 = personList.stream().sorted((p1, p2) -> { if (p1.getSalary() == p2.getSalary()) { return p2.getAge() - p1.getAge(); } else { return p2.getSalary() - p1.getSalary(); } }).map(Person::getName).collect(Collectors.toList()); System.out.println( "按工资升序排序:" + newList); System.out.println( "按工资降序排序:" + newList2); System.out.println( "先按工资再按年龄升序排序:" + newList3); System.out.println( "先按工资再按年龄自定义降序排序:" + newList4); } /** * 归约(reducing) * Collectors类提供的reducing方法,相比于stream本身的reduce方法,增加了对自定义归约的支持。 */ public void streamTest17() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , 23 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , 21 , "female" , "Washington" )); // 每个员工减去起征点后的薪资之和(这个例子并不严谨,但一时没想到好的例子) Integer sum = personList.stream().collect(Collectors.reducing( 0 , Person::getSalary, (i, j) -> (i + j - 5000 ))); System.out.println( "员工扣税薪资总和:" + sum); // stream的reduce Optional<Integer> sum2 = personList.stream().map(Person::getSalary).reduce(Integer::sum); System.out.println( "员工薪资总和:" + sum2.get()); } /** * 接合(joining) * joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。 */ public void streamTest16() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , 23 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , 21 , "female" , "Washington" )); String names = personList.stream().map(p -> p.getName()).collect(Collectors.joining( "," )); System.out.println( "所有员工的姓名:" + names); List<String> list = Arrays.asList( "A" , "B" , "C" ); String string = list.stream().collect(Collectors.joining( "-" )); System.out.println( "拼接后的字符串:" + string); } /** * 分组(partitioningBy/groupingBy) * 将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组 */ public void streamTest15() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , "female" , "Washington" )); personList.add( new Person( "Anni" , 8200 , "female" , "New York" )); personList.add( new Person( "Owen" , 9500 , "male" , "New York" )); personList.add( new Person( "Alisa" , 7900 , "female" , "New York" )); // 将员工按薪资是否高于8000分组 Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000 )); // 将员工按性别分组 Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex)); // 将员工先按性别分组,再按地区分组 Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea))); System.out.println( "员工按薪资是否大于8000分组情况:" + part); System.out.println( "员工按性别分组情况:" + group); System.out.println( "员工按性别、地区:" + group2); } /** * 统计(count/averaging) * 统计员工人数、平均工资、工资总额、最高工资。 */ public void streamTest14() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , 23 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , 21 , "female" , "Washington" )); // 求总数 Long count = personList.stream().collect(Collectors.counting()); // 求平均工资 Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary)); // 求最高工资 Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare)); // 求工资之和 Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary)); // 一次性统计所有信息 DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary)); System.out.println( "员工总数:" + count); System.out.println( "员工平均工资:" + average); System.out.println( "员工最高工资:" + max); System.out.println( "员工工资总和:" + sum); System.out.println( "员工工资所有统计:" + collect); } /** * 归集(toList/toSet/toMap) * 求所有员工的工资之和和最高工资。 */ public void streamTest13() { List<Integer> list = Arrays.asList( 1 , 6 , 3 , 4 , 6 , 7 , 9 , 6 , 20 ); List<Integer> listNew = list.stream().filter(x -> x % 2 == 0 ).collect(Collectors.toList()); Set<Integer> set = list.stream().filter(x -> x % 2 == 0 ).collect(Collectors.toSet()); List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , 23 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , 21 , "female" , "Washington" )); personList.add( new Person( "Anni" , 8200 , 24 , "female" , "New York" )); Map<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000 ) .collect(Collectors.toMap(Person::getName, p -> p)); System.out.println( "toList:" + listNew); System.out.println( "toSet:" + set); System.out.println( "toMap:" + map); } /** * 归约(reduce) * 求所有员工的工资之和和最高工资。 */ public void streamTest12() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , 23 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , 21 , "female" , "Washington" )); personList.add( new Person( "Anni" , 8200 , 24 , "female" , "New York" )); personList.add( new Person( "Owen" , 9500 , 25 , "male" , "New York" )); personList.add( new Person( "Alisa" , 7900 , 26 , "female" , "New York" )); // 求工资之和方式1: Optional<Integer> sumSalary = personList.stream().map(Person::getSalary).reduce(Integer::sum); // 求工资之和方式2: Integer sumSalary2 = personList.stream().reduce( 0 , (sum, p) -> sum += p.getSalary(), (sum1, sum2) -> sum1 + sum2); // 求工资之和方式3: Integer sumSalary3 = personList.stream().reduce( 0 , (sum, p) -> sum += p.getSalary(), Integer::sum); // 求最高工资方式1: Integer maxSalary = personList.stream().reduce( 0 , (max, p) -> max > p.getSalary() ? max : p.getSalary(), Integer::max); // 求最高工资方式2: Integer maxSalary2 = personList.stream().reduce( 0 , (max, p) -> max > p.getSalary() ? max : p.getSalary(), (max1, max2) -> max1 > max2 ? max1 : max2); System.out.println( "工资之和:" + sumSalary.get() + "," + sumSalary2 + "," + sumSalary3); System.out.println( "最高工资:" + maxSalary + "," + maxSalary2); } /** * 归约(reduce) * 求Integer集合的元素之和、乘积和最大值。 */ public void streamTest11() { List<Integer> list = Arrays.asList( 1 , 3 , 2 , 8 , 11 , 4 ); // 求和方式1 Optional<Integer> sum = list.stream().reduce((x, y) -> x + y); // 求和方式2 Optional<Integer> sum2 = list.stream().reduce(Integer::sum); // 求和方式3 Integer sum3 = list.stream().reduce( 0 , Integer::sum); // 求乘积 Optional<Integer> product = list.stream().reduce((x, y) -> x * y); // 求最大值方式1 Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y); // 求最大值写法2 Integer max2 = list.stream().reduce( 1 , Integer::max); System.out.println( "list求和:" + sum.get() + "," + sum2.get() + "," + sum3); System.out.println( "list求积:" + product.get()); System.out.println( "list求和:" + max.get() + "," + max2); } /** * 映射(map/flatMap) * 将两个字符数组合并成一个新的字符数组。 */ public void streamTest10() { List<String> list = Arrays.asList( "m,k,l,a" , "1,3,5,7" ); List<String> listNew = list.stream().flatMap(s -> { // 将每个元素转换成一个stream String[] split = s.split( "," ); Stream<String> s2 = Arrays.stream(split); return s2; }).collect(Collectors.toList()); System.out.println( "处理前的集合:" + list); System.out.println( "处理后的集合:" + listNew); } /** * 映射(map/flatMap) * 将员工的薪资全部增加10000。 */ public void streamTest9() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , 23 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , 21 , "female" , "Washington" )); personList.add( new Person( "Anni" , 8200 , 24 , "female" , "New York" )); personList.add( new Person( "Owen" , 9500 , 25 , "male" , "New York" )); personList.add( new Person( "Alisa" , 7900 , 26 , "female" , "New York" )); // 改变原来员工集合的方式 List<Person> personListNew = personList.stream().map(person -> { Person personNew = new Person(person.getName(), 0 , 0 , null , null ); personNew.setSalary(person.getSalary() + 10000 ); return personNew; }).collect(Collectors.toList()); System.out.println( "一次改动前:" + JSON.toJSONString(personList)); System.out.println( "一次改动后:" + JSON.toJSONString(personListNew)); // 不改变原来员工集合的方式 List<Person> personListNew2 = personList.stream().map(person -> { person.setSalary(person.getSalary() + 10000 ); return person; }).collect(Collectors.toList()); System.out.println( "二次改动前:" + JSON.toJSONString(personList)); System.out.println( "二次改动后:" + JSON.toJSONString(personListNew2)); } /** * 映射(map/flatMap) * 英文字符串数组的元素全部改为大写。整数数组每个元素+3。 */ public void streamTest8() { String[] strArr = { "abcd" , "bcdd" , "defde" , "fTr" }; List<String> strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList()); List<Integer> intList = Arrays.asList( 1 , 3 , 5 , 7 , 9 , 11 ); List<Integer> intListNew = intList.stream().map(x -> x + 3 ).collect(Collectors.toList()); System.out.println( "每个元素大写:" + strList); System.out.println( "每个元素+3:" + intListNew); } /** * 聚合(max/min/count) * 计算Integer集合中大于6的元素的个数。 */ public void streamTest7() { List<Integer> list = Arrays.asList( 7 , 6 , 4 , 8 , 2 , 11 , 9 ); long count = list.stream().filter(x -> x > 6 ).count(); System.out.println( "list中大于6的元素个数:" + count); } /** * 聚合(max/min/count) * 获取员工工资最高的人。 */ public void streamTest6() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , 23 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , 21 , "female" , "Washington" )); personList.add( new Person( "Anni" , 8200 , 24 , "female" , "New York" )); personList.add( new Person( "Owen" , 9500 , 25 , "male" , "New York" )); personList.add( new Person( "Alisa" , 7900 , 26 , "female" , "New York" )); Optional<Person> max = personList.stream().max(Comparator.comparingInt(Person::getSalary)); System.out.println( "员工工资最大值:" + max.get().getSalary()); } /** * 聚合(max/min/count) * 获取Integer集合中的最大值。 */ public void streamTest5() { List<Integer> list = Arrays.asList( 7 , 6 , 9 , 4 , 11 , 6 ); // 自然排序 Optional<Integer> max = list.stream().max(Integer::compareTo); // 自定义排序 Optional<Integer> max2 = list.stream().max( new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } }); System.out.println( "自然排序的最大值:" + max.get()); System.out.println( "自定义排序的最大值:" + max2.get()); } /** * 聚合(max/min/count) * 获取String集合中最长的元素。 */ public void streamTest4() { List<String> list = Arrays.asList( "adnm" , "admmt" , "pot" , "xbangd" , "weoujgsd" ); Optional<String> max = list.stream().max(Comparator.comparing(String::length)); System.out.println( "最长的字符串:" + max.get()); } /** * 筛选员工中工资高于8000的人,并形成新的集合。 形成新集合依赖collect(收集), */ public void streamTest3() { List<Person> personList = new ArrayList<Person>(); personList.add( new Person( "Tom" , 8900 , 23 , "male" , "New York" )); personList.add( new Person( "Jack" , 7000 , 25 , "male" , "Washington" )); personList.add( new Person( "Lily" , 7800 , 21 , "female" , "Washington" )); personList.add( new Person( "Anni" , 8200 , 24 , "female" , "New York" )); personList.add( new Person( "Owen" , 9500 , 25 , "male" , "New York" )); personList.add( new Person( "Alisa" , 7900 , 26 , "female" , "New York" )); List<String> fiterList = personList.stream().filter(x -> x.getSalary() > 8000 ).map(Person::getName) .collect(Collectors.toList()); System.out.print( "高于8000的员工姓名:" + fiterList); } /** * 筛选出Integer集合中大于7的元素,并打印出来 */ public static void streamTestFilter() { List<Integer> list = Arrays.asList( 6 , 7 , 3 , 8 , 1 , 2 , 9 ); Stream<Integer> stream = list.stream(); stream.filter(x -> x > 7 ).forEach(System.out::println); } /** * 遍历/匹配(foreach/find/match) */ public static void streamTest2() { List<Integer> list = Arrays.asList( 7 , 6 , 9 , 3 , 8 , 2 , 1 ); // 遍历输出符合条件的元素 list.stream().filter(x -> x > 6 ).forEach(System.out::println); // 匹配第一个 Optional<Integer> findFirst = list.stream().filter(x -> x > 6 ).findFirst(); // 匹配任意(适用于并行流) Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6 ).findAny(); // 是否包含符合特定条件的元素 boolean anyMatch = list.stream().anyMatch(x -> x > 8 ); System.out.println( "匹配第一个值:" + findFirst.get()); System.out.println( "匹配任意一个值:" + findAny.get()); System.out.println( "是否存在大于8的值:" + anyMatch); } /** * Stream可以通过集合数组创建。 */ public static void stream1Test() { // 1、通过 java.util.Collection.stream() 方法用集合创建流 List<String> list1 = Arrays.asList( "a" , "b" , "c" ); // 创建一个顺序流 Stream<String> stream = list1.stream(); // 创建一个并行流 Stream<String> parallelStream = list1.parallelStream(); // 使用java.util.Arrays.stream(T[] array)方法用数组创建流 int [] array = { 1 , 3 , 5 , 6 , 8 }; IntStream stream0 = Arrays.stream(array); // 使用Stream的静态方法:of()、iterate()、generate() Stream<Integer> stream1 = Stream.of( 1 , 2 , 3 , 4 , 5 , 6 ); Stream<Integer> stream2 = Stream.iterate( 0 , (x) -> x + 3 ).limit( 4 ); stream2.forEach(System.out::println); Stream<Double> stream3 = Stream.generate(Math::random).limit( 3 ); stream3.forEach(System.out::println); } class Person { private String name; // 姓名 private int salary; // 薪资 private int age; // 年龄 private String sex; //性别 private String area; // 地区 // 构造方法 public Person(String name, int salary, int age, String sex, String area) { this .name = name; this .salary = salary; this .age = age; this .sex = sex; this .area = area; } // 构造方法 public Person(String name, int salary, String sex, String area) { this .name = name; this .salary = salary; this .sex = sex; this .area = area; } public String getName() { return name; } public void setName(String name) { this .name = name; } public int getSalary() { return salary; } public void setSalary( int salary) { this .salary = salary; } public int getAge() { return age; } public void setAge( int age) { this .age = age; } public String getSex() { return sex; } public void setSex(String sex) { this .sex = sex; } public String getArea() { return area; } public void setArea(String area) { this .area = area; } @Override public String toString() { final StringBuilder sb = new StringBuilder( "{" ); sb.append( "\"name\":\"" ) .append(name).append( '\"' ); sb.append( ",\"salary\":" ) .append(salary); sb.append( ",\"age\":" ) .append(age); sb.append( ",\"sex\":\"" ) .append(sex).append( '\"' ); sb.append( ",\"area\":\"" ) .append(area).append( '\"' ); sb.append( '}' ); return sb.toString(); } } |
分类:
关于java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!