深度掌握 Java Stream 流操作,让你的代码高出一个逼格!

输出结果:

8

9

Process finished with exit code 0

聚合(max/min/count)

maxmincount 这些字眼你一定不陌生,没错,在mysql中我们常用它们进行数据统计。Java stream中也引入了这些概念和用法,极大地方便了我们对集合、数组的数据统计工作。

案例一:获取 String 集合中最长的元素。

public class StreamTest {

public static void main(String[] args) {

List list = Arrays.asList(“adnm”, “admmt”, “pot”, “xbangd”, “weoujgsd”);

Optional max = list.stream().max(Comparator.comparing(String::length));

System.out.println(“最长的字符串:” + max.get());

}

}

输出结果:

最长的字符串:weoujgsd

Process finished with exit code 0

案例二:获取 Integer 集合中的最大值。

public class StreamTest {

public static void main(String[] args) {

List list = Arrays.asList(7, 6, 9, 4, 11, 6);

// 自然排序

Optional max = list.stream().max(Integer::compareTo);

// 自定义排序

Optional max2 = list.stream().max(new Comparator() {

@Override

public int compare(Integer o1, Integer o2) {

return o1.compareTo(o2);

}

});

System.out.println(“自然排序的最大值:” + max.get());

System.out.println(“自定义排序的最大值:” + max2.get());

}

}

输出结果:

自然排序的最大值:11

自定义排序的最大值:11

Process finished with exit code 0

案例三:计算 Integer 集合中大于6的元素的个数。

public class StreamTest {

public static void main(String[] args) {

List 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);

}

}

输出结果:

list中大于6的元素个数:4

Process finished with exit code 0

映射(map/flatMap)

映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为 mapflatMap

map

flatMap

案例一:英文字符串数组的元素全部改为大写。整数数组每个元素+3。

public class StreamTest {

public static void main(String[] args) {

String[] strArr = { “abcd”, “bcdd”, “defde”, “fTr” };

List strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());

System.out.println(“每个元素大写:” + strList);

List intList = Arrays.asList(1, 3, 5, 7, 9, 11);

List intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());

System.out.println(“每个元素+3:” + intListNew);

}

}

输出结果:

每个元素大写:[ABCD, BCDD, DEFDE, FTR]

每个元素+3:[4, 6, 8, 10, 12, 14]

Process finished with exit code 0

案例二:将两个字符数组合并成一个新的字符数组。

public class StreamTest {

public static void main(String[] args) {

List list = Arrays.asList(“m,k,l,a”, “1,3,5,7”);

List listNew = list.stream().flatMap(s -> {

// 将每个元素转换成一个stream

String[] split = s.split(“,”);

Stream s2 = Arrays.stream(split);

return s2;

}).collect(Collectors.toList());

System.out.println(“处理前的集合:” + list);

System.out.println(“处理后的集合:” + listNew);

}

}

输出结果:

处理前的集合:[m,k,l,a, 1,3,5,7]

处理后的集合:[m, k, l, a, 1, 3, 5, 7]

Process finished with exit code 0

归约(reduce)

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

案例一:求 Integer 集合的元素之和、乘积和最大值。

public class StreamTest {

public static void main(String[] args) {

List list = Arrays.asList(1, 3, 2, 8, 11, 4);

// 求和方式1

Optional sum = list.stream().reduce(Integer::sum);

// 求和方式2

Optional sum2 = list.stream().reduce(Integer::sum);

// 求和方式3

Integer sum3 = list.stream().reduce(0, Integer::sum);

// 求乘积

Optional product = list.stream().reduce((x, y) -> x * y);

// 求最大值方式1

Optional 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);

}

}

输出结果:

list求和:29,29,29

list求积:2112

list求和:11,11

Process finished with exit code 0

归集(toList/toSet/toMap)

因为流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。 toListtoSettoMap 比较常用,另外还有 toCollectiontoConcurrentMap 等复杂一些的用法。

下面用一个案例演示 toListtoSettoMap

public 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 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() {

return “Person{” +

“name='” + name + ‘’’ +

“, salary=” + salary +

“, age=” + age +

“, sex='” + sex + ‘’’ +

“, area='” + area + ‘’’ +

‘}’;

}

}

public class StreamTest {

public static void main(String[] args) {

List list = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20);

List listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());

Set set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());

List personList = new ArrayList();

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);

}

}

输出结果:

toList:[6, 4, 6, 6, 20]

toSet:[4, 20, 6]

toMap:{Tom=Person{name=‘Tom’, salary=8900, age=23, sex=‘male’, area=‘New York’}, Anni=Person{name=‘Anni’, salary=8200, age=24, sex=‘female’, area=‘New York’}}

Process finished with exit code 0

统计(count/averaging)

Collectors 提供了一系列用于数据统计的静态方法:

  • 计数: count

  • 平均值: averagingIntaveragingLongaveragingDouble

  • 最值: maxByminBy

  • 求和: summingIntsummingLongsummingDouble

  • 统计以上所有: summarizingIntsummarizingLongsummarizingDouble

