今天我们来学习一下Java 8 的新特新—>Stream流;
Stream流
stream流是Java8的新特性,它也是有关于集合的新api;
Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作;
Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性;
下面我们用一个例子来引入Stream流的操作:
Stream流的数据操作特性
这里有一个集合
List<Integer> list = Arrays.asList(1,2,3,4,5);
我们要写一个方法找偶数,返回一个新的list包含结果;
用我们以前的方法做的话就会比较繁琐:
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,3,4,5);
System.out.println(exec(list, new Predicate<Integer>(){
@Override
public boolean test(Integer i) {
return i % 2 == 0;
}
}));
//System.out.println(exec(list, i -> i % 2 == 0));
}
// 设计模式中,策略模式
public static List<Integer> exec(List<Integer> list, Predicate<Integer> predicate) {
List<Integer> list2 = new ArrayList<>();
for(Integer i :list) {
if(predicate.test(i)) {
list2.add(i);
}
}
return list2;
}
在这里我们使用了设计模式中的策略模式,将它的处理方法拿出来,可以对它的使用方法进行主动的编写,同时我们用了一个新的模式Predicate,这个模式叫做断言模式,顾名思义就是对我们要进行的处理进行断言操作,断定它能进行的功能;比如上面的例子就是我们求出了list集合中所有的偶数,那我们如果不想对他进行求偶操作呢?比如我们想求出集合中所有大于三的数据呢?
这个时候我们就可以改变这个断言,重新写入想要的操作;
System.out.println(exec(list, new Predicate<Integer>(){
@Override
public boolean test(Integer i) {
return i >3;
}
在不用断言模式的时候,我们甚至需要新写一个方法,然后调用它,有了断言模式,我们就可以主动的给exec这个方法传入我们想要的策略;
甚至我们可以对断言进行简写;即lambda表达式;
这里我们可以看到这个接口是一个函数式接口,就是单方法接口;所以我们完全可以用lambda表达式给他写入断言;
System.out.println(exec(list,i -> i % 2 == 0);
System.out.println(exec(list,i -> i > 3);
用了lambda表达式就大大减少了我们的代码量;
可是这也是比较麻烦的 ;而且在之前我们遍历集合的时候就需要循环,或者 Iterator 迭代器来遍历;这也都是很浪费时间和空间的;
那有没有一种方法,是我们不用调用方法,直接用语句来获得所有的偶数呢?这个时候我们就需要用到jdk1.8的新特性,Stream流,将数组元素变为一条数据流,然后对这个数据流进行操作,过滤或者收集想要的数据;
- 特点:
-
Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。
-
Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。
-
Stream 的数据源本身可以是无限的。
Stream()类的方法
- filter (过滤器)
这个过滤器的方法就是对流中的数据一个一个的进行筛选,看看它是不是符合规则,如果不符合就拦截住,也就是舍弃,如果符合要求,则让他通过,进行下一步的操作,说白了就像一个滤网一样,我们可以设置过滤的规则,然后它对数据流进行筛选;
比如上面的例子来说我们就可以用这样的方法;
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
List<Integer> stream = list.stream().filter( i