Java8初探

安装配置

JDK8下载链接,安装完之后就能直接用javac编译java8代码了.

新特性

1.lambda表达式

Lambda表达式可以说是函数式编程的标志性语法,有了lambda表达式就可以和Java蹩脚的匿名内部类说再见了

List prices = Arrays.asList(...);
// 匿名内部类
Collections.sort(prices, new Comparator() {
    @Override
    public int compare(TimePricePair p1, TimePricePair p2) {
        return Float.compare(p1.getPrice(), p2.getPrice());
    }
});
// lambda表达式	
Collections.sort(prices, (x, y) -> Float.compare(x.getPrice(), y.getPrice()) );
// 嵌套lambda表达式
Callable c = () -> () -> { System.out.println("hi"); };

Java的lambda表达式和C#一致,小括号间是参数列表,箭头后面是函数体。为了使lambda表达式足够容易写,在只有一个表达式的时候可以不加花括号,可以不加return,使用类型推断使得参数列表中的参数类型可以省略。另外,lambda表达式可以访问当前上下文中的任何变量,而不是像匿名内部类一样只能访问final变量。一句话总结,lambda表达式就是新世纪的匿名内部类。

2.函数引用

这个特性看几行代码就很清楚了

Arrays.asList("Alice", "Bob", "Charlie", "Dave").forEach(System.out::println);
Arrays.sort(names, String::compareToIgnoreCase);

3.接口默认方法

简而言之, 接口可以有一个默认实现,实现这个接口的子类可以使用这个默认实现,也可以重载它。对于这样的接口,大多数情况下实现都相同,只在特殊需要的时候需要重写非常有用,比如序列化接口IWritable中的copyFileds,完全可以由readFileds和writeFileds实现:

public interface IWritable {
    public void writeFields(DataOutput out) throws IOException;
    public void readFields(DataInput in) throws IOException;
    public IWritable copyFields(IWritable that) default {
        if (this != that) {
            DataOutputBuffer out = new DataOutputBuffer();
            DataInputBuffer in = new DataInputBuffer();
            that.writeFields(out);
            in.reset(out.getData(), out.size());
            this.readFields(in);
        }
        return this;
    }
}

从此再也不用写copyFields了

4.其他函数式编程特性

/** map filter and forEach */
List names = Arrays.asList("Alice", "Bob", "Charlie", "Dave");
names
    .mapped(e -> { return e.length(); }) // 转成一个(name, name length)的二元组list
    .asIterable() // 类似map的entrySet
    .filter(e -> e.getValue() >= 4) // 过滤名字长度大于4
    .sorted((a, b) -> a.getValue() - b.getValue()) // 按名字长度排序
    .forEach(e -> { System.out.println(e.getKey() + 't' + e.getValue()); });

python、scala、js里都有类似的工具,所以就不多说了。这些方法实际上是由一些函数式编程接口实现的,只不过在java8里可以用lambda表达式代替匿名内部类了,语法一下就简洁明了了。

在Eclipse里使用Java8

每改一次代码都要在命令行下编译一次比较痛苦。Eclipse的JDT现在还不支持Java 8(其实也不可能支持,java现在语法都还没完全确定),不过用还是可以在Eclipse里编译代码查看输出,但是语法检查的功能就没了,不过再怎么也比命令行稍微舒服点。

具体方法是在工程设置 -> Builders里把默认的Java Builder禁用,新建一个Builder,如下图设置:

参考资料

  1. State of the Lambda(详细介绍了各个特性)
  2. Java 8 lambdas
  3. What’s Cooking in Java 8 – Project Lambda
  4. Translation of Lambda Expressions(介绍了lambda表达式的编译过程)
This entry was posted in 技术学习. Bookmark the permalink.

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据