概述
Stream 的操作三个步骤
- 创建 Stream
一个数据源(如:集合、数组),获取一个流
- 中间操作
一个中间操作链,对数据源的数据进行处理
- 终止操作(终端操作)
一个终止操作,执行中间操作链,并产生结果
1.Stream创建
package jdk.jdk8.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;
/**
* Stream
* Stream不会自己存储数据
* Stream不会改变源数据,会返回一个持有结果的新的stream
* Stram是延时操作
*
*
*
*
*/
public class StreamDemo {
public static void main(String[] args) {
//Stream的创建方式
//1.collection提供的stream()方法或parallelStream()方法
ArrayList<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
Stream<String> stringStream = list.parallelStream();
//2.Arrays的静态方法stream()
Stream<Person> stream1 = Arrays.stream(new Person[10]);
//3.Stream类的静态方法of()
Stream<String> aaa = Stream.of("aaa", "bbb", "ccc");
//4.无限流
//迭代
Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2);
//选择
Stream<Integer> generate = Stream.generate(() -> 1);
}
}
class Person{
}
2.中间操作
多个中间操作可以连接起来形成一个流水线,除非流水 线上触发终止操作,否则中间操作不会执行任何的处理! 而在终止操作时一次性全部处理,称为“惰性求值”。
筛选与切片
| 方 法 |
描 述 |
| filter(Predicate p) |
接收 Lambda , 从流中排除某些元素。 |
| distinct() |
筛选,通过流所生成元素的 hashCode() 和 equals() 去 除重复元素 |
| limit(long maxSize) |
截断流,使其元素不超过给定数量。 |
| skip(long n) |
跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素 不足 n 个,则返回一个空流。与 limit(n) 互补 |
package jdk.jdk8.stream;
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
package jdk.jdk8.stream;
import java.util.ArrayList;
public class StreamDemo2 {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("zhangsan",10));
list.add(new Person("lisi",20));
list.add(new Person("wangwu",30));
list.add(new Person("zhaoliu",40));
list.add(new Person("tianqi",50));
list.add(new Person("tianqi",50));
list.add(new Person("tianqi",50));
//filter(Predicate p) 接收 Lambda , 从流中排除某些元素。
list.stream().filter((person)->{
System.out.println("Streeam Filter...");
return person.getAge()>20;
}).forEach(System.out::println);
System.out.println("-------------------------------------------------------------");
//distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去 除重复元素
list.stream().filter((person)->{
System.out.println("Streeam Filter...");
return person.getAge()>20;
}).distinct().forEach(System.out::println);
System.out.println("-------------------------------------------------------------");
//limit(long maxSize) 截断流,使其元素不超过给定数量。
list.stream().filter((person)->{
System.out.println("Streeam Filter...");
return person.getAge()>20;
}).limit(2).forEach(System.out::println);
System.out.println("-------------------------------------------------------------");
//skip(long n)
list.stream().filter((person)->{
System.out.println("Streeam Filter...");
return person.getAge()>20;
}).skip(2).forEach(System.out::println);
}
}
Streeam Filter...
Streeam Filter...
Streeam Filter...
Person{name='wangwu', age=30}
Streeam Filter...
Person{name='zhaoliu', age=40}
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Person{name='tianqi', age=50}
-------------------------------------------------------------
Streeam Filter...
Streeam Filter...
Streeam Filter...
Person{name='wangwu', age=30}
Streeam Filter...
Person{name='zhaoliu', age=40}
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Streeam Filter...
-------------------------------------------------------------
Streeam Filter...
Streeam Filter...
Streeam Filter...
Person{name='wangwu', age=30}
Streeam Filter...
Person{name='zhaoliu', age=40}
-------------------------------------------------------------
Streeam Filter...
Streeam Filter...
Streeam Filter...
Streeam Filter...
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Person{name='tianqi', age=50}
映射
| 方 法 |
描 述 |
| map(Function f) |
接收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素。 |
| mapToDouble(ToDoubleFunction f) |
接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的 DoubleStream。 mapToInt(ToIntFunction f) |
| flatMap(Function f) |
接收一个函数作为参数,将流中的每个值都换成另 一个流,然后把所有流连接成一个流 |
排序
| 方 法 |
描 述 |
| sorted() |
产生一个新流,其中按自然顺序排序 |
| sorted(Comparator comp) |
产生一个新流,其中按比较器顺序排序 |
3.Stream 的终止操作
终端操作会从流的流水线生成结果。其结果可以是任何不是流的 值,例如:List、Integer,甚至是 void 。
查找与匹配
| 方 法 |
描 述 |
| allMatch(Predicate p) |
检查是否匹配所有元素 |
| anyMatch(Predicate p) |
检查是否至少匹配一个元素 |
| noneMatch(Predicate p) |
检查是否没有匹配所有元素 |
| findFirst() |
返回第一个元素 |
| count() |
返回流中元素总数 |
| max(Comparator c) |
返回流中最大值 |
| min(Comparator c) |
返回流中最小值 |
| forEach(Consumer c) |
内部迭代(使用 Collection 接口需要用户去做迭 代,称为外部迭代。相反,Stream API 使用内部 迭代——它帮你把迭代做了) |
归约
| 方 法 |
描 述 |
| reduce(T iden, BinaryOperator b) |
可以将流中元素反复结合起来,得到一个值。 返回 T 归约 |
| reduce(BinaryOperator b) |
可以将流中元素反复结合起来,得到一个值。 返回 Optional |
| collect(Collector c) |
将流转换为其他形式。接收一个 Collector接口的 实现,用于给Stream中元素做汇总的方法 |
Collector 接口中方法的实现决定了如何对流执行收集操作(如收
集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态
方法,可以方便地创建常见收集器实例,具体方法与实例如下表: