简而言之,java8的新特性就是:Lamdba函数(匿名函数),流,默认方法。java
Java8 的灵活使用,会使得代码可读性更好(前提是你的同事也使用,别人不会,你强行使用,会被喷的!!!)、简洁易懂。编程
Collections.sort(inventory, new Comparator<Apple>() { public int compare(Apple a1, Apple a2){ return a1.getWeight().compareTo(a2.getWeight()); } });
注:此处使用的是匿名内部类,总体嘛,感受还能够app
invertory.sort(comparing(Apple:getWeight))
注:此处使用的是Lambda表达式,它念起来就是“给库存排序,比较苹果的重量”编程语言
到此处,你可能不太明白Java8为神马能够一行代码搞定排序这个逻辑,不过,经过此处也见识了Java8的强大了,下面让咱们总体认识一下。函数
编程语言中的函数一词一般指的是方法。java8中新增了函数----值得一种新形式。做为值的函数有何益处,Java8的设计者容许方法做为值,让编程更轻松。设计
java8的第一个新功能就是方法引用。比方说你想要筛选一个目录中全部隐藏的文件。你须要编写一个方法,而后给它一个File,它就会告诉你文件是否是隐藏的。幸亏,File 类面有一个叫作isHidden的方法。咱们能够把它看作一个函数,接受一个File,返回一个boolean值.但要用它作筛选,你须要把它包在一个 FileFilter 对象里,而后传递给 File.listFiles 方法,以下所示:code
File[] hiddenFiles = new File(".").listFiles(new FileFilter() { public boolean accept(File file) { return file.isHidden(); } });
呃!真可怕!虽然只有三行,但这三行可真够绕的。咱们第一次碰到的时候确定都说过:“非 得这样不可吗?”咱们已经有一个方法 isHidden 可使用,为何非得把它包在一个啰嗦的 FileFilter 类里面再实例化呢?由于在Java 8以前你必须这么作!对象
java8的作法以下,blog
File[] hiddenFiles = new File(".").listFiles(File::isHidden);
哇!酷不酷?你已经有了函数 isHidden ,所以只需用Java 8的方法引用 :: 语法(即“把这 个方法做为值”)将其传给 listFiles 方法;请注意,咱们也开始用函数表明方法了。稍后咱们会解释这个机制是如何工做的排序
在软件工程中,一个众所周知的问题就是,无论你作神吗,用户的需求都会变。
一种可能的解决方案是对你的选择标准建模:你考虑的是苹果,须要根据 Apple 的某些属性(好比它是绿色的吗?重量超过150克吗?)来返回一个boolean 值。咱们把它称为谓词(即一个返回 boolean 值的函数)。
让咱们定义一个接口来对选择标准建模:
public interface ApplePredicate{ boolean test (Apple apple); }
如今你就能够用 ApplePredicate 的多个实现表明不一样的选择标准了,好比(如图2-1所示):
public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){ List<Apple> result = new ArrayList<>(); for(Apple apple: inventory){ if(p.test(apple)){ result.add(apple); } } return result; }
作到此处,你已经很NB了,filterApples的行为取决于你经过ApplePredicate对象传递的代码,换句话说,你把filterApples方法的行为参数化了。
但使人遗憾的是,因为该 filterApples 方法只能接受对象,因此你必须把代码包裹在 ApplePredicate 对象里。你的作法就相似于在内联“传递代码”,由于你是经过一个实现了 test 方法的对象来传递布尔表达式的。
经过使用Lambda,你能够直接把表达式 "red".equals(apple.getColor()) &&apple.getWeight() > 150 传递给 filterApples 方法,而无需定义多个 ApplePredicate类,从而去掉没必要要的代码。
其代码传递过程以下:
public interface Predicate<T>{ boolean test(T t); } public static <T> List<T> filter(List<T> list, Predicate<T> p){ List<T> result = new ArrayList<>(); for(T e: list){ if(p.test(e)){ result.add(e); } } return result; }
如今你能够把 filter 方法用在香蕉、桔子、 Integer 或是 String 的列表上了。这里有一个
使用Lambda表达式的例子:
List<Apple> redApples = filter(inventory, (Apple apple) -> "red".equals(apple.getColor())); List<Integer> evenNumbers = filter(numbers, (Integer i) -> i % 2 == 0);
酷不酷?你如今在灵活性和简洁性之间找到了最佳平衡点,这在Java 8以前是不可能作到的!