案例:统计员工人数、平均工资、工资总额、最高工资。

public class StreamTest {

public static void main(String[] args) {

List personList = new ArrayList();

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.size();

// 求平均工资

Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));

// 求最高工资

Optional max = personList.stream().map(Person::getSalary).max(Integer::compare);

// 求工资之和

int sum = personList.stream().mapToInt(Person::getSalary).sum();

// 一次性统计所有信息

DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));

System.out.println(“员工总数:” + count);

System.out.println(“员工平均工资:” + average);

System.out.println(“员工最高工资:” + max.get());

System.out.println(“员工工资总和:” + sum);

System.out.println(“员工工资所有统计:” + collect);

}

}

输出结果:

员工总数:3

员工平均工资:7900.0

员工最高工资:8900

员工工资总和:23700

员工工资所有统计:DoubleSummaryStatistics{count=3, sum=23700.000000, min=7000.000000, average=7900.000000, max=8900.000000}

Process finished with exit code 0

分组(partitioningBy/groupingBy)

  • 分区:将 stream 按条件分为两个 Map ,比如员工按薪资是否高于8000分为两部分。

  • 分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。

案例:将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组

public class StreamTest {

public static void main(String[] args) {

List personList = new ArrayList();

personList.add(new Person(“Tom”, 8900, 23, “male”, “Washington”));

personList.add(new Person(“Jack”, 7000, 25, “male”, “Washington”));

personList.add(new Person(“Lily”, 7800, 21, “female”, “New York”));

personList.add(new Person(“Anni”, 8200, 24, “female”, “New York”));

// 将员工按薪资是否高于8000分组

Map<Boolean, List> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));

// 将员工按性别分组

Map<String, List> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));

// 将员工先按性别分组,再按地区分组

Map<String, Map<String, List>> 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);

}

}

输出结果:

员工按薪资是否大于8000分组情况:{false=[Person{name=‘Jack’, salary=7000, age=25, sex=‘male’, area=‘Washington’}, Person{name=‘Lily’, salary=7800, age=21, sex=‘female’, area=‘New York’}], true=[Person{name=‘Tom’, salary=8900, age=23, sex=‘male’, area=‘Washington’}, Person{name=‘Anni’, salary=8200, age=24, sex=‘female’, area=‘New York’}]}

员工按性别分组情况:{female=[Person{name=‘Lily’, salary=7800, age=21, sex=‘female’, area=‘New York’}, Person{name=‘Anni’, salary=8200, age=24, sex=‘female’, area=‘New York’}], male=[Person{name=‘Tom’, salary=8900, age=23, sex=‘male’, area=‘Washington’}, Person{name=‘Jack’, salary=7000, age=25, sex=‘male’, area=‘Washington’}]}

员工按性别、地区:{female={New York=[Person{name=‘Lily’, salary=7800, age=21, sex=‘female’, area=‘New York’}, Person{name=‘Anni’, salary=8200, age=24, sex=‘female’, area=‘New York’}]}, male={Washington=[Person{name=‘Tom’, salary=8900, age=23, sex=‘male’, area=‘Washington’}, Person{name=‘Jack’, salary=7000, age=25, sex=‘male’, area=‘Washington’}]}}

Process finished with exit code 0

接合(joining)

joining 可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。

public class StreamTest {

public static void main(String[] args) {

List personList = new ArrayList();

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(Person::getName).collect(Collectors.joining(“,”));

System.out.println(“所有员工的姓名:” + names);

List list = Arrays.asList(“A”, “B”, “C”);

String string = list.stream().collect(Collectors.joining(“-”));

System.out.println(“拼接后的字符串:” + string);

}

}

输出结果:

所有员工的姓名:Tom,Jack,Lily

拼接后的字符串:A-B-C

Process finished with exit code 0

排序(sorted)

sorted ,中间操作。有两种排序:

  • sorted() :自然排序,流中元素需实现 Comparable 接口

  • sorted(Comparator com)Comparator 排序器自定义排序

案例:将员工按工资由高到低(工资一样则按年龄由大到小)排序

public class StreamTest {

public static void main(String[] args) {

List personList = new ArrayList();

personList.add(new Person(“Sherry”, 9000, 24, “female”, “New York”));

personList.add(new Person(“Tom”, 8900, 22, “male”, “Washington”));

personList.add(new Person(“Jack”, 9000, 25, “male”, “Washington”));

personList.add(new Person(“Lily”, 8800, 26, “male”, “New York”));

personList.add(new Person(“Alisa”, 9000, 26, “female”, “New York”));

// 按工资升序排序(自然排序)

List newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)

.collect(Collectors.toList());

// 按工资倒序排序

List newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())

.map(Person::getName).collect(Collectors.toList());

// 先按工资再按年龄升序排序

List newList3 = personList.stream()

.sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)

.collect(Collectors.toList());

// 先按工资再按年龄自定义排序(降序)

