java 8 limbda探索(遍历和流对象)

2019-07-04 00:00:00 对象 遍历 探索

注意如果在java版本正确的情况下idea limbda表达式报错则请做如下配置:

《java 8 limbda探索(遍历和流对象)》
《java 8 limbda探索(遍历和流对象)》

1)遍历对象

forEach方法最简单的使用便是用一个参数指向里面执行的表达式:

        List<String> list = Arrays.asList("aaa","bbb","ccc","aaa");
//如果只有一个表达式则可以不需要这个中括号         list.forEach(a -> {
            a ="a is " + a;
            System.out.println(a);
        });
        /**  * out :  * a is aaa  * a is bbb  * a is ccc  * a is aaa  **/

这相当于:

        List<String> list = Arrays.asList("aaa","bbb","ccc","aaa");
        for(String a:list){
            a ="a is " + a;
            System.out.println(a);
        }

同样,用map也可以用forEach方法进行迭代,但是参数需要多填写一个,两个参数分别代表key,value 。

        Map<Integer,Integer> map = new HashMap<>();
        map.put(1,2);
        map.put(3,4);
        map.put(5,6);
        map.forEach((a,b) -> System.out.println(a+b));
        /**
         * out :
         * 3
         * 7
         * 11
         **/

这相当于

        Map<Integer,Integer> map = new HashMap<>();
        map.put(1,2);
        map.put(3,4);
        map.put(5,6);
        for(Integer a:map.keySet()){
            System.out.println(a+map.get(a));
        }

在参数不做改动且方法参数相同时,forEach内部也可以做一个简单的方法引用 。

例如list的遍历可以修改成这样:

 list.forEach(System.out::println);

但是map不能做这样的修改,如果需要的话我们可以这样调用:

        Map<Integer,Integer> map = new HashMap<>();
        map.put(1,2);
        map.put(3,4);
        map.put(5,6);
        map.forEach(Demo::OutPrint);
    
        public static void OutPrint(int a ,int b){
        System.out.println("a:"+a);
        System.out.println("b:"+b);
        }
        /**
         * out :
         * a:1
         * b:2
         * a:3
         * b:4
         * a:5
         * b:6
         **/

当然也可以调用非静态方法:

        Map<Integer,Integer> map = new HashMap<>();
        map.put(1,2);
        map.put(3,4);
        map.put(5,6);
        map.forEach(new Demo()::OutPrint);
    
        void OutPrint(int a ,int b){
        System.out.println("a+"+a);
        System.out.println("b+"+b);
        }

2)流(Stream)

Stream对象为我们操作数组提供了更多的便利,我们可以直接在流对象中对数组进行过滤,并且直接进行遍历(filter):

        List<String> list = Arrays.asList("aaa","bbb","ccc","aaa");
        list.stream().filter(Str -> !Str.startsWith("a")).forEach(System.out::println);
        /**
         * out :
         * bbb
         * ccc
         **/

当然由于stream对象的设计都是链式设计,我们可以多次过滤:

        List<String> list = Arrays.asList("aaa","bbb","ccc","aaa");
        list.stream().filter(Str -> !Str.startsWith("a")).filter(Str -> Str.startsWith("b")).forEach(System.out::println);
        /**
         * out :
         * bbb
         **/

filter方法的参数是一个predicate对象,我们可以直接将条件拼接传入 :

        List<String> list = Arrays.asList("aaa","bbb","ccc","aaa");
        Predicate<String> predicatea = Str -> !Str.startsWith("a");
        Predicate<String> predicateb = Str -> Str.startsWith("b");
        list.stream().filter(predicatea.and(predicateb)).forEach(System.out::println);
        /**
         * out :
         * bbb
         **/

这期间我们也可以直接去重和排序(distinct和sorted):

        List<String> list = Arrays.asList("aaa","bbbb","cccc","aaaa","aaa");
        Predicate<String> predicatea = Str -> Str.startsWith("a");
        list.stream().filter(predicatea).distinct().sorted((x,y) -> y.length() - x.length()).forEach(System.out::println);
        list.stream().filter(predicatea).distinct().sorted((x,y) -> x.length() - y.length()).forEach(System.out::println);
        /**
         * out :
         * aaaa
         * aaa
         * aaa
         * aaaa
         **/

我们还可以在判断前先对数组的值做部分处理(map):

        List<String> list = Arrays.asList("aaa","bbbb","cccc","aaaa","aaa");
        list.stream().map((str) -> str+str).filter(str -> str.length()>6).forEach(System.out::println);
        /**
         * out :
         * bbbbbbbb
         * cccccccc
         * aaaaaaaa
         **/

使用max方法:

        List<Integer> list = Arrays.asList(111,222,333,444,555);
        System.out.println(list.stream().map((a) -> a+a).max(Integer::compare).get());
        /**
         * out :
         * 1110
         **/

查询元素(findFirst和findAny),由于此时流是有序的findAny执行起来其实和First是一个效果,但如果findAny之前执行了parallel()方法,那么就都找到哪一个都有可能了。

        List<Integer> list = Arrays.asList(777,999,333,444,555);
        System.out.println(list.stream().findFirst().get());
        System.out.println(list.stream().findAny().get());
        /**
         * out :
         * 777
         * 777
         **/

元素匹配(allMatch)

        List<Integer> list = Arrays.asList(777,999,333,444,555);
        System.out.println(list.stream().parallel().allMatch(Demo::OutPrint));
        System.out.println(list.stream().parallel().noneMatch(Demo::OutPrint));
        public static boolean OutPrint(int a){
            if(a > 444)
            return true;
            else return false;
        }
        /**
         * out :
         * false
         * false
         **/

需要注意的是,在变成流被操作的期间,数组本身是不被改变的:

        List<String> list = Arrays.asList("aaa","bbbb","cccc","aaaa","aaa");
        Predicate<String> predicatea = Str -> Str.startsWith("a");
        list.stream().filter(predicatea).distinct().sorted((x,y) -> y.length() - x.length()).forEach(a -> System.out.println("流数据:"+a));
        list.forEach(a -> System.out.println("原数据:"+a));
        /**
         * out :
         * 流数据:aaaa
         * 流数据:aaa
         * 原数据:aaa
         * 原数据:bbbb
         * 原数据:cccc
         * 原数据:aaaa
         * 原数据:aaa
         **/

如果需要获得改变后的数组,我们可以聚合它,让它成为一个新的数组:

        List<String> list = Arrays.asList("aaa","bbbb","cccc","aaaa","aaa");
        Predicate<String> predicatea = Str -> Str.startsWith("a");
        List newlist = list.stream().filter(predicatea).distinct().sorted((x,y) -> y.length() - x.length()).collect(Collectors.toList());
        newlist.forEach(a -> System.out.println("新数组:"+a));
        /**
         * out :
         * 新数组:aaaa
         * 新数组:aaa
         **/

    原文作者:龚海生
    原文地址: https://zhuanlan.zhihu.com/p/35445336
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章