在 JDK 1.8 中,得益于 Lambda 表达式所带来的函数式编程,引入了一个全新的 Stream 概念,用于解决已有集合类库既有的弊端。
我们需要筛选出集合中元素包含“叁”的元素,但是我们却遍历了元素集合,这无疑是累赘的。
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
List<String> tempList = new ArrayList<>();
for (String name : list) {
if (name.contains("叁")) {
tempList.add(name);
}
}
for (String s : tempList) {
System.out.println(s);
}
}
}
下述代码中并没有体现出遍历操作,我们可以更好地体现做什么而不是怎么做。
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
// :: 方法引用,如果已有方法能够完成函数式接口中的功能,就可以使用方法引用替换 Lambda
list.stream().filter(s -> s.contains("叁")).forEach(System.out::println);
}
}
Stream 是 JDK 1.8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用 Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。Stream 有如下特点: ♞ 不是数据结构,不会保存数据。 ♞ 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。 ♞ 惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。 Stream 就像是流水线上生产的产品,直到最后一步才会生成成品。
collection 集合可以通过 stream( ) 默认方法获取流
public class Demo {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.add("壹");
collection.add("贰");
collection.add("叁");
collection.add("肆");
collection.add("伍");
Stream<String> stream = collection.stream();
}
}
数组通过 Stream 接口的静态方法 of( ) 获取流,基本数据类型数组不能使用 Stream.of( )。
public class Demo {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5};
Stream<Integer> stream = Stream.of(array);
}
}
操作符就是对数据进行的一种处理工作,一道加工程序;就好像工厂的工人对流水线上的产品进行一道加工程序一样。Stream 的操作符分为两种:中间操作符和终止操作符。
操作符 | 说明 |
---|---|
map( ) | 转换操作 |
limit( ) | 限流操作 |
distint( ) | 去重操作 |
filter( ) | 过滤操作 |
peek( ) | 挑出操作 |
skip( ) | 跳过操作 |
sorted( ) | 排序操作 |
concat( ) | 合并操作 |
转换操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
Stream.of(array).map(s -> Integer.parseInt(s))
.forEach(s -> System.out.println(s + "的类型是:" + s.getClass().getName()));
}
}
限流操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
Stream.of(array).limit(3).forEach(System.out::println);
}
}
去重操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "1", "1"};
Stream.of(array).distinct().forEach(System.out::println);
}
}
过滤操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "1", "1"};
Stream.of(array).filter(s -> !"1".equals(s)).forEach(System.out::println);
}
}
挑出操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
Stream.of(array).skip(3).peek(s -> System.out.println("peek --- " + s)).forEach(System.out::println);
}
}
跳过操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
Stream.of(array).skip(3).forEach(System.out::println);
}
}
排序操作
public class Demo {
public static void main(String[] args) {
String[] array = {"5", "2", "6", "1", "4"};
Stream.of(array).sorted().forEach(System.out::println);
}
}
合并操作
合并操作两个流的数据类型要一致
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
Stream.concat(Stream.of(array), list.stream()).forEach(System.out::println);
}
}
终止操作符就是用来对数据进行收集或者消费的,数据到了终止操作这里就不会向下流动了,终止操作符只能使用一次。
操作符 | 说明 |
---|---|
count | 统计操作 |
forEach | 遍历操作 |
toArray | 数组操作 |
统计操作
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
long count = list.stream().filter(s -> !"叁".equals(s)).count();
System.out.println(count);
}
}
遍历操作
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
list.stream().filter(s -> !"叁".equals(s)).forEach(System.out::println);
}
}
数组操作
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
Object[] objects = list.stream().filter(s -> !"叁".equals(s)).toArray();
System.out.println(Arrays.toString(objects));
}
}
每个 Stream 流只能使用一次 Stream 流必须使用 终止操作符 否则不会有输出