了解 Stream
- Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一个则是 Stream API(java.util.stream.*)。Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式.
- 关键点:
- Stream是针对集合操作的API
- Stream主要是为集合进行复杂查询操作的
什么是 Stream
- 是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,流讲的是计算!”
- 注意:
- Stream 自己不会存储元素。
- Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
- Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
Stream使用的三个步骤
- 创建Stream对象
- 调用Stream的中间操作(也就是对数据进行筛选等等操作)
- 终止操作:产生最终结果.
如何创建Stream
- 通过Collocation接口创建
方法名 | 返回值 | 说明 |
---|
default Stream<E> stream() | Stream<E> | 返回一个顺序流 |
default Stream<E> parallelStream() | Stream<E> | 返回一个并行流 |
- 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
- 示例:
List<String> strings = new ArrayList<>();
Stream<String> stream = strings.parallelStream();
- 通过数组创建Stream
- Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:
- 其中有许多重载的方法返回不同基本数据类型的Steam对象(Integer,String,Double)
方法名 | 返回值 | 说明 |
---|
static <T> Stream<T> stream(T[] array) | Stream<T> | 返回一个类型为T的流 |
public static IntStream stream(int[] array) | IntStream | IntStream |
public static LongStream stream(long[] array) | LongStream | LongStream |
public static DoubleStream stream(double[] array) | DoubleStream | DoubleStream |
String[] strArray = {"1"};
Stream<String> stringStream = Arrays.stream(strArray);
- 通过Stream.of()方法,创建流
方法名 | 返回值 | 说明 |
---|
public static<T> Stream<T> of(T… values) | 返回一个类型为T的流 | 接收一个或多个现有的值value,创建一个value类型的流 |
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);
- 创建无限流
方法名 | 返回值 | 说明 |
---|
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) | Stream<T> | 返回一个类型为T的无限流 |
public static<T> Stream<T> generate(Supplier<T> s) | Stream<T> | 返回一个类型为T的无限流 |
- 第一个参数为起始数据,第二个参数是一个一元运算操作接口,如果没有中间操作,那么创建出来的无限流数据时没有止境的.
- 示例:
Stream<Integer> iterate = Stream.iterate(1, (x) -> x + 2);
iterate.forEach(System.out::println);
中间操作
- 多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。
筛选与切片
方法 | 描述 |
---|
filter(Predicate p) | 接收 Lambda , 从流中排除某些元素 |
distinct() | 筛选,通过流所生成元素的hashCode()和equals()去除重复元素 |
limit(long maxSize) | 截断流,使其元素不超过给定数量 |
skip(long n) | 跳过元素,返回一个扔掉了前n个元素的流.若流中元素不足n个,则返回一个空流…与limit(n)互补 |
List<Employee> employeeList = Arrays.asList(
new Employee("xiemaoshu", 23, 5000.0),
new Employee("lanchaogou", 23, 10000.0),
new Employee("xxx", 30, 3000.0),
new Employee("yyy", 40, 2000.0),
new Employee("yyy", 40, 2000.0),
new Employee("yyy", 40, 2000.0)
);
@Test
public void test1() {
Stream<Employee> employeeStream = employeeList.stream().filter(e -> e.getAge() > 30);
employeeStream.forEach(System.out::println);
}
@Test
public void test2() {
employeeList.stream().distinct().forEach(System.out::println);
}
@Test
public void test3() {
employeeList.stream().limit(3).forEach(System.out::println);
}
@Test
public void test4() {
employeeList.stream().skip(4).forEach(System.out::println);
}
映射
方法 | 描述 |
---|
map(Function f) | 接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素. |
mapToDouble(ToDoubleFunctionf) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。 |
mapTioInt(ToIntFunction f) | 接受一个函数作为参数,该函数会被应用到每个元素上,产生一个新的IntStream |
flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有的流连接成一个流 |
@Test
public void test1() {
List<String> stringList = Arrays.asList("xiemaoshu","lanchaogou","huahui");
Stream<String> stringStream = stringList.stream().map((e) -> e.toUpperCase());
stringStream.forEach(System.out::println);
}
@Test
public void test2() {
List<Integer> integerList = Arrays.asList(1,2,3,4);
DoubleStream doubleStream = integerList.stream().mapToDouble((e) -> e + 1);
doubleStream.forEach(System.out::println);
}
@Test
public void test3() {
List<String> stringList = Arrays.asList("xiemaoshu","lanchaogou","huahui");
IntStream intStream = stringList.stream().mapToInt(String::length);
intStream.forEach(System.out::println);
}
@Test
public void test4() {
List<String> stringList = Arrays.asList("xiemaoshu","lanchaogou","huahui");
List<String> stringList1 = Arrays.asList("xiemaoshu","lanchaogou","huahui");
List<String> stringList2= Arrays.asList("xiemaoshu","lanchaogou","huahui");
List<String> stringList3 = Arrays.asList("xiemaoshu","lanchaogou","huahui");
List<String> stringList4 = Arrays.asList("xiemaoshu","lanchaogou","huahui");
List<String> stringList5 = Arrays.asList("xiemaoshu","lanchaogou","huahui");
List<List<String>> allStringList = Arrays.asList(stringList,stringList1,stringList2,stringList3,stringList4,stringList5);
Stream<String> stringStream = allStringList.stream().flatMap(Collection::stream);
stringStream.forEach(System.out::println);
}
排序
方法 | 描述 |
---|
sorted() | 产生一个新流,其中按自然顺序排序 |
sorted(Comparator comp) | 产生一个新流,其中按比较器顺序排序 |
@Test
public void test1() {
List<String> stringList = Arrays.asList("aaa","bbb","qqqqqq","ttttt");
Stream<String> employeeStream = stringList.stream().sorted();
employeeStream.forEach(System.out::println);
List<Employee> employeeList = Arrays.asList(
new Employee("xiemaoshu", 23, 5000.0),
new Employee("lanchaogou", 23, 10000.0),
new Employee("xxx", 30, 3000.0),
new Employee("yyy", 40, 2000.0)
);
Stream<Employee> sorted = employeeList.stream().sorted((emp1, emp2) -> {
return -emp1.getAge() - emp2.getAge();
});
sorted.forEach(System.out::println);
}