Stream创建

1.通过已有的集合来创建流

public static void main(String[] args) {
        List<String> list = Arrays.asList("html", "css", "javascript", "java", "sql");
        
        Stream<String> stream = list.stream();
    }

2.通过Stream创建流

public static void main(String[] args) {
        Stream<String> stream = Stream.of("html", "css", "javascript", "java", "sql");
    }

Stream中间操作

Stream有很多中间操作,多个中间操作可以连接起来形成一个流水线,每一个中间操作就像流水线上的一个工人,每人工人都可以对流进行加工,加工后得到的结果还是一个流。

filter 方法用于通过设置的条件过滤出元素,举例:

public static void main(String[] args) {
    	// 创建一个list集合
        List<String> list = Arrays.asList("An", "", "ordinary", "collection");
                
        // 使用filter方法过滤掉空字符串
        list.stream().filter(string -> !string.isEmpty()).forEach(System.out::println);
        // 输出结果: An ordinary collection
    }

map 方法用于映射每个元素到对应的结果,举例:

public static void main(String[] args) {
        // 创建一个list集合
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); 
        
        // 使用map输出了元素对应的平方数
        list.stream().map( i -> i*i).forEach(System.out::println);
        // 输出结果: 1 4 9 16 25 36 49 64 81
    }

limit 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素,举例:

public static void main(String[] args) {
        // 创建一个list集合
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        
        // 使用limit方法返回前面3个元素
        list.stream().limit(3).forEach(System.out::println);
        // 输出结果: 1 2 3
        
        // 使用skip方法扔掉后面3个元素
        list.stream().skip(3).forEach(System.out::println);
        // 输出结果: 4 5 6 7 8 9
    }

sorted 方法用于对流进行自然排序,举例:

public static void main(String[] args) {
        // 创建一个list集合
        List<Integer> list = Arrays.asList(5, 6, 8, 1, 7, 4);

        // 使用sorted方法进行自然排序
        list.stream().sorted().forEach(System.out::println);
        // 输出结果: 1 4 5 6 7 8
    }

distinct 主要用来去重,举例:

public static void main(String[] args) {
        // 创建一个list集合
        List<Integer> list = Arrays.asList(5, 4, 6, 8, 1, 1, 7, 9, 4);

        // 使用distinct对元素进行去重
        list.stream().distinct().forEach(System.out::println);
        // 输出结果: 5 4 6 8 1 7 9
    }

Stream最终操作

Stream的中间操作得到的结果还是一个Stream,那么如何把一个Stream转换成我们需要的类型呢?比如计算出流中元素的个数、将流装换成集合等。这就需要最终操作(terminal operation)。

最终操作会消耗流,产生一个最终结果。也就是说,在最终操作之后,不能再次使用流,也不能在使用任何中间操作,否则将抛出异常:

java.lang.IllegalStateException: stream has already been operated upon or closed

forEach方法用来迭代流中的每个数据,举例:

public static void main(String[] args) {
        // 创建一个list集合
        List<String> list = Arrays.asList("a","b","c","d","e","f","g");

        // 使用distinct对元素进行去重
        list.forEach(System.out::println);
        // 输出结果: a b c d e f g
    }

count用来统计流中的元素个数,举例:

public static void main(String[] args) {
        // 创建一个list集合
        List<String> list = Arrays.asList("a","b","c","d","e","f","g");
        
        // 统计
        System.out.println(list.stream().count());
        // 输出结果: 7
    }

collect就是一个归约操作,可以接受各种做法作为参数,将流中的元素累积成一个汇总结果,举例:

public static void main(String[] args) {
        // 创建一个list集合
        List<Integer> list = Arrays.asList(5, 2, 3, 9, 8, 0, 5, 2, 3);

        list = list.stream()
                .filter(integer -> integer > 0) // 去掉小于等于0的整体
                .distinct() // 去重
                .sorted() // 自然排序
                .collect(Collectors.toList()); // 将元素汇总进list列表

        System.out.println(list);
        // 输出结果: [2, 3, 5, 8, 9]
    }

总结

本文介绍了Java 8中的几种用法,分别是Stream创建、中间操作和最终操作。

Stream的创建有两种方式,分别是通过集合类的stream方法、通过Stream的of方法。

Stream的中间操作可以用来处理Stream,中间操作的输入和输出都是Stream,中间操作可以是过滤、转换、排序等。

Stream的最终操作可以将Stream转成其他形式,如计算出流中元素的个数、将流装换成集合、以及元素的遍历等。