DrewJhung's Blog

java8新语法

了解java8新语法

  1. 最近在学习java版的简式爬虫框架:webmagic,看Spider源码的时候翻到了jre1.8的Map接口的一个静态方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Returns a comparator that compares {@link Map.Entry} in natural order on key.
*
* <p>The returned comparator is serializable and throws {@link
* NullPointerException} when comparing an entry with a null key.
*
* @param <K> the {@link Comparable} type of then map keys
* @param <V> the type of the map values
* @return a comparator that compares {@link Map.Entry} in natural order on key.
* @see Comparable
* @since 1.8
*/
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getKey().compareTo(c2.getKey());
}

上面的代码中的这个标记 -> 有些疑惑, 查资料得:

  • -> 这个标记是lambda表达式;

  • lambda表达式的限定范围:接口回调、匿名内部类, 但不是所有的接口和匿名内部类都可以用这个lambda表达式,接口中或者匿名内部类中只包含一个抽象方法才可以使用lambda表达式语法,称这样的接口为函数接口,接口函数例子:

    java.lang.Runnable

    java.util.concurrent.Callable

    java.io.FileFilter

    java.nio.file.PathMatcher

    java.lang.reflect.InvocationHandler

  1. lambda语法介绍

    它包含三部分:参数、箭头符号 “->”、代码块。例子:

    1
    2
    3
    4
    5
    6
    7
    8
    public static void main(String[] args){
    // 无参数函数回调
    Runnable r = () -> System.out.println("hello, lambda expression.");
    // 一个或者多个参数函数接口
    java.util.Comparator<String> c = (String o1, String o2) -> o1.compareTo(o2);
    new Thread(r).start();
    c.compare("test", "123");
    }
  2. lambda表达式的一点疑惑

    我之前介绍lambda 表达式目前仅用于只包含一个抽象方法的接口中, 但是java.util.Comparator除了compare(T o1, T o2);还有equals(Object obj)这个方法, 那为什么你的Comparator还可以称为函数接口, 答案:

    首先看一张截图:

    alt

    这个注解也是jdk1.8搞出来的, 该注解的目的及意图如下解释:

    alt

    大致就是说其实凡是从Object 继承来的方法都有默认的实现, 他们都不算是抽象方法, 所以, 在java.util.Comparator中 equals(Object obj);不算是抽象方法, 所以Comparator中只有一个抽象方法:compare(T o1, T o2);故, 可以利用lambda表达式咯。

  3. 大概总结到这里, 我不太喜欢这个lambda表达式, 感性的说:我习惯了以前的匿名内部类的写法。我了解的企业现在并没有发力于基于java1.8的开发, 我们公司还在用1.7。