在Java中,Stream是一种用于操作集合(Collection)和数组的高级抽象。它提供了一种功能强大且表达力丰富的编程模型,可以以声明性的方式对数据进行处理和转换。
概述:
Stream是Java 8引入的一种新的抽象,它使得我们可以以类似于SQL查询的方式来操作集合数据。Stream不是数据结构,而是对数据进行操作的工具。它可以从集合、数组等数据源创建,并支持各种操作,如过滤、映射、排序、聚合等。
特点:
Stream是面向函数式编程的,它允许使用Lambda表达式进行操作。
Stream提供了一种延迟执行的机制。在进行最终操作之前,可以对Stream进行多次中间操作,这样可以构建一个操作流水线。
Stream操作是惰性的,只有在需要结果时才会进行实际计算。
Stream可以是无限的,也可以是有限的。
创建Stream:
从集合创建:可以通过集合的stream()方法来创建一个Stream流。
从数组创建:可以使用()方法来创建一个Stream流。
从值或数组元素创建:可以使用()方法来创建一个包含指定值或数组元素的Stream流。
从文件创建:可以使用()方法来读取文件并创建一个Stream流。
中间操作和终端操作:
中间操作:中间操作是对Stream进行转换和过滤的操作,它们返回一个新的Stream对象。常见的中间操作包括filter()、map()、sorted()、distinct()等。
终端操作:终端操作是对Stream进行最终操作并产生结果的操作。它们可能返回一个非Stream的结果,例如forEach()、count()、collect()等,或者返回一个新的Stream,例如map()和filter()操作的组合。
常见操作示例:
过滤:使用filter()方法根据给定的条件过滤集合中的元素。
映射:使用map()方法将集合中的元素映射为新的值。
排序:使用sorted()方法对集合中的元素进行排序。
聚合:使用reduce()方法将集合中的元素聚合为单个结果。
收集:使用collect()方法将Stream中的元素收集到集合中。
经典例子
import java.util.Objects;
public class Student {
String name;
int age;
double height;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
public Student() {
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
streamTest
import java.util.*;
import java.util.stream.Collectors;
public class test4 {
/**
* 目标:Stream流的终结方法
*/
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
Student s1 = new Student("蜘蛛精", 26, 172.5);
Student s2 = new Student("蜘蛛精", 26, 172.5);
Student s3 = new Student("紫霞", 23, 167.6);
Student s4 = new Student("白晶晶", 25, 169.0);
Student s5 = new Student("牛魔王", 35, 183.3);
Student s6 = new Student("牛夫人", 34, 168.5);
Collections.addAll(students, s1, s2, s3, s4, s5, s6);
// 需求1:请计算出身高超过168的学生有几人。
long size = students.stream().filter(s -> s.getHeight() > 168).count();
System.out.println(size);
// 需求2:请找出身高最高的学生对象,并输出。
Student s = students.stream().max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
System.out.println(s);
// 需求3:请找出身高最矮的学生对象,并输出。
Student ss = students.stream().min((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
System.out.println(ss);
// 需求4:请找出身高超过170的学生对象,并放到一个新集合中去返回。
// 流只能收集一次。
List<Student> students1 = students.stream().filter(a -> a.getHeight() > 170).collect(Collectors.toList());
System.out.println(students1);
Set<Student> students2 = students.stream().filter(a -> a.getHeight() > 170).collect(Collectors.toSet());
System.out.println(students2);
// 需求5:请找出身高超过170的学生对象,并把学生对象的名字和身高,存入到一个Map集合返回。
Map<String, Double> map =
students.stream().filter(a -> a.getHeight() > 170)
.distinct().collect(Collectors.toMap(a -> a.getName(), a -> a.getHeight()));
System.out.println(map);
// Object[] arr = ().filter(a -> () > 170).toArray();
Student[] arr = students.stream().filter(a -> a.getHeight() > 170).toArray(len -> new Student[len]);
System.out.println(Arrays.toString(arr));
}
}