1、Stream流的定义
Stream是Java中的一个接口。它的作用类似于迭代器,但其功能比迭代器强大,主要用于对数组和集合的操作。
Stream中的流式思想:每一步只操作,不存储。
2、Stream流的获取
可以获取Stream流的有数组和集合。对于数组而言,获取Stream流的方式如下:
代码示例:
//数组变为Stream流
int[] arr={1,2,3,4,5,6,7};
Stream<int[]> stream = Stream.of(arr);
对于集合而言,获取Stream流的方式如下:
代码示例:
//把集合转换为Stream流
List<String> list=new ArrayList<>();
Stream<String> stream1=list.stream();
Set<String> set=new HashSet<>();
Stream<String> stream2=set.stream();
Map<String,Integer> map=new HashMap<>();
//获取键,存储到Set中
Set<String> key_set=map.keySet();
Stream<String> stream3=key_set.stream();
//获取值,存储到collection集合中
Collection<Integer> values=map.values();
Stream<Integer> stream4 = values.stream();
//获取键值对
Set<Map.Entry<String, Integer>> entries = map.entrySet();
Stream<Map.Entry<String, Integer>> stream5 = entries.stream();
3、对于Stream流进行操作的方法
当数组和集合转化为Stream流之后,可以直接使用Stream流中定义好的方法对于原始的数组和集合进行遍历和过滤等一系列操作,从而使其更加简洁方便。Stream 流自身可以调用的方法大致可以分为两类:
(1)终结方法:返回值不再是stream接口自身类型的方法。
(2)延迟方法:stream流调用该类方法后得到的返回值还是一个Stream流,
故而使用此类方法可以实现链式调用。
3.1、终结方法
3.1.1、forEach方法
该方法的具体定义如下:void forEach(Consumer<? super T> action);
关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.
在此处只对其功能做简要介绍。
该方法的主要作用是:对流中的元素进行遍历。
代码示例:
public static void main(String[] args) {
//获取Stream流
Stream<String> stream = Stream.of("jay","jj","vae");
//使用Stream流的方法forEach对流进行遍历
stream.forEach((String name)->{
System.out.println(name);//输出结果:jay,jj,vae
});
}
此处对于函数式接口Consume的实现采用的是lambda表达式方法,以下再次出现时就不在重复介绍。
3.1.2、count方法
该方法的具体定义如下:long count();
该方法的主要作用是:对流中的元素的总个数进行统计。
代码示例:
public static void main(String[] args) {
//获取一个Stream流
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
Stream<Integer> stream1 = list.stream();
long count1 = stream1.count();
System.out.println(count1);//输出结果为:7
}
3.2、延迟方法
该类方法的最重要的一个性质就是可以进行链式调用,提升数据处理效率。
3.2.1、filter方法
该方法的具体定义如下: Stream filter(Predicate<? super T> predicate);
关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.
在此处只对其功能做简要介绍。
该方法的主要作用是:对流中的元素按照某种规则进行筛选后得到一个新的流。其功能等价于一个for循环语句+一个条件判断语句。
代码示例:
public static void main(String[] args) {
//创建一个流
Stream<String> stream = Stream.of("朱元璋", "李世民", "张三丰", "周芷若", "赵敏");
//对流中的元素进行过滤,只要姓张的
Stream<String> stream2 = stream.filter((String name)->{
return name.startsWith("张");
});
stream2.forEach((name)->{
System.out.println(name);//输出结果:"张三丰"
});
}
3.2.2、concat方法
该方法的具体定义如下: Stream concat(Stream<? extends T> a, Stream<? extends T> b)
该方法的主要作用是:将两个Stream流整合为一个Stream流。
代码示例:
public static void main(String[] args) {
Map<String,String> map=new HashMap<>();
map.put("张无忌","赵敏");
map.put("宋青书","周芷若");
map.put("灭绝师太","圆空");
map.put("黄晓明","章金莱");
map.put("孙悟空","白骨精");
map.put("猪八戒","嫦娥");
Set<String> setKey = map.keySet();
Collection<String> values = map.values();
Stream<String> stream1 = setKey.stream();
Stream<String> stream2 = values.stream();
Stream<String> concatStream = Stream.concat(stream1, stream2);
concatStream.forEach((s)->{
System.out.println(s);//输出结果过长,就不再一一赘述
});
3.2.3、map方法
该方法的具体定义如下:Stream map(Function<? super T, ? extends R> mapper);
关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.
在此处只对其功能做简要介绍。
该方法的主要作用是:将一个流中的元素映射到另一个流中。
代码示例:
public static void main(String[] args) {
//获取Stream流
Stream<String> stringStream = Stream.of("1", "2", "3", "4");
//使用map方法,将字符串类型转化为int型
Stream<Integer> stream=stringStream.map((String s)->{
return Integer.parseInt(s);
});
stream.forEach((i)->{
System.out.println(i);
});
}
3.2.4、limit方法
该方法的具体定义如下: Stream limit(long maxSize);
该方法的主要作用是:用于截取给定Stream流中的元素,从而形成一个新的流。
代码示例:
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("李");
list.add("张");
list.add("许");
list.add("王");
list.add("朱");
Stream<String> stream = list.stream();
//limit方法
Stream<String> limitStream = stream.limit(3);
limitStream.forEach((s)->{
System.out.println(s);//输出结果:李、张、王
});
}
3.2.5、skip方法
该方法的具体定义如下: Stream skip(long maxSize);
该方法的主要作用是:用于跳过给定Stream流中前几个元素,从而形成一个新的流。
代码示例:
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("李");
list.add("张");
list.add("许");
list.add("王");
list.add("朱");
Stream<String> stream = list.stream();
//skip方法
Stream<String> skipStream = stream.skip(3);
try{
skipStream.forEach((s1)->{
System.out.println(s1);//输出结果:王、朱
});
}catch (Exception e){
e.printStackTrace();
}
}
4、总结
Stream流主要是对于集合和数组的遍历操作做了一系列改进。
将集合和数组转化为stream流后,结合stream中已经定义好的各种方法,可以更加简洁的对于数组和结合中的元素进行操作。
当以后需要遍历一个集合和数组之前,不妨想想使用stream流会不会更合适。