• JAVA8 Stream集合操作:中间方法和完结方法


    Stream
    Lambda为java8带了闭包,这一特性在集合操作中尤为重要:java8中支持对集合对象的stream进行函数式操作,此外,stream api也被集成进了collection api,允许对集合对象进行批量操作。
    下面我们来认识Stream。
    Stream表示数据流,它没有数据结构,本身也不存储元素,其操作也不会改变源Stream,而是生成新Stream.作为一种操作数据的接口,它提供了过滤、排序、映射、规约等多种操作方法,这些方法按照返回类型被分为两类:凡是返回Stream类型的方法,称之为中间方法(中间操作),其余的都是完结方法(完结操作)。完结方法返回一个某种类型的值,而中间方法则返回新的Stream。中间方法的调用通常是链式的,该过程会形成一个管道,当完结方法被调用时会导致立即从管道中消费值,这里我们要记住:Stream的操作尽可能以“延迟”的方式运行,也就是我们常说的“懒操作”,这样有助于减少资源占用,提高性能。对于所有的中间操作(除sorted外)都是运行在延迟模式下。

    Stream不但提供了强大的数据操作能力,更重要的是Stream既支持串行也支持并行,并行使得Stream在多核处理器上有着更好的性能。

    Stream的使用过程有着固定的模式:


    创建Stream
    通过中间操作,对原始Stream进行“变化”并生成新的Stream
    使用完结操作,生成最终结果
    也就是
    创建——>变化——>完结


    Stream的创建

    对于集合来说,可以通过调用集合的stream()或者parallelStream()来创建,另外这两个方法也在Collection接口中实现了。对于数组来说,可以通过Stream的静态方法of(T … values)来创建,另外,Arrays也提供了有关stream的支持。
    除了以上基于集合或者数组来创建Stream,也可以通过Steam.empty()创建空的Stream,或者利用Stream的generate()来创建无穷的Stream。
    下面我们以串行Stream为例,分别说明Stream几种常用的中间方法和完结方法。首先创建一个List集合:

    List<String> lists=new ArrayList<String >();
            lists.add("a1");
            lists.add("a2");
            lists.add("b1");
            lists.add("b2");
            lists.add("b3");
            lists.add("o1");

    中间方法:

    过滤器(Filter)

    结合Predicate接口,Filter对流对象中的所有元素进行过滤,该操作是一个中间操作,这意味着你可以在操作返回结果的基础上进行其他操作。

    public static void streamFilterTest() {
            lists.stream().filter((s -> s.startsWith("a"))).forEach(System.out::println);
    
            //等价于以上操作
            Predicate<String> predicate = (s) -> s.startsWith("a");
            lists.stream().filter(predicate).forEach(System.out::println);
    
            //连续过滤
            Predicate<String> predicate1 = (s -> s.endsWith("1"));
            lists.stream().filter(predicate).filter(predicate1).forEach(System.out::println);
    }

    排序(Sorted)

    结合Comparator接口,该操作返回一个排序过后的流的视图,原始流的顺序不会改变。通过Comparator来指定排序规则,默认是按照自然顺序排序。

    public static void streamSortedTest() {
            System.out.println("默认Comparator");
            lists.stream().sorted().filter((s -> s.startsWith("a"))).forEach(System.out::println);
    
            System.out.println("自定义Comparator");
            lists.stream().sorted((p1, p2) -> p2.compareTo(p1)).filter((s -> s.startsWith("a"))).forEach(System.out::println);
    
    }

    映射(Map)

    结合Function接口,该操作能将流对象中的每个元素映射为另一种元素,实现元素类型的转换。

    public static void streamMapTest() {
            lists.stream().map(String::toUpperCase).sorted((a, b) -> b.compareTo(a)).forEach(System.out::println);
    
            System.out.println("自定义映射规则");
            Function<String, String> function = (p) -> {
                return p + ".txt";
            };
            lists.stream().map(String::toUpperCase).map(function).sorted((a, b) -> b.compareTo(a)).forEach(System.out::println);
    
    }

    在上面简单介绍了三种常用的操作,这三种操作极大简化了集合的处理。接下来,介绍几种完结方法:

    完结方法

    “变换”过程之后,需要获取结果,即完成操作。下面我们来看相关的操作:


    匹配(Match)

    用来判断某个predicate是否和流对象相匹配,最终返回Boolean类型结果,例如:

    public static void streamMatchTest() {
            //流对象中只要有一个元素匹配就返回true
            boolean anyStartWithA = lists.stream().anyMatch((s -> s.startsWith("a")));
            System.out.println(anyStartWithA);
            //流对象中每个元素都匹配就返回true
            boolean allStartWithA
                    = lists.stream().allMatch((s -> s.startsWith("a")));
            System.out.println(allStartWithA);
    }

    收集(Collect)

    在对经过变换之后,我们将变换的Stream的元素收集,比如将这些元素存至集合中,此时便可以使用Stream提供的collect方法,例如:

    public static void streamCollectTest() {
            List<String> list = lists.stream().filter((p) -> p.startsWith("a")).sorted().collect(Collectors.toList());
            System.out.println(list);
    
    }

    计数(Count)

    类似sql的count,用来统计流中元素的总数,例如:

    public static void streamCountTest() {
            long count = lists.stream().filter((s -> s.startsWith("a"))).count();
            System.out.println(count);
    }

    规约(Reduce)

    reduce方法允许我们用自己的方式去计算元素或者将一个Stream中的元素以某种规律关联,例如:

    public static void streamReduceTest() {
            Optional<String> optional = lists.stream().sorted().reduce((s1, s2) -> {
                System.out.println(s1 + "|" + s2);
                return s1 + "|" + s2;
            });
    }

    执行结果如下:

    a1|a2
    a1|a2|b1
    a1|a2|b1|b2
    a1|a2|b1|b2|b3
    a1|a2|b1|b2|b3|o1

    相关文档:https://blog.csdn.net/dd864140130/article/details/50603420

  • 相关阅读:
    N皇后
    水域大小
    1221 分割平衡字符串
    1391 检查是否存在有效路径 DFS
    盛最多水的容器11 双指针
    烧饼排序
    每日日报8——软件设计④|抽象工厂模式(人与肤色)
    每日日报5——登录功能的实现(JAVA)
    每日日报4——软件设计②|简单工厂模式(女娲造人)
    vue利用transition过渡动画实现轮播图
  • 原文地址:https://www.cnblogs.com/hooly/p/10135338.html
Copyright © 2020-2023  润新知