Java Stream流操作详解:实现代码简洁与性能高效的完美结合
目录
🚀前言

大家好!我是 EnigmaCoder。
本文介绍了Java中Stream相关的知识,包括获取Stream流、Stream流的中间方法和终结方法等。
🤔认识Stream流
Stream流是JDK8开始新增的一套API(java.util.stream.*),可以用来操作集合或者数组的数据。
优势:Stream流大量的结合了Lambda的语法风格来编程,功能强大,性能高效,代码简洁,可读性好。
⚙️Stream流的使用步骤
- 获取
Stream流:Stream流代表一条流水线,并能与数据源建立连接。 - 调用流水线的各种方法:对数据进行处理、计算。
- 获取处理的结果:遍历、统计、收集到一个新集合中返回。
💯获取Stream流
Stream流| Collection提供的方法 | 说明 |
|---|---|
| default Stream< E> stream() | 获取当前集合对象的Stream流 |
Stream流| Arrays类提供的如下方法 | 说明 |
|---|---|
| public static < T > Stream< T> stream(T[ ] array) | 获取当前数组的Stream流 |
| Stream类提供的如下方法 | 说明 |
|---|---|
| public static< T> Stream< T> of(T… values) | 获取当前接收数据的Stream流 |
import java.util.*;
import java.util.stream.Stream;
public class StreamCreationExample {
public static void main(String[] args) {
// 1. 从Collection获取Stream流
List<String> list = Arrays.asList("apple", "banana", "cherry");
Stream<String> listStream = list.stream();
listStream.forEach(System.out::println); // 输出: apple banana cherry
// 2. 从数组获取Stream流
Integer[] array = {1, 2, 3, 4, 5};
Stream<Integer> arrayStream = Arrays.stream(array);
arrayStream.filter(n -> n % 2 == 0)
.forEach(System.out::println); // 输出: 2 4
// 3. 使用Stream.of()获取Stream流
Stream<String> ofStream = Stream.of("Java", "Python", "C++");
ofStream.map(String::toUpperCase)
.forEach(System.out::println); // 输出: JAVA PYTHON C++
// 4. 直接从可变参数创建Stream
Stream<Integer> numbers = Stream.of(10, 20, 30);
numbers.reduce(Integer::sum)
.ifPresent(sum -> System.out.println("Sum: " + sum)); // 输出: Sum: 60
}
}
🦜常用的中间方法
中间方法指的是调用完成后会返回新的stream流,可以继续使用(支持链式编程)。
| Stream提供的常用的中间方法 | 说明 |
|---|---|
| Stream< T > filter(Predicate<? super T> predicate) | 用于对流中的数据进行过滤 |
| Stream< T > sorted() | 对元素进行升序排序 |
| Stream< T >sorted(Comparator<? super T>comparator) | 按照指定规则排序 |
| Stream< T >limit(long maxsize) | 获取前几个元素 |
| Stream< T >skip(long n) | 跳过前几个元素 |
| Stream< T >distinct() | 去除流中重复的元素 |
| < R > Stream < R > map(Function< ? super T , ? extends R> mapper) | 对元素进行加工,并返回对应的新流 |
| static < T > Stream< T > concat(Stream a,Stream b) | 合并a和b两个流为一个流 |
public class Test {
public static void main(String[] args) {
List<Double> scores=new ArrayList<>();
scores.add(48.4);
scores.add(63.1);
scores.add(63.1);
scores.add(74.0);
scores.add(85.9);
scores.add(96.3);
scores.stream().sorted().forEach(System.out::println);//升序
System.out.println("--------------------------------");
scores.stream().sorted((s1,s2)->Double.compare(s2,s1)).forEach(System.out::println);//降序
System.out.println("--------------------------------");
scores.stream().sorted((s1,s2)->Double.compare(s2,s1)).limit(3).forEach(System.out::println);//取前3个
System.out.println("--------------------------------");
scores.stream().sorted((s1,s2)->Double.compare(s2,s1)).skip(3).forEach(System.out::println);//跳过前3个
System.out.println("--------------------------------");
scores.stream().sorted((s1,s2)->Double.compare(s2,s1)).distinct().forEach(System.out::println);//去重
System.out.println("--------------------------------");
scores.stream().map(s->s*2).forEach(System.out::println);
System.out.println("--------------------------------");
Stream<String> s1=Stream.of("hello","world","java");
Stream<Integer> s2=Stream.of(1,2,3);
Stream<Object>s3=Stream.concat(s1,s2);//拼接
s3.forEach(System.out::println);
}
}
🌟Stream流的终结方法
终结方法指的是调用完成后,不会返回新的Stream了,没法继续使用流了。
| Stream提供的常用终结方法 | 说明 |
|---|---|
| void forEach(Consumer action) | 对此流运算后的元素执行遍历 |
| long count() | 统计此流运算后的元素个数 |
| Optional < T > max(Comparator< ? super T> comparator) | 获取此流运算后的最大值元素 |
| Optional < T > min(Comparator< ? super T> comparator) | 获取此流运算后的最小值元素 |
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
class Teacher {
private String name;
private int age;
private double salary;
public Teacher(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public double getSalary() {
return salary;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
}
public class StreamDemo4 {
public static void main(String[] args) {
List<Teacher> teachers = new ArrayList<>();
teachers.add(new Teacher("陈昆", 42, 48000));
teachers.add(new Teacher("张宇", 38, 18000));
teachers.add(new Teacher("李娜", 35, 12000));
// forEach方法:遍历薪水大于15000的老师
teachers.stream()
.filter(t -> t.getSalary() > 15000)
.forEach(System.out::println);
System.out.println("-----------------------------");
// count方法:统计薪水大于15000的老师数量
long count = teachers.stream()
.filter(t -> t.getSalary() > 15000)
.count();
System.out.println(count);
System.out.println("-----------------------------");
// 获取薪水最高的老师对象
Optional<Teacher> max = teachers.stream().max((t1, t2) -> Double.compare(t1.getSalary(), t2.getSalary()));
Teacher maxTeacher = max.get();//获取Optional对象中的元素
System.out.println(maxTeacher);
// 获取薪水最低的老师对象
Optional<Teacher> min = teachers.stream().min((t1, t2) -> Double.compare(t1.getSalary(), t2.getSalary()));
Teacher minTeacher = min.get();
System.out.println(minTeacher);
}
}
💯收集Stream流
收集Stream流就是把Stream流操作后的结果转回到集合或者数组中去返回。
注意:
Stream流只是方便操作集合/数组的手段;集合/数组:才是开发中的目的。Stream流只能被收集一次。| Stream提供的常用终结方法 | 说明 |
|---|---|
| R collect(Collecter collector) | 把流处理后的结果收集到一个指定的集合中去 |
| Object[ ] toArray() | 把流处理后的结果收集到一个数组中去 |
| Collectors 工具类提供了具体的收集方式 | 说明 |
|---|---|
| public static < T > Collector toList() | 把元素收集到List集合中 |
| public static < T > Collector toSet() | 把元素收集到Set集合中 |
| public static Collector toMap(Function keyMapper,Function valueMapper) | 把元素收集到Map集合中 |
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Teacher {
private String name;
private double salary;
public Teacher(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
}
public class StreamCollectTest {
public static void main(String[] args) {
// 1. 收集到数组
List<String> stringList = Arrays.asList("张三", "李四", "张五", "王六");
Object[] array = stringList.stream()
.filter(s -> s.startsWith("张"))
.toArray();
System.out.println("数组: " + Arrays.toString(array));
// 2. 收集到List
List<String> filteredList = stringList.stream()
.filter(s -> s.length() == 2)
.collect(Collectors.toList());
System.out.println("List: " + filteredList);
// 3. 收集到Set(自动去重,此处无重复,效果同List)
Set<String> stringSet = stringList.stream()
.filter(s -> s.contains("张"))
.collect(Collectors.toSet());
System.out.println("Set: " + stringSet);
// 4. 收集到Map(Teacher示例)
List<Teacher> teachers = Arrays.asList(
new Teacher("张三", 10000.0),
new Teacher("李四", 8000.0),
new Teacher("张五", 12000.0)
);
Map<String, Double> teacherMap = teachers.stream()
.collect(Collectors.toMap(
Teacher::getName, // 键映射:老师姓名
Teacher::getSalary // 值映射:老师薪水
));
System.out.println("Map: " + teacherMap);
}
}
作者:EnigmaCoder