Posts 《Effective Java》第7章lambda表达式和流
Post
Cancel

《Effective Java》第7章lambda表达式和流

第42条:Lambda优先于匿名类

1
2
3
4
5
6
Collections.sort(words, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return Integer.compare(s1.length(),s2.length());
    }
});

Java 8中,带有单个抽象方法的接口被称作函数接口(function interface)Java允许利用Lambda表达式创建这些接口的实例。Lambda表达式类似于匿名类的函数,但是比它简洁的多。

1
Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(),s2.length()));

可以用Lambda表达式代替比较器构造方法(comparator construction method)

1
Collections.sort(words, Comparator.comparingInt(String::length));

利用Java 8List接口中添加的sort方法,代码片段可以更加简短一些:

1
words.sort(Comparator.comparingInt(String::length));

Java中增加了Lambda之后,使得之前不能使用函数对象的地方现在也能使用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public enum Operation {
    PLUS("+"){
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    },
    MINUS("-"){
        @Override
        public double apply(double x, double y) {
            return x - y;
        }
    },
    TIMES("*"){
        @Override
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVIDE("/"){
        @Override
        public double apply(double x, double y) {
            return x / y;
        }
    };
    
    private final String symbol;
    Operation(String symbol){
        this.symbol = symbol;
    }
    public abstract double apply(double x,double y);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public enum Operation {
    PLUS("+", (x, y) -> x + y),
    MINUS("-", (x, y) -> x - y),
    TIMES("*", (x, y) -> x * y),
    DIVIDE("/", (x, y) -> x / y);

    private final String symbol;
    private final DoubleBinaryOperator op;

    Operation(String symbol, DoubleBinaryOperator op) {
        this.symbol = symbol;
        this.op = op;
    }

    public double apply(double x, double y) {
        return op.applyAsDouble(x, y);
    }
}

Lambda限于函数接口,无法为带有多个抽象方法的接口创建实例。Lambda无法获得对自身的引用。在Lambda中,关键字this是指外围实例。在匿名类中,关键字this是指匿名类实例。如果需要从函数对象的主体内部访问它,就必须使用匿名类。

第43条:方法引用优先于Lambda

与匿名类相比,Lambda的主要优势在于更加简洁。Java提供了生成比Lambda更简洁的函数对象的方法:方法引用(method reference)

1
2
3
Map<String,Integer> map = new HashMap<>();
System.out.println(map.merge("one",1,(oldValue,value)->oldValue + value));//1
System.out.println(map.merge("one",1,(oldValue,value)->oldValue + value));//2

merge方法时Java 8Map接口中添加的。如果指定的键没有值,就会插入指定的值;如果值存在,merge方法就会将指定的函数应用到当期值和指定值上,并用结果覆盖当前值。

Java 8开始,Integer提供了一个名为sum的静态方法,它的作用也同样是求和。我们只要传入一个对该方法的引用,就可以更轻松地得到相同的结果:

1
2
3
Map<String,Integer> map = new HashMap<>();
System.out.println(map.merge("one",1, Integer::sum));//1
System.out.println(map.merge("one",1, Integer::sum));//2

第44条:坚持使用标准的函数接口

第45条:谨慎使用 Stream

第46条:优先选择 Stream 中无副作用的函数

第47条:Stream 要优先用 Collection 作为返回类型

第48条:谨慎使用 Stream 并行

This post is licensed under CC BY 4.0 by the author.

《Effective Java》第6章枚举和注解

《Effective Java》第8章方法

Comments powered by Disqus.