**
Stream
**
前面写了那么多关于I/O流的操作,我们不妨想一下,既然可以把数据变成‘流’的形式输入输出,那么我们可不可以直接把所要做的操作(当然包括输入输出)都变成流的形式呢?Stream接口实现了这样的想法。
Stream属于管道流,只能被使用一次,一个stream流使用完数据就流到下一个stream上,前一个流就关闭了。
这样说可能比较抽象,我们直接看一下使用Stream和不使用Stream的区别。
现在有一个存储了一些人名的集合,要想把集合里面姓张的并且三个字的姓名筛选出来,先是我们已经知道的做法:
List<String> list=new ArrayList<>();
Collections.addAll(list,"张无忌","灭绝师太","张三丰","周芷若");
//使用一般的循环找出姓张且三个字的人名
List<String> list2=new ArrayList<>();
for(String s:list)
{
if(s.startsWith("张"))
{
list2.add(s);
}
}
List<String> list3=new ArrayList<>();
for(String s:list2)
{
if(s.length()==3)
{
list3.add(s);
}
}
System.out.println(list3);
结果
[张无忌, 张三丰]
现在使用流来完成这个操作
list.stream().filter(name->name.startsWith("张")).filter((String name)->name.length()==3).forEach((String name)->System.out.println(name));
//把集合变成流 第一次过滤,使用Lambda表达式 第二次过滤,使用Lambda表达式 输出
结果
张无忌
张三丰
代码是不是一下子变得更加的简洁!下面来看一下Stream的详细用法。
把数组或者集合转换为流:
单列集合
List<String> list4=new ArrayList<>();
Stream<String> stream1=list4.stream();//List与Set直接使用方法就可以
双列集合(注:双列集合不可以直接转换为Stream,所以我们要把Key与Value转换为两个流)
Map<String,String> map=new HashMap<>();
Set<String> set=map.keySet();//把key储存到Set集合中
Stream<String> stream2=set.stream();
Collection<String> values=map.values();//把value储存到Collection集合中
Stream<String> stream3=values.stream();
//key与value分别成为了流
数组:
Stream<Integer> stream4=Stream.of(1,2,3,4,5);//of是一个静态方法,可以传递可变的参数
int[] array=new int[10];
Stream<int[]> stream5=Stream.of(array);
有了一个Stream对象,我们现在来使用它
Stream中两种方法:
延迟方法:返回值类型仍然是Stream接口自身类型的方法,支持链式调用
终结方法:返回值类型不在是Stream接口自身类型的方法,不支持链式调用
终结方法:forEach方法,用来遍历流中的数据,该方法接收一个Consumer函数接口,所以可以使用Lambda表达式
Stream<String> stream6=Stream.of("gfx","zbh","ycj","jyh");
stream6.forEach((String name)->{System.out.println(name);});
结果
gfx
zbh
ycj
jyh
延迟方法:filter方法,满足条件的元素返回true保留在集合中。该方法接收一个Predicate函数接口,所以可以使用Lambda表达式
Stream<String> stream7=Stream.of("张无忌","灭绝师太","张三丰","周芷若","张翠花");
stream7.filter((String name)->{return name.startsWith("张");}).forEach((String name)->{System.out.println(name);});
结果
张无忌
张三丰
张翠花
延迟方法:map方法,把一个流中的元素映射到另外一个流中。该方法接收一个Function函数接口,所以可以使用Lambda表达式
Stream<String> stream9=Stream.of("1","2","3","4","5");
stream9.map((String s)->{return Integer.parseInt(s);}).forEach((Integer num)->{System.out.println(num);});
结果
1
2
3
4
5
终结方法:count方法,用来数集合中的元素个数
Stream<String> stream11=Stream.of("1","2","3","4","5","6");
System.out.println("集合中的元素有:"+stream11.count()+"个");
结果
集合中的元素有:6个
延迟方法:limit方法,对流中的元素进行截取,该方法接收一个long类型的整数
Stream<String> stream12=Stream.of("1","2","3","4","5","6");
stream12.limit(2).forEach((String name)->{System.out.print(name);});
结果
12
延迟方法:skip方法,跳过流中前n个元素,该方法接收一个long类型的整数
Stream<String> stream13=Stream.of("1","2","3","4","5","6");
stream13.skip(2).forEach((String name)->{System.out.print(name);});
结果
3456
延迟方法:concat方法,合并两个流为一个
Stream<String> stream14=Stream.of("张无忌","灭绝师太");
Stream<String> stream15=Stream.of("张三丰","周芷若","张翠花");
Stream<String> stream16=Stream.concat(stream14, stream15);
stream16.forEach((String name)->{System.out.println(name);});
结果
张无忌
灭绝师太
张三丰
周芷若
张翠花