1 引言 Stream流是可以用于解决已有集合/数组类库有的弊端,Stream的作用是把集合转换成一个传送带,借用Stream流的强大功能进行的操作,而这个强大的功能的经典API将在此文中展示,最
1 引言
Stream流是可以用于解决已有集合/数组类库有的弊端,Stream的作用是把集合转换成一个传送带,借用Stream流的强大功能进行的操作,而这个强大的功能的经典API将在此文中展示,最终流形式操作完毕以后还是要收集成集合,类比于工厂流水线,进行一道工序后可以接着进行下一道工序,直至形成一个个产品。
2 如何获取Stream流?
2.1 Collection集合如何获取Stream流
内容:调用stream()即可,List也可用这个方式
代码
Collection<String> c = new ArrayList<>();
Stream<String> ss = c.stream();
2.2 Map获取Stream流
内容:调用.stream()
代码
Map<String,Integer> map = new HashMap<>();
//先获取键的Stream流
Stream<String> keys = map.keySet().stream();
//获取值的Stream流
Stream<Integer> values =map.values().stream();
//获取键值对的流
Stream<Map.Entry<String, Integer>> keyAndValues = map.entrySet().stream();
2.3 数组获取流
内容:两种方式
- Arrays.stream(arr)
- Stream.of(arr)
代码
String[] arrs = new String[]{"Java","JavaEE","Spring Boot"};
Stream<String> arrstream = Arrays.stream(arrs);
Stream<String> arrstream2 = Stream.of(arrs);
3 如何使用Stream流?
3.1 filter
内容:进行条件的筛选
代码
List<String> lists = new ArrayList<>();
lists.add("赵敏");
lists.add("小昭");
lists.add("殷素素");
lists.add("周芷若");
lists.add("张无忌");
lists.add("张三丰");
//1.filter
//中间的lambda表达式原来是个匿名内部类,Predicate是一个函数接口
lists.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length()==3;
}
});
//简化一下
lists.stream().filter((String s) ->{
return s.length()==3;
});
//继续简化:简化return,大括号,分号,参数类型,参数小括号,以后用直接背,括号中,s打个箭头,然后跟上条件,香
lists.stream().filter(s -> s.length()==3);
//可以多重处理,再来个filter
lists.stream().filter(s->s.length()==3).filter(s->s.startsWith("张"))
.forEach(System.out::println);//遍历下,然后方法引用
3.2 count
内容:计数
代码
long count = lists.stream().filter(s->s.length()==3).filter(s->s.startsWith("张"))
.count();
System.out.println(count);
3.3 limit
内容:取前几个
代码
//limit取前几个,找长度为3的前两个
lists.stream().filter(s->s.length()==3 ).limit(2)
.forEach(System.out::println);
3.4 skip
内容:跳过几个
代码
//4.跳过前两个
lists.stream().filter(s->s.length()==3 ).skip(2)
.forEach(System.out::println);
3.5 map
内容:(映射),把原来的元素加工后,重新放上去
代码
//需求:把名字都加上“倚天屠龙记的:+xxx”
lists.stream().map(s->"倚天屠龙记的"+s)
.forEach(System.out::println);
//需求:把名字都加工成学生对象放上去!
lists.stream().map(s-> new Student(s))
.forEach(System.out::println);
//构造器引用可以再装一下
lists.stream().map(Student::new)
.forEach(System.out::println);
3.6 合并流
内容:把流两两合并
代码
//数组流
Stream<Integer> s1 = Stream.of(10,20,30,40);//Stream本身就是一个整体,相当与充当一个数组
//集合流
Stream<String> s2 = lists.stream();
//合并流:两两合并
Stream<Object> allStream = Stream.concat(s1,s2);//concat是静态方法,用类调,合并不一样类型的用Object接
allStream.forEach(System.out::println);
4 如何将流收回集合?
内容:需要注意流收回成集合后不能在重复收集,否则会程序会挂起
代码
List<String> lists = new ArrayList<>();
lists.add("赵敏");
lists.add("小昭");
lists.add("殷素素");
lists.add("周芷若");
lists.add("张无忌");
lists.add("张三丰");
lists.add("张三丰");
Stream<String> zhangLists = lists.stream().filter(s->s.startsWith("张"));
//把Stream流转换成Set集合
Set<String> sets = zhangLists.collect(Collectors.toSet());
System.out.println(sets);//set是不重复的
//把Stream流转换成List集合
Stream<String> zhangLists1 = lists.stream().filter(s->s.startsWith("张"));//再来一个新的流
List<String> list = zhangLists1.collect(Collectors.toList());
System.out.println(list);//会报错,挂起,原因是set已经把水管里的水给取完了
//把Stream转成数组
Stream<String> zhangLists2 = lists.stream().filter(s->s.startsWith("张"));//再来一个新的流
Object[] arrs = zhangLists2.toArray();//直接转数组
//硬要是String接数组,可以借用构造器引用申明转换成的数组类型
String[] arrs1 = zhangLists2.toArray(String[]::new);