1.Stream 简介
- Stream 自己不会存储元素。
- Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
- Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
2.Stream 的三个操作步骤
2.1创建Stream
代码语言:javascript复制 /**
* 创建 Stream
*/
@Test
public void test1(){
//1。可以通过collection 系列集合提供的 stream()或者parallelstream
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
//2。通过Arrays中的静态方法stream() 获取数组流
Integer[] integers = new Integer[10];
Stream<Integer> stream1 = Arrays.stream(integers);
//3。通过Stream中的静态方法 of()
Stream<String> stringStream = Stream.of("1", "2", "3");
stringStream.limit(1).forEach(System.out::println);
}
2.2中间操作(可省略)
2.2.1 user.java
代码语言:javascript复制package lambda;
import java.util.Objects;
/**
* @author dencycheng
* @date 2020/12/24 7:31 下午
*/
public class User {
private String name;
private int age;
private double salary;
private Status status;
public User() {
}
public User(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public User(String name, int age, double salary, Status status) {
this.name = name;
this.age = age;
this.salary = salary;
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "User{"
"name='" name '''
", age=" age
", salary=" salary
'}';
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Double.compare(user.salary, salary) == 0 && Objects.equals(name, user.name) && status == user.status;
}
@Override
public int hashCode() {
return Objects.hash(name, age, salary, status);
}
public enum Status{
BUSY,FREE
}
}
2.2.2 帅选与切片
代码语言:javascript复制 filter - 接受lambda,从六种排除某些元素
limit - 截断流,时其元素不超过给定数量
skin - 跳过元素,返回一个丢掉钱n个元素的流。若流中元素不足n个,则返回一个空流。与limit互补
distinct - 筛选,通过流生成的hashcode()与equals()去除重复元素
代码语言:javascript复制/**
* filter
*/
@Test
public void test1(){
userList.stream().filter(x->x.getAge()>20)
.forEach(System.out::println);
}
/**
* limit
*/
@Test
public void test2(){
userList.stream().limit(2)
.forEach(System.out::println);
}
/**
* skin
*/
@Test
public void test3(){
userList.stream().skip(4)
.forEach(System.out::println);
}
/**
* distinct
*/
@Test
public void test4(){
userList.stream().distinct()
.forEach(System.out::println);
}
2.2.3 map(构建新的数据结构)
代码语言:javascript复制 /**
* map
*/
@Test
public void Test5(){
userList.stream().map(User::getName).forEach(System.out::println);
}
2.2.4 sort(排序)
代码语言:javascript复制 /**
* 排序
*/
@Test
public void test6(){
List<String> strings = Arrays.asList("aa", "cc", "bb");
strings.stream()
.sorted()
.forEach(System.out::println);
System.out.println("-----------------------------------");
/**
* 默认生序
* 如果想倒叙的话,可以添加-号
*/
userList.stream()
.sorted((u1,u2)-> -u1.getAge().compareTo(u2.getAge())).forEach(System.out::println);
System.out.println("-----------------------------------");
/**
* 先安装年龄生序排序,如果年龄相等按照薪资倒叙
*/
userList.stream()
.sorted((u1,u2)->{
if(u1.getAge().equals(u2.getAge())){
return -u1.getSalary().compareTo(u2.getSalary());
}else {
return u1.getAge().compareTo(u2.getAge());
}
}).forEach(System.out::println);
}
2.3终止操作(终端操作)
代码语言:javascript复制 查找与匹配
allMatch-检查是否匹配所以元素
anyMatch-检查是否至少匹配一个元素
noneMatch-检查是否没有匹配所有元素
findFirst-返回第一个元素
findAny-返回当前流中的任何元素
count-返回流中元素的总个数
max-最大值
min-最小值
代码语言:javascript复制 List<User> userList = Arrays.asList(
new User("张三",20,10000, User.Status.BUSY),
new User("李四",45,6000,User.Status.FREE),
new User("王五",37,3000,User.Status.FREE),
new User("赵六",21,900,User.Status.BUSY),
new User("田七",8,4000,User.Status.FREE),
new User("王八",8,3500,User.Status.BUSY)
);
/**
* 查找与匹配
* allMatch-检查是否匹配所以元素
* anyMatch-检查是否至少匹配一个元素
* noneMatch-检查是否没有匹配所有元素
* findFirst-返回第一个元素
* findAny-返回当前流中的任何元素
* count-返回流中元素的总个数
* max-最大值
* min-最小值
*/
@Test
public void test2(){
long count = userList.stream().count();
System.out.println(count);
System.out.println("---------------");
Optional<User> max = userList.stream()
.max((u1, u2) -> u1.getAge().compareTo(u2.getAge()));
System.out.println(max.get());
System.out.println("---------------");
Optional<User> min = userList.stream()
.min((u1, u2) -> u1.getAge().compareTo(u2.getAge()));
System.out.println(min.get());
System.out.println("---------------");
}
@Test
public void test1(){
boolean b = userList.stream()
.allMatch(x -> x.getStatus().equals(User.Status.BUSY));
System.out.println(b);
System.out.println("--------------------------");
boolean b1 = userList.stream()
.anyMatch(x -> x.getStatus().equals(User.Status.BUSY));
System.out.println(b1);
System.out.println("--------------------------");
boolean b2 = userList.stream()
.noneMatch(x -> x.getStatus().equals(User.Status.BUSY));
System.out.println(b2);
System.out.println("--------------------------");
Optional<User> first = userList.stream()
.findFirst();
System.out.println(first.get());
System.out.println("--------------------------");
Optional<User> any = userList.stream()
.findAny();
System.out.println(any.get());
System.out.println("--------------------------");
}