• 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 数组的构造器引用

  • 相关阅读:
    Ubuntu中Nginx的安装与配置
    在Ubuntu中安装Redis
    微博开放平台
    QQ互联 回调地址
    PostgreSQL在Ubuntu上安装指南
    postgresql常用命令
    在Linux下查看环境变量
    vue-04-组件
    vue-03-style与class
    vue-02-安装-指令
  • 原文地址:https://www.cnblogs.com/qqfff/p/13253868.html
Copyright © 2020-2023  润新知