Stream流
区别于IO流,Stream流是jdk1.8的新东西,用来对容器(集合,数组)操作进行书写简化,配合众多函数式接口以及lambda表达式,方法引用,集合的遍历,计数,过滤,映射,截取等操作变得异常优雅,上流。以往对集合的操作最简单的如遍历就是用for循环,函数式编程思想的引入,使得我们对这一遍历的实现操作有了新的认识,遍历取出每个元素是我们的目的,而for循环从1到最后取只是手段,在函数式编程注重行为而非过程的思想下,引入Stream流来简化对集合,数组的遍历等操作。
获取Stream流
- 集合对象的stream()方法:
//Stream类在java.util.stream.Stream下
//List
ArrayList<String> al = new ArrayList<>();
Stream<String> stream1 = al.stream();
//Set
HashSet<String> hs = new HashSet<>();
Stream<String> stream2 = hs.stream();
//map集合不符合集合元素单一的特点所以要分开key,value或者EntrySet获取
Map<String,String> map = new HashMap<>();
Set<String> keySet = map.keySet();
Collection<String> values = map.values();
Set<Entry<String,String>> entrySet = map.entrySet();
Stream<String> stream3 = keySet.stream();
...
- 数组通过Stream类的静态方法of()获取流
int[] a = new int{1,2,3,4,5};
Stream<Integer> stream = Stream.of(a);
//接受可变参数,可直接传数
Stream<String> stream = Stream.of("a","b","c");
常用操作
流对象包含的方法众多,分成两类:
- 非终结方法:这类方法返回一个和调用对像同类型的新的流对象(而非调用者本身),所以可以链式调用。
- 终结方法:返回类型不再是Strea类型,所以不能链式调用
- 遍历:stream.forEach()
void forEach(Consumer<? super T> action)
Consumer接口接收一个T类型或其子类型或对象作为唯一成员函数accept()的参数,在函数内执行操作
List<String> list = new ArrayList<String>();
Stream<String> stream1 = list.stream();
list.add("张山");
list.add("李斯");
list.add("王武");
//一句搞定,foreach的参数是一个Consumer接口,所以forEach当然包含
//但不仅限于遍历,这里只是将action即接口的函数get()定义为
//将接收到的每个列表元素输出从而达到遍历的效果。
stream1.forEach(System.out::println);
- 过滤:stream.filter()
Stream filter(Predicate<? super T> predicate)
List<String> list = new ArrayList<String>();
Stream<String> stream2 = list.stream();
list.add("张山");
list.add("李斯");
list.add("王武");
list.add("张飞");
list.add("张恒九");
//将张性名字出来并打印出来,链式调用
stream2.filter((s)>s.startsWith("张")).forEach(System.out::println);
//筛选也可以进行多次
stream1.filter(s->s.startsWith("张")).filter(s->s.length()<3).forEach(System.out::println);
- 映射:stream.map()
< R> Stream map(Function<? super T,? extends R> mapper)
List<String> list2 = new ArrayList<String>();
Stream<String> stream2 = list2.stream();
list2.add("1");
list2.add("2");
list2.add("3");
list2.add("4");
stream2.map(s>Integer.parseInt(s)).forEach(System.out::println);
- 组合:Stream.concat()
static Stream concat(Stream<? extends T> a,Stream<? extends T> b)
这是一个静态方法
Stream<String> stream1 = Stream.of("lili");
Stream<String> stream2 = stream.of("hehe");
Stream<String> stream3 = Stream.concat(stream1,stream2);
- 统计个数:stream.count()
- 截取:stream.limit()
- 跳过:stream.skip()