List 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);

}

}

输出结果:

按工资升序排序:[Lily, Tom, Sherry, Jack, Alisa]

按工资降序排序:[Sherry, Jack, Alisa, Tom, Lily]

先按工资再按年龄升序排序:[Lily, Tom, Sherry, Jack, Alisa]

先按工资再按年龄自定义降序排序:[Alisa, Jack, Sherry, Tom, Lily]

Process finished with exit code 0

提取/组合

流也可以进行合并、去重、限制、跳过等操作。

public class StreamTest {

public static void main(String[] args) {

String[] arr1 = { “a”, “b”, “c”, “d” };

String[] arr2 = { “d”, “e”, “f”, “g” };

Stream stream1 = Stream.of(arr1);

Stream stream2 = Stream.of(arr2);

// concat:合并两个流 distinct:去重

List newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());

// limit:限制从流中获得前n个数据

List collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());

// skip:跳过前n个数据

List 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);

}

}

输出结果:

流合并:[a, b, c, d, e, f, g]

limit:[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

skip:[3, 5, 7, 9, 11]

Process finished with exit code 0

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

Docker步步实践

目录文档:

①Docker简介

②基本概念

③安装Docker

④使用镜像:

⑤操作容器:

⑥访问仓库:

⑦数据管理:

⑧使用网络:

⑨高级网络配置:

⑩安全:

⑪底层实现:

⑫其他项目:

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

Docker步步实践

目录文档:

[外链图片转存中…(img-xw1D8Usx-1713749660674)]

[外链图片转存中…(img-U7Ql2USR-1713749660674)]

①Docker简介

②基本概念

③安装Docker

[外链图片转存中…(img-aWCfUDkD-1713749660674)]

④使用镜像:

[外链图片转存中…(img-2v3tOqxn-1713749660675)]

⑤操作容器:

[外链图片转存中…(img-plCmMp81-1713749660675)]

⑥访问仓库:

[外链图片转存中…(img-IHnLms0y-1713749660675)]

⑦数据管理:

[外链图片转存中…(img-FjEjPaKx-1713749660675)]

⑧使用网络:

[外链图片转存中…(img-2S5c6yCL-1713749660675)]

⑨高级网络配置:

[外链图片转存中…(img-E7lWYE3f-1713749660676)]

⑩安全:

[外链图片转存中…(img-wiXQTxue-1713749660676)]

⑪底层实现:

[外链图片转存中…(img-Gcs7itLO-1713749660676)]

⑫其他项目:

[外链图片转存中…(img-LDqCu5kn-1713749660676)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个完整的Java Stream案例,包含了Stream中的常用功能: ```java import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; public class StreamDemo { public static void main(String[] args) throws IOException { // 读取文件并过滤掉空行 List<String> lines = Files.lines(Paths.get("data.txt")) .filter(line -> !line.trim().isEmpty()) .collect(Collectors.toList()); // 将过滤后的内容写入到新文件中 Files.write(Paths.get("data_copy.txt"), lines); // 将过滤后的内容转为大写并写入到新文件中 Files.write(Paths.get("data_uppercase.txt"), lines.stream() .map(String::toUpperCase) .collect(Collectors.toList())); // 将过滤后的内容写入到gz压缩文件中 try (GZIPOutputStream out = new GZIPOutputStream(Files.newOutputStream(Paths.get("data.txt.gz")))) { lines.forEach(line -> { try { out.write(line.getBytes()); out.write('\n'); } catch (IOException e) { e.printStackTrace(); } }); } // 读取gz压缩文件并解压缩 try (GZIPInputStream in = new GZIPInputStream(Files.newInputStream(Paths.get("data.txt.gz")))) { byte[] buffer = new byte[1024]; StringBuilder sb = new StringBuilder(); int read; while ((read = in.read(buffer)) != -1) { sb.append(new String(buffer, 0, read)); } String content = sb.toString(); System.out.println(content); } // 从数组中创建Stream并输出每个元素的平方 int[] numbers = {1, 2, 3, 4, 5}; Arrays.stream(numbers) .map(n -> n * n) .forEach(System.out::println); // 从List中创建Stream并输出满足条件的元素 List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date", "elderberry"); fruits.stream() .filter(fruit -> fruit.startsWith("a") || fruit.startsWith("c")) .forEach(System.out::println); } } ``` 以上代码实现了以下功能: 1. 读取本地的data.txt文件,并过滤掉空行,将过滤后的内容写入到新文件data_copy.txt中; 2. 将过滤后的内容转为大写并写入到新文件data_uppercase.txt中; 3. 将过滤后的内容写入到gz压缩文件data.txt.gz中; 4. 读取gz压缩文件data.txt.gz并解压缩,输出解压缩后的内容; 5. 从数组中创建Stream并输出每个元素的平方; 6. 从List中创建Stream并输出满足条件的元素。 以上代码演示了Java Stream的常用操作,包括创建Stream、过滤、映射、收集等操作,以及与文件和压缩文件的交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值