Stream流
什么是Stream?
- Stream也叫Stream流,是JDK8开始新增的一套API(java.untl.stream.*),可以用于操作集合或者数组的数据。
- 优势:Steam流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作集合或者数组中的数据,代码更简洁,可读性更好。
案例:体验Stream流
需求:

- 把集合中所有以“张”开头,且是三个字的元素存储到一个新集合中。
案例代码
//目标:了解Stream流
public class StreamTest01 {public static void main(String[] args) {List<String> names = new ArrayList<>();List<String> names2 = new ArrayList<>();names.add("张无忌");names.add("周芷若");names.add("赵敏");names.add("张强");names.add("张三丰");//1.老方法for (String name : names) {
// if(name.charAt(0) == '张' && name.length() == 3){if(name.startsWith("张") && name.length() == 3){names2.add(name);}}System.out.println(names2);//2. Stream流List<String> newlist = names.stream().filter(s->(s.startsWith("张") && s.length() == 3)).collect(Collectors.toUnmodifiableList());System.out.println(newlist);}
}
Stream流的使用步骤

Stream流的常用方法
1. 如何获取Stream流?
- 获取集合的Stream流。
![image]()
- 获取数组的stream流。
![image]()
![image]()
代码案例
//目标:获取Stream流的方式
public class StreamTest02 {public static void main(String[] args) {//1. 获取集合的Stream流:default stream<E> steam()Collection<String> list = new ArrayList<>();Collections.addAll(list,"张无忌", "周芷若", "赵敏", "张强", "张三丰");Stream<String> s1 = list.stream();System.out.println(s1.count());//获取元素个数//2. 获取map集合的Stream流:default Stream<Map.Entry<K,V>> stream()Map<String, Integer> map = new HashMap<>();//a. 获取键流Stream<String> ks = map.keySet().stream();//b. 获取值流Stream<Integer> vs = map.values().stream();//c.获取键值对流Stream<Map.Entry<String, Integer>> kvs = map.entrySet().stream();//3. 获取数组的Stream流String[] names = {"赵敏", "周芷若", "张无忌"};Stream<String> s2 = Arrays.stream(names);Stream<String> s3 = Stream.of(names);}
}
- Stream流常见的中间方法
- 中间方法指的是调用完成后会返回新的stream流,可以继续使用(支持链式编程)。
![image]()
案例
movie类:
@Data // 包含了无参 + get + set + toString + equals + hashCode
@NoArgsConstructor
@AllArgsConstructor
public class Movie implements Comparable<Movie>{private String name;private double score;private String actor;@Overridepublic int compareTo(Movie o) {return Double.compare(this.score, o.score);}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Movie movie = (Movie) o;return Double.compare(score, movie.score) == 0 && Objects.equals(name, movie.name) && Objects.equals(actor, movie.actor);}@Overridepublic int hashCode() {return Objects.hash(name, score, actor);}
}测试类:
//目标掌握Stream流的常用方法
public class StreamTest03 {public static void main(String[] args) {List<String> list = new ArrayList<>();Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山");//1.过滤方法list.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(System.out::println);//2. 准备一个集合,排序List<Movie> movies = new ArrayList<>();movies.add(new Movie("肖申克的救赎", 9.7, "蒂姆罗宾斯"));movies.add(new Movie("霸王别姬", 9.6, "张国荣,张丰毅"));movies.add(new Movie("阿甘正传", 9.5, "汤姆.汉克斯"));movies.add(new Movie("阿甘正传", 9.5, "汤姆.汉克斯"));movies.add(new Movie("阿甘正传", 9.5, "汤姆.汉克斯"));movies.add(new Movie("这个杀手不太冷", 9.4, "刘镇伟"));movies.add(new Movie("泰坦尼克号", 9.3, "詹姆斯.卡梅隆"));movies.add(new Movie("辛德勒的名单", 9.2, "达利欧.斯图尔特"));//集合中如果存储对象,方式一:对象类可以实现Comparable接口,指定比较规则movies.stream().sorted().forEach(System.out::println);System.out.println("--------------------------");
// movies.stream().sorted(Movie::compareTo).forEach(System.out::println);movies.stream().sorted((m1,m2)->Double.compare(m1.getScore(), m2.getScore())).forEach(System.out::println);//3.limit取前几个System.out.println("------------------------");movies.stream().sorted((m1,m2)->Double.compare(m1.getScore(), m2.getScore())).limit(3).forEach(System.out::println);//4.skip跳过前几个System.out.println("------------------------");movies.stream().sorted((m1,m2)->Double.compare(m1.getScore(), m2.getScore())).skip(3).forEach(System.out::println);//5. distinct去重// 注意:去重复需要重写对象类的hashcode和equals方法System.out.println("------------------------");movies.stream().sorted((m1,m2)->Double.compare(m1.getScore(), m2.getScore())).distinct().forEach(System.out::println);//6. map加工方法:把流上的数据加工成新数据。System.out.println("------------------------");movies.stream().map(m->m.getName()+ "==>" + m.getScore()).forEach(System.out::println);// 7.合并流// 把两个流接起来Stream<String> s1 = Stream.of("张三", "楚留香", "西门吹牛", "王五", "刘麻子");Stream<String> s2 = Stream.of("李四", "石管幅");Stream<String> allStream = Stream.concat(s1, s2);allStream.forEach(System.out::println);}
}
3. Stream流常见的终结方法
- 终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了。
![image]()
收集Stream流
- 就是把Stream流操作后的结果转回到集合或者数组中去返回。
- Stream流:方便操作集合/数组的手段;集合/数组:才是开发中的目的。
![image]()
案例
//目标:Stream流的常见终极方法
public class StreamTest4 {public static void main(String[] args) {List<Movie> movies = new ArrayList<>();movies.add(new Movie("肖申克的救赎", 9.7, "蒂姆罗宾斯"));movies.add(new Movie("霸王别姬", 9.6, "张国荣,张丰毅"));movies.add(new Movie("阿甘正传", 9.5, "汤姆.汉克斯"));movies.add(new Movie("这个杀手不太冷", 9.4, "刘镇伟"));//1. forEach遍历movies.stream().forEach(System.out::println);//2.count统计个数System.out.println(movies.stream().count());//3. 取最大值,最小值/* Optional<Movie> max = movies.stream().max((o1, o2) -> Double.compare(o1.getScore(), o2.getScore()));Movie m = max.get();System.out.println(m);*/Movie max = movies.stream().max((o1, o2) -> Double.compare(o1.getScore(), o2.getScore())).get();Movie min = movies.stream().min((o1, o2) -> Double.compare(o1.getScore(), o2.getScore())).get();System.out.println(max);System.out.println(min);// 4. 收集Stream流:把流中的数据恢复到集合或者数组中去。// 收集到List集合中去List<String> names = new ArrayList<>();names.add("张无忌");names.add("周芷若");names.add("赵敏");names.add("张强");names.add("张三丰");names.add("张翠山");Stream<String> stream = names.stream();//流只能用一次,如果需要再次使用,需要重新获取流对象。List<String> newList = stream.filter(n -> n.startsWith("张") && n.length() == 3).collect(Collectors.toList());
// List<String> newList = names.stream().filter(n -> n.startsWith("张") && n.length() == 3).collect(Collectors.toList());System.out.println(newList);//收集到Set集合Stream<String> stream1 = names.stream();Set<String> newSet = stream1.filter(n -> n.startsWith("张") && n.length() == 3).collect(Collectors.toSet());System.out.println(newSet);//收集到数组Stream<String> stream2 = names.stream();Object[] objects = stream2.filter(n -> n.startsWith("张") && n.length() == 3).toArray();// 收到Map集合(拓展)List<Movie> movies1 = new ArrayList<>();movies1.add(new Movie("肖申克的救赎", 9.7, "蒂姆罗宾斯"));movies1.add(new Movie("霸王别姬", 9.6, "张国荣,张丰毅"));movies1.add(new Movie("阿甘正传", 9.5, "汤姆.汉克斯"));movies1.add(new Movie("这个杀手不太冷", 9.4, "刘镇伟"));// Map<String, Double> map = movies1.stream().limit(3).collect(Collectors.toMap(m1->m1.getName(),m2->m2.getScore(), (v1,v2)->v2));Map<String, Double> map = movies1.stream().limit(3).collect(Collectors.toMap(Movie::getName, Movie::getScore));System.out.println(map);}
}






