zoukankan      html  css  js  c++  java
  • java Stream流,方法引用

    1.Stream流

    1.1两种获取流的方法

    java.util.stream.Stream<T> 是Java 8新加入的最常用的流接口。(这并不是一个函数式接口。)

    获取一个流非常简单,有以下几种常用的方式:
    所有的 Collection 集合都可以通过 stream 默认方法获取流;
    Stream 接口的静态方法 of 可以获取数组对应的流。
    根据Collection获取流
    import
     java.util.*; import java.util.stream.Stream; public class Demo04GetStream {     public static void main(String[] args) {         List<String> list = new ArrayList<>();         // ...         Stream<String> stream1 = list.stream();         Set<String> set = new HashSet<>();         // ...         Stream<String> stream2 = set.stream();         Vector<String> vector = new Vector<>();         // ...

      Stream<String> stream3 = vector.stream();
        }

     }
    根据Map获取流
    import java.util.HashMap;
    import java.util.Map;
    import java.util.stream.Stream;
    public class Demo05GetStream {
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<>();
            // ...
            Stream<String> keyStream = map.keySet().stream();
            Stream<String> valueStream = map.values().stream();
            Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
        }
    }
    根据数组获取流
    如果使用的不是集合或映射而是数组,由于数组对象不可能添加默认方法,所以 Stream 接口中提供了静态方法
    of ,使用很简单:
    import java.util.stream.Stream;
    public class Demo06GetStream {
        public static void main(String[] args) {
            String[] array = { "张无忌", "张翠山", "张三丰", "张一元" };
            Stream<String> stream = Stream.of(array);
        }

    1.2常用方法

    流模型的操作很丰富,这里介绍一些常用的API。这些方法可以被分成两种:
    延迟方法:返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方
    法均为延迟方法。)
    终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似 StringBuilder 那样的链式调
    用。本小节中,终结方法包括 count 和 forEach 方法。

    逐一处理
    void forEach(Consumer<? super T> action);
    过滤
    Stream<T> filter(Predicate<? super T> predicate);
    映射
    <R> Stream<R> map(Function<? super T, ? extends R> mapper);
    统计个数
    long count();
    取用前几个
    Stream<T> limit(long maxSize);
    跳过前几个
    Stream<T> skip(long n);
    组合
    static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

     1.3练习:集合元素处理

    现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)依次进行以
    下若干操作步骤:
    1. 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
    2. 第一个队伍筛选之后只要前3个人;存储到一个新集合中。
    3. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
    4. 第二个队伍筛选之后不要前2个人;存储到一个新集合中。
    5. 将两个队伍合并为一个队伍;存储到一个新集合中。
    6. 根据姓名创建 Person 对象;存储到一个新集合中。
    7. 打印整个队伍的Person对象信息。

    两个队伍(集合)的代码如下:

    import java.util.ArrayList;
    而 Person 类的代码为:
    import java.util.List;
    public class DemoArrayListNames {
        public static void main(String[] args) {
           //第一支队伍
            ArrayList<String> one = new ArrayList<>();
            one.add("迪丽热巴");
            one.add("宋远桥");
            one.add("苏星河");
            one.add("石破天");
            one.add("石中玉");
            one.add("老子");
            one.add("庄子");
            one.add("洪七公");
            //第二支队伍
            ArrayList<String> two = new ArrayList<>();
            two.add("古力娜扎");
            two.add("张无忌");
            two.add("赵丽颖");
            two.add("张三丰");
            two.add("尼古拉斯赵四");
            two.add("张天爱");
            two.add("张二狗");
    // ....        
        }
    }

    而 Person 类的代码为:

    public class Person {
       
        private String name;
        public Person() {}
        public Person(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Person{name='" + name + "'}";
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }

    解答:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Stream;
    public class DemoStreamNames {
        public static void main(String[] args) {
            List<String> one = new ArrayList<>();
            // ...
            List<String> two = new ArrayList<>();
            // ...
            // 第一个队伍只要名字为3个字的成员姓名;
            // 第一个队伍筛选之后只要前3个人;
            Stream<String> streamOne = one.stream().filter(s ‐> s.length() == 3).limit(3);
            // 第二个队伍只要姓张的成员姓名;
            // 第二个队伍筛选之后不要前2个人;
            Stream<String> streamTwo = two.stream().filter(s ‐> s.startsWith("张")).skip(2);
            // 将两个队伍合并为一个队伍;
            // 根据姓名创建Person对象;
            // 打印整个队伍的Person对象信息。
            Stream.concat(streamOne, streamTwo).map(Person::new).forEach(System.out::println);
        }}

    运行效果:

    Person{name='宋远桥'}
    Person{name='苏星河'}
    Person{name='石破天'}
    Person{name='张天爱'}
    Person{name='张二狗'}

    2.方法引用

    在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿什么参数做什么操作。那么考虑
    一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑?

    双冒号 :: 为引用运算符,而它所在的表达式被称为方法引用。如果Lambda要表达的函数方案已经存在于某个方
    法的实现中,那么则可以通过双冒号来引用该方法作为Lambda的替代者。

    2.1 通过对象名引用成员方法

     2.2 通过类名称引用静态方法

     2.3 通过super引用成员方法

     

     2.4 通过this引用成员方法

     2.5 类的构造器引用

     

     2.6 数组的构造器引用

  • 相关阅读:
    【Javascript】javascript学习 二十二 JavaScript 对象简介
    【Javascript】javascript学习 二十六 JavaScript Boolean(逻辑)对象
    【Javascript】javascript学习 二十九 JavaScript HTML DOM 对象
    【Javascript】javascript学习 二十八 JavaScript RegExp 对象
    【Javascript】javascript学习 二十一 JavaScript 指导方针
    【Javascript】javascript学习 二十三 JavaScript 字符串(String)对象
    【Javascript】javascript学习 三十 JavaScript 浏览器检测
    【Javascript】javascript学习 二十五 JavaScript Array(数组)对象
    【Javascript】javascript学习 二十四 JavaScript Date(日期)对象
    【Javascript】javascript学习 二十七 JavaScript Math(算数)对象
  • 原文地址:https://www.cnblogs.com/qqfff/p/13253868.html
Copyright © 2011-2022 走看看