22Java基础之Stream流

Stream流

什么是Stream?

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

案例:体验Stream流
需求:
image

  • 把集合中所有以“张”开头,且是三个字的元素存储到一个新集合中。

案例代码

//目标:了解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流的使用步骤
image

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);
    }
}

  1. 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;

    @Override
    public int compareTo(Movie o) {
        return Double.compare(this.score, o.score);
    }

    @Override
    public 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);
    }

    @Override
    public 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);
    }
}
posted @ 2025-09-04 17:07  狂风将军  阅读(43)  评论(0)    收藏  举报