zoukankan      html  css  js  c++  java
  • 方法作为一等公民-Java

                              方法和 Lambda作为一等公民 

    方法引用

    在Java8以前,如果我们要筛选一个目录中的隐藏文件,我们需要这样做:

        File[] hiddenFiles = new File("").listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isHidden();
            }
        });

    Java8里,我们可以重写成:

    File[] hiddenFiles2 = new File("").listFiles(File::isHidden);

    :: 这个语法的意思是把这个方法作为值传递给listFiles方法。

     传递方法

    public class Apple {
        String color;
        int weight;
    
        public Apple(String color, int weight) {
            this.color = color;
            this.weight = weight;
        }
    
        public static boolean isGreen(Apple apple) {
            return "green".equals(apple.getColor());
        }
    
        public static boolean isHeavy(Apple apple) {
            return apple.getWeight() > 20;
        }
    
        public static List<Apple> filterApples(List<Apple> apples, Predicate<Apple> p) {
            List<Apple> result = new ArrayList<>();
            for (Apple apple : apples) {
                if (p.test(apple)) {
                    result.add(apple);
                }
            }
            return result;
        }
    
        public static void main(String[] args) {
            List<Apple> apples = List.of(new Apple("green", 21), new Apple("black", 19));
            List<Apple> apples1 = filterApples(apples, Apple::isGreen);
            List<Apple> apples2 = filterApples(apples, Apple::isHeavy);
            apples1.stream().forEach(e -> System.out.println(e));
        }
    
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        public int getWeight() {
            return weight;
        }
    
        public void setWeight(int weight) {
            this.weight = weight;
        }
    }

    前面的代码传递了方法Apple::isGreenApple(它接受参数Apple并返回一个 boolean)给 filterApples,后者则希望接受一个Predicate<Apple>参数。谓词(predicate) 在数学上常常用来代表一个类似函数的东西,它接受一个参数值,并返回true或false。你 在后面会看到,Java 8也会允许你写Function<Apple,Boolean>——在学校学过函数却没学 过谓词的读者对此可能更熟悉,但用Predicate<Apple>是更标准的方式,效率也会更高一 点儿,这避免了把boolean封装在Boolean里面。 

    实际上并不需要单独写比较过滤方法,可以用这种匿名Lambda形式替代:

    List<Apple> apples2 = filterApples(apples, (Apple a) -> a.getWeight() > 20);

    但是对于实际开发来讲,这种并非是一种很好的方式,毕竟维护稍微困难了些,如果你写了很长的lambda,还不如老老实实定义方法然后call.

    甚至还有一种更简便的方式,直接不需要filterApples()方法:

    static <T> Collection<T> filter(Collection<T> c, Predicate<T> p); 

    这就是基于流化实现

    apples.stream().filter(a -> a.getWeight() > 20).forEach(System.out::println);

    流Strem

            List<Apple> apples = List.of(new Apple("green", 21), new Apple("black", 19));
            Map<String, List<Apple>> groupForApples = new HashMap<>();
            for (Apple apple : apples) {
                if (apple.getWeight() > 20) {
                    String color = apple.getColor();
                    List<Apple> appleList = groupForApples.get(color);
                    if (appleList == null) {
                        groupForApples.put(color, appleList);
                    }
                    appleList.add(apple);
                }
            }

    这段复杂的代码描述的意思很简单,就是将重量大于20的apple按照颜色分组。但描述还是不够清晰的。现在用流转换一下。

            Map<String, List<Apple>> groupForApples2 =
                    apples.stream().
                            filter((Apple apple) -> apple.getWeight() > 20).
                            collect(Collectors.groupingBy(Apple::getColor));

    emm,很清晰,首先流转化,然后过滤,然后groupBy颜色分组。

    总之简单来讲,利用Collection API就是外部迭代,用Stream API就是内部迭代。

     并行处理

            Map<String, List<Apple>> groupForApples2 =
                    apples.parallelStream().
                            filter((Apple apple) -> apple.getWeight() > 20).
                            collect(Collectors.groupingBy(Apple::getColor));

    看起来是不是有点像分治,归并的思路。

    语言特性的添加要考虑的一个很重要的问题是和老版本的兼容。比如我们现在可以对list.sort()这种操作,但是原先是不可以的,现在的处理方法是,我们可以对接口中加入default方法。

    这就是我们在List接口中添加的。

    default void sort(Comparator<? super E> c) { 
        Collections.sort(this, c);
    }

    这种default方法,在任何实现类都不需要显示的实现sort。

    著名的NULL,万能的NULL也是万恶的NULL。如何避免出现NullPointer异常--->Optional<T>

     
    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    C# 异步编程 (12)
    C# 动态语言扩展(11)
    C# LINQ(10)
    代码整洁之道(1)
    C# 集合(9) 持续更新
    C# 字符串和正则表达式(8) 持续更新
    C# 委托、lambda表达式和事件 (7) 持续更新
    C# 运算符和类型强制转换(6) 持续更新
    C++_将图二维矩阵形式转为邻接表结构
    .NET(C#)连接各类数据库-集锦
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12116367.html
Copyright © 2011-2022 走看看