Java8新特性

  这两天看到Java8的新特性,发现真的好用,代码更加简洁了,看着就舒服,所以我不得不在这里记录一下


Java8新特性

以下详细介绍不按照上面顺序排列,自行看大标题区分

方法引用

这是Java8出来之前调用isHidden方法的语句

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

看起来虽热只有三行,但是逻辑有点绕,然后变成Lambda表达式

File[] hiddenFiles = new File(".").listFiles(file -> file.isHidden());

用方法引用会更简略

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

哈哈,是不是看起来逻辑很明了,也很简洁?


方法引用图解

在Java 8里写下File::isHidden的时候,你就创建了一个方法引用,你同样可以传递它。只要方法中有代码(方法中的可执行部分),那么用方法引用就可以传递代码。

Lambda——匿名函数

  使用匿名类来表示不同的行为并不令人满意:代码十分啰嗦,这会影响程序员在实践中使用行为参数化的积极性。Lambda(最初是根据希腊字母λ命名的。虽然Java中不使用这个符号,名称还是被保留了下来)体现了更广义的将函数作为值的思想。你可以Xxx类里面定义一个x方法,然后写Xxx::x吗?确实是可以,但要是你没有方便的方法和类可用,而新的Lambda语法更简洁,它可以让你很简洁地表示一个行为或传递代码。现在你可以把Lambda表达式看作匿名功能,它基本上就是没有声明名称的方法,但和匿名类一样,它也可以作为参数传递给一个方法。
  Lambda表达式最终结果就是你的代码变得更清晰、更灵活。比如,利用Lambda表达式,你可以更为简洁地自定义一个Comparator对象(本例子比较Apple的重量)
之前的实现方法

Comparator byWeight = new Comparator() {
    public int compare(Apple a1, Apple a2){
        return a1.getWeight().compareTo(a2.getWeight());
    }
};

使用Lambda表达式后

Comparator byWeight = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
Lambda表达式组成图解

Lambda实例

// 1. 不需要参数,返回值为 5  
() -> 5  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)

传递代码的一个例子
假设你有一个Apple类,它有一个getColor方法,还有一个变量inventory保存着一个Apples的列表。你可能想要选出所有的绿苹果,并返回一个列表。通常我们用筛选(filter)一词来表达这个概念。在Java 8之前,你可能会写这样一个方法filterGreenApples:

public static List filterGreenApples(List inventory){
    List result = new ArrayList<>();
    for (Apple apple: inventory){
        if ("green".equals(apple.getColor())) {
            result.add(apple);
        }
    }
    return result;
}

但是接下来,有人可能想要选出重的苹果,比如超过150克,于是你心情沉重地写了下面这
个方法,甚至用了复制粘贴

public static List filterHeavyApples(List inventory){
    List result = new ArrayList<>();
    for (Apple apple: inventory){
        if (apple.getWeight() > 150) {
            result.add(apple);
        }
    }
    return result;
}

我们前面提过了,Java 8会把条件代码作为参数传递进去,这样可以避免filter方法
出现重复的代码。现在你可以写

public static boolean isGreenApple(Apple apple) {
    return "green".equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple) {
    return apple.getWeight() > 150;
}
public interface Predicate{
    boolean test(T t);
}
static List filterApples(List inventory, Predicate p) {
    List result = new ArrayList<>();
    for (Apple apple: inventory){
        if (p.test(apple)) {
            result.add(apple);
        }
    }
    return result;
}

要用它的话,你可以写:

//绿色
filterApples(inventory, Apple::isGreenApple); 
//重量
filterApples(inventory, Apple::isHeavyApple);

把方法作为值来传递显然很有用,但要是为类似于isHeavyApple和isGreenApple这种可
能只用一两次的短方法写一堆定义有点儿烦人。不过Java 8也解决了这个问题,它引入了一套新
记法(匿名函数或Lambda),让你可以写

//绿色
filterApples(inventory, (Apple a) -> "green".equals(a.getColor()) ); 
//重量大于150
filterApples(inventory, (Apple a) -> a.getWeight() > 150 ); 
//重量小于80或者棕色
filterApples(inventory, (Apple a) -> a.getWeight() < 80 ||  "brown".equals(a.getColor()) );

你可能感兴趣的:(Java8新特性)