Java8中新加入了流(Stream),可以以声明性方式处理数据集合,可以简单的理解成一种新型的遍历数据集的高级迭代器。
流操作有两个重要的特点:
1.流水线------流操作会返回一个流,这样多个操作就可以链接起来,形成一个大的流水线,流水线的操作可以看作对数据源进行数据库式查询。
2.内部迭代------与使用迭代器显式迭代的集合不同,流的迭代操作是在内部进行的。
流操作可以分成两部分,中间操作和终端操作
1、流的创建
Java8提供多种创建流的方式,由值创建,数组创建,文件生成,函数生成,常用的是值创建和数组创建
可以使用静态方法Stream.of,通过显式值创建一个流。
Stream<String> stream = Stream.of("Java8", "10086", "Lambda");
使用empty得到一个空流
Stream<String> emptyStream = Stream.empty();
由数组创建流,使用静态方法Arrays.stream从数组创建一个流
int[] numbers = {2, 4, 23, 15, 30};
int sum = Arrays.stream(numbers).sum();
List<String> strs = Arrays.asList("Java8", "ChongQing", "Hello");
Stream<String> stream = strs.stream();
2、流的中间操作
可以连接起来的流操作称为中间操作,filter、map和limit等可以连成一条流水线,中间操作会返回另一个流。主要的中间操作有filter、distinct、limit、skip、map、sorted等
filter用于设置条件过滤元素,例如筛选出能被2整除的数
List<Integer> numbers = Arrays.asList(1, 2, 4, 3, 5, 4);
numbers.stream().filter(i -> i % 2 == 0).forEach(System.out::println);
//2,4,4
distinct用于设置条件过滤重复元素,例如筛选出能被2整除的数
List<Integer> numbers = Arrays.asList(1, 2, 4, 3, 5, 4);
numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);
//2,4
limit返回不超过给定长度的流
List<Integer> numbers = Arrays.asList(4, 3, 12, 30, 17, 23, 25);
numbers.stream().limit(4).forEach(System.out::println);
//4, 3, 12, 30
skip是扔掉前n个数
List<Integer> numbers = Arrays.asList(4, 3, 12, 30, 17, 23, 25);
numbers.stream().skip(4).forEach(System.out::println);
//17, 23, 25
map用于映射元素到对应的位置
List<Integer> numbers = Arrays.asList(5, 12, 10, 8, 7, 5, 9);
numbers.stream().map( i -> i*2).forEach(System.out::println);
//10,24,20,16,14,10,18
flatMap可以使流扁平化,把一个流中的每个值都换成另一个流,然后把所有的流连接
起来成为一个流,例如给定列表[1, 2, 3]和列表[3, 4],返回所以数对
List<Integer> numbers1 = Arrays.asList(1, 2, 3);
List<Integer> numbers2 = Arrays.asList(3, 4);
List<int[]> pairs = numbers1.stream().flatMap(i -> numbers2.stream().map(j -> new int[]{i, j})).collect(toList());
sorted 方法用于对流进行排序
List<Integer> numbers = Arrays.asList(5, 4, 4, 13, 7, 8, 15);
numbers.stream().sorted().forEach(System.out::println);
//4,4,5,7,8,13,15
3、流的终端操作
关闭流的操作称为终端操作,终端操作会从流的流水线生成结果。其结果是任何不是流的值
forEach迭代流中的每个数据
count用来统计流中的元素个数
collect就是一个归约操作,可以接受各种做法作为参数,将流中的元素累积成一个汇总结果
另外流的中间操作还提供查找和匹配方法,allMatch、anyMatch、noneMatch、findFirst和findAny方法
参考Java8实战