在开始java实例之前,先了解以下stream流,不过最终想要理解stream流是干什么的,最好还是得结合代码来自行理解!
1.什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
- 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
- Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
- 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
2、如何使用Stream流?
操作三个步骤
1、创建流
2、中间操作
3、终止操作
3、一个java实例
package com.test;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class myTest {
public static void main(String[] args) {
//--------------------------实例1--------------------------
//创建一个stream流
List<String> listStream = Arrays.asList("1", "2", "3");
//利用stream流的filter方法!!筛选出集合中不等于字符串2的数据,并且打印(System.out :: println为打印所有数据)
listStream.stream().filter(s -> s != "2").forEach(System.out::println);// "1" "3"
//--------------------------实例2--------------------------
//创建一个stream流
Stream<Integer> stream = Stream.of(6, 4, 6, 7, 3, 9, 8, 10, 12, 14, 14);
Stream<Integer> newStream = stream.filter(s -> s > 5) //过滤 -> 6 6 7 9 8 10 12 14 14
.distinct() //去重 -> 6 7 9 8 10 12 14
.skip(2) // 去掉最前面的两个 -> 9 8 10 12 14
.limit(2); // 只要2个数据 -> 9 8
newStream.forEach(System.out::println);
}
}
上面的代码只是举了个例子,假如你对stream还不是很清楚,博主建议各位自己创建test类,试写以下,时间空余的话常用的stream流的方法都可以试一下!
结尾(附两张图,包含了Stream的方法以及方法对应的例子)
流方法 | 含义 | 示例 |
filter | (中间操作)该操作会接受一个谓词(一个返回boolean的函数)作为参数,并返回一个包括所有符合谓词的元素的流。 | List<Dish> vegetarianMenu = menu.stream() .filter(Dish::isVegetarian) .collect(toList()); System.out.println(vegetarianMenu); |
distinct | (中间操作)返回一个元素各异(根据流所生成元素的hashCode和equals方法实现)的流。 | List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); numbers.stream() .filter(i -> i % 2 == 0) .distinct() .forEach(System.out::println); |
limit | (中间操作)会返回一个不超过给定长度的流。 | List<Dish> dishes = menu.stream() .filter(d -> d.getCalories() > 300) .limit(3) .collect(toList()); System.out.println(dishes); |
skip | (中间操作)返回一个扔掉了前n个元素的流。 | List<Dish> dishes = menu.stream() .filter(d -> d.getCalories() > 300) .skip(2) .collect(toList()); System.out.println(dishes); |
map | (中间操作)接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素(使用映射一词,是因为它和转换类似,但其中的细微差别在于它是“创建一个新版本”而不是去“修改”)。 | List<String> dishNames = menu.stream() .map(Dish::getName) .collect(toList()); System.out.println(dishNames); |
flatMap | (中间操作)使用flatMap方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用map(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流。 | List<String> words = Arrays.asList("Goodbye", "World"); List<String> uniqueCharacters = words.stream() .map(w -> w.split("")) .flatMap(Arrays::stream) .distinct() .collect(Collectors.toList()); System.out.println(uniqueCharacters); |
sorted | (中间操作)返回排序后的流 | List<String> traderStr = menu.stream() .map(transaction -> transaction.getName()) .sorted() .collect(toList()); System.out.println(traderStr); |
anyMatch | (终端操作)可以回答“流中是否有一个元素能匹配给定的谓词”。 | if (menu.stream().anyMatch(Dish::isVegetarian)) { System.out.println("The menu is (somewhat) vegetarian friendly!!"); } |
allMatch | (终端操作)会看看流中的元素是否都能匹配给定的谓词。 | boolean isHealthy = menu.stream() .allMatch(d -> d.getCalories() < 1000); System.out.println(isHealthy); |
noneMatch | (终端操作)可以确保流中没有任何元素与给定的谓词匹配。 | boolean isHealthy = menu.stream() .noneMatch(d -> d.getCalories() >= 1000); System.out.println(isHealthy); |
findAny | (终端操作)将返回当前流中的任意元素。 | Optional<Dish> dish = menu.stream() .filter(Dish::isVegetarian) .findAny(); System.out.println(dish); |
findFirst | (终端操作)有些流有一个出现顺序(encounter order)来指定流中项目出现的逻辑顺序(比如由List或排序好的数据列生成的流)。对于这种流,可能想要找到第一个元素。 | List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5); Optional<Integer> firstSquareDivisibleByThree = someNumbers.stream() .map(x -> x * x) .filter(x -> x % 3 == 0) .findFirst(); System.out.println(firstSquareDivisibleByThree); |
forEach | (终端操作)遍历流 | List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); numbers.stream() .filter(i -> i % 2 == 0) .distinct() .forEach(System.out::println); |
collect | (终端操作)收集器 | List<String> traderStr = menu.stream() .map(transaction -> transaction.getName()) .sorted() .collect(toList()); |
reduce | (终端操作)归约reduce接受两个参数: •一个初始值,这里是0; •一个BinaryOperator<T>来将两个元素结合起来产生一个新值,这里我们用的是lambda (a, b) -> a + b。 | List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); int sum = numbers.stream().reduce(0, (a, b) -> a + b); System.out.println(sum); |
count | (终端操作)返回此流中元素的计数。 | long evenNumbers = IntStream.rangeClosed(1, 100) .filter(n -> n % 2 == 0) .count(); System.out.println(evenNumbers); |