Stream流的常用方法
Stream流属于管道流,只能被消费(使用)一次
第一个Stream流调用完毕方法,数据就会流转到下一个Stream上
而这时第一个Stream流已经使用完毕,就会关闭了。
所以第一个Stream流就不能再调用方法了。
IllegalStateException:Stream has already been operated upon or closed
映射:map
如果需要将流中的元素映射到另一个流中,可以使用map方法。方法签名:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
复习Function接口
此前已经学习过java.util.stream.Function函数式接口,其中唯一的抽象方法为:
R apply(T t);
这可以将一种T类型转换成为R类型,而这种转换的动作,就成为“映射”。
package day16;
import java.util.stream.Stream;
public class Demo01 {
public static void main(String[] args) {
//获取一个String类型的Stream流
Stream<String> stream = Stream.of("1","2","3","4");
//使用map方法,把字符串类型的证书,转换(映射)为Integer类型的整数
Stream<Integer> stream2 = stream.map((String s)->{
return Integer.parseInt(s);
});
//遍历Stream2流
stream2.forEach(i -> System.out.println(i));
}
}
统计个数:count
Stream流中的常用方法_count:用于统计Stream流中元素的个数。
long count();
count方法是一个终结方法,返回值是一个Long类型的整数。
所以不能再继续调用Stream流中的其他方法了。
package day16;
import java.util.ArrayList;
import java.util.stream.Stream;
public class Stream_Count {
public static void main(String[] args) {
ArrayList<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> stream = list.stream();
long count = stream.count();
System.out.println(count);
}
}
取用前几个:limit
limit方法可以对流进行截取,只取用前几个。方法签名:
Stream<T> limit(long maxSize);
参数是一个long型,如果集合当前长度大于参数则进行截取;否则不进行操作。
limit方法用于截取流中的元素
limit方法是一个延迟方法,只是对流中的元素进行截取,返回的是一个新的流,所以可以继续调用Stream流中的其他方法。
package day16;
import java.util.stream.Stream;
public class Stream_limit {
public static void main(String[] args) {
//获取一个stream流
Integer[] arr = {1,2,3,4,5,6,7};
Stream<Integer> stream = Stream.of(arr);
//使用Limit截取三个元素
Stream<Integer> stream2 = stream.limit(3);
//遍历结果
stream2.forEach(name -> System.out.println(name));
}
}
跳过前几个:skip
如果希望跳过前几个元素,可以使用skip方法获取一个截取之后的新流:
Stream<T> skip(long n);
如果当前流的长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。
package day16;
import java.util.stream.Stream;
public class Stream_skip {
public static void main(String[] args) {
//获取一个stream流
Integer[] arr = {1,2,3,4,5,6,7};
Stream<Integer> stream = Stream.of(arr);
//使用skip创建一个新流
Stream<Integer> stream2 = stream.skip(3);
//遍历stream2
stream2.forEach(name -> System.out.println(name));
}
}
组合:concat
如果有两个流,希望合并成为一个流,那么可以使用Stream接口的静态方法concat:
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
备注:这是一个静态方法,与java.lang.String 当中的concat 方法是不同。
package day16;
import java.util.stream.Stream;
public class Stream_concat {
public static void main(String[] args) {
//创建两个stream流
Integer[] arr = {1,2,3,4,5};
Integer[] arr2 = {6,7,8,9,0};
Stream<Integer> stream = Stream.of(arr);
Stream<Integer> stream2 = Stream.of(arr2);
//使用concat方法组合两个流
Stream<Integer> concat = Stream.concat(stream,stream2);
//遍历concat
concat.forEach(name -> System.out.println(name));
}
}
练习:集合元素处理
题目:
现有两个ArrayList集合存储队伍当中的多个成员名字,要求使用stream流的方法一次完成下面的操作。
- 第一个队伍只要名字为三个字的成员姓名:存储到一个新集合中。
- 第一个队伍筛选之后只要前三个人;存储到一个新集合中
- 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
- 第二个队伍筛选之后不要前两个人;存储到一个新集合中。
- 将两个队伍合并成为一个队伍,存储到一个新集合中。
- 根据姓名创建Person对象,存储到一个新集合中。
- 打印整个队伍的Person对象信息。
package day16;
import java.util.ArrayList;
import java.util.stream.Stream;
public class 练习 {
public static void main(String[] args) {
//第一个队伍
ArrayList<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋冬野");
one.add("苏星河");
one.add("龙傲天");
one.add("李星云");
one.add("李煜");
one.add("庄周");
one.add("李白");
one.add("项羽");
one.add("李清照");
//1. 第一个队伍只要名字为三个字的成员姓名:存储到一个新集合中。
//2. 第一个队伍筛选之后只要前三个人;存储到一个新集合中
Stream<String> oneStream = one.stream().filter(name -> name.length()==3).limit(3);
//第二个队伍
ArrayList<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张三丰");
two.add("张无忌");
two.add("上官纤云");
two.add("弗拉基米尔");
two.add("章鱼哥");
two.add("海绵宝宝");
two.add("李天然");
//1. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
//2. 第二个队伍筛选之后不要前两个人;存储到一个新集合中。
Stream<String> twoStream = two.stream().filter(name -> name.startsWith("张00")).skip(2);
//1. 将两个队伍合并成为一个队伍,存储到一个新集合中。
//2. 根据姓名创建Person对象,存储到一个新集合中。
//3. 打印整个队伍的Person对象信息。
Stream.concat(oneStream,twoStream).map(name->new Person(name)).forEach(p-> System.out.println(p));
}
}