Lambda表达式-stream流

流与集合相比的优点
流的延迟执行特点
集合、映射或数组获取流
常用的流操作
输出语句的方法引用
使用类和数组的构造器引用

public class StreamDemo {
    //流控制,打印
    @Test
    public void test1() {
        List<String> data = new ArrayList<String>();
        data.add("张无忌");
        data.add("着迷");
        data.add("张三丰");
        data.add("百里一组");
        data.add("二蛋二狗子");
        data.stream().filter(
                s -> s.startsWith(""))
                .filter(s -> s.length() == 3).forEach(System.out::println);
    }

    //获取流
    @Test
    public void test2() {
        List<String> data = new ArrayList<String>();
        Stream<String> stream = data.stream();
        HashMap<String, Object> data2 = new HashMap<>();
        Stream<String> keys = data2.keySet().stream();
        Stream<Object> values = data2.values().stream();
        //数组
        String[] arr = {"张三", "李四", "张三丰"};
        Stream<String> arr1 = Stream.of(arr);
        arr1.filter(s -> s.startsWith("")).forEach(name -> System.out.println(name));
        //arr1.forEach(name-> System.out.println(name));
    }

    /**
     * 果需要将流中的元素映射到另一个流中,可以使用 map 方法。方法签名:
     * 该接口需要一个 Function 函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流
     */
    @Test
    public void test3() {
        String[] arr = {"张三", "李四", "张三丰"};
        Stream<String> data = Stream.of("12", "13", "22");
        Stream<Integer> result = data.map(str -> Integer.parseInt(str));
        result.forEach(str -> System.out.println(str));
    }

    /**
     * 如旧集合 Collection 当中的 size 方法一样,流提供 count 方法来数一数其中的元素个数:
     */
    @Test
    public void test4() {
        String[] arr = {"张三", "李四", "张三丰"};
        Stream<String> arr1 = Stream.of(arr);
        Stream<String> result = arr1.filter(s -> s.startsWith(""));
        System.out.println(result.count());
    }

    /**
     * 取用前几个:limit
     * limit 方法可以对流进行截取,只取用前n个。方法签名:
     */
    @Test
    public void test5() {
        String[] arr = {"张三", "李四", "张三丰"};
        Stream<String> arr1 = Stream.of(arr);
        Stream<String> limit = arr1.limit(1);
        Stream<String> result = limit.filter(s -> s.startsWith(""));
        System.out.println(result.count());
    }

    /**
     * 如果希望跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流
     */
    @Test
    public void test6() {
        String[] arr = {"张三", "李四", "张三丰"};
        Stream<String> arr1 = Stream.of(arr);
        Stream<String> skip = arr1.skip(1);
        System.out.println(skip.count());
    }

    /**
     * 如果希望跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流
     */
    @Test
    public void test7() {
        String[] arr = {"张三", "李四", "张三丰"};
        Stream<String> arr1 = Stream.of("张三丰");
        Stream<String> arr2 = Stream.of("张无极");
        Stream<String> concat = Stream.concat(arr1, arr2);
        concat.forEach(System.out::println);
    }

    /**
     * 1. 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
     * 2. 第一个队伍筛选之后只要前3个人;存储到一个新集合中。
     * 3. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
     * 4. 第二个队伍筛选之后不要前2个人;存储到一个新集合中。
     * 5. 将两个队伍合并为一个队伍;存储到一个新集合中。
     * 6. 根据姓名创建 Person 对象;存储到一个新集合中。
     * 7. 打印整个队伍的Person对象信息。
     */
    class Person {
        private String name;


        public Person(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }

    @Test
    public void test8() {
        List<String> one = new ArrayList<String>();
        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("石破天");
        one.add("石中玉");
        one.add("老子");
        one.add("庄子");
        one.add("洪七公");
        List<String> two = new ArrayList<String>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("赵丽颖");
        two.add("张三丰");
        two.add("尼古拉斯赵四");
        two.add("张天爱");
        two.add("张二狗");
        Stream<String> oneConcat = one.stream().filter(name -> name.length() == 3).limit(3);
        Stream<String> twoConcat = two.stream().filter(name -> name.startsWith("")).skip(2);
        Stream.concat(oneConcat, twoConcat).map(Person::new).forEach(System.out::println);
    }
    /**
     * :: 为“方法引用”,而双冒号是一种新的语法
     * Lambda表达式写法: s -> System.out.println(s);
     * 方法引用写法: System.out::println
     * 第一种语义是指:拿到参数之后经Lambda之手,继而传递给 System.out.println 方法去处理。
     * 第二种等效写法的语义是指:直接让 System.out 中的 println 方法来取代Lambda。两种写法的执行效果完全一
     * 样,而第二种方法引用的写法复用了已有方案,更加简洁。
     */

    /**
     * 通过函数引用静态方法
     */
    @Test
    public void test9() {
        test9Demo(s->{
                System.out.println(s);
        });
        test9Demo(System.out::println);
    }
    public void test9Demo(Printable p) {
        p.print("hello");
    }
    class ChildInterfacd implements ParentInterface{
        @Override
        public String method(String a) {
            System.out.println(a);
            return null;
        }
    }
    /***
     * 通过对象名引用方法
     */
    @Test
    public void test9Demo1() {
        ChildInterfacd childInterfacd = new ChildInterfacd();
        test9Demo(childInterfacd::method);
    }
    /**
     * 静态方法调用
     */
    @FunctionalInterface
    public interface  Calcable{
        int calc(int num);
    }
    public class Demo05Lamba implements Calcable{
        @Override
        public int calc(int num) {
            return 0;
        }
    }
    //调用常量类
    @Test
    public void test10() {
        //这个例子中,下面两种写法是等效的:
        //Lambda表达式: n -> Math.abs(n)
        //方法引用: Math::abs
        test10Demo(-10,n->Math.abs(n+5));
        test10Demo(-10,Math::abs);
    }
    public void test10Demo(int num,Calcable c) {
        System.out.println(c.calc(num));
    }

猜你喜欢

转载自www.cnblogs.com/liushisaonian/p/11424708.html