java8 (一):为神马要学习java8?

1. java8新特性

1.1 新特性介绍

简而言之,java8的新特性就是:Lamdba函数(匿名函数),流,默认方法。java

Java8 的灵活使用,会使得代码可读性更好(前提是你的同事也使用,别人不会,你强行使用,会被喷的!!!)、简洁易懂编程

1.2 示例展现(对库存中的苹果按照苹果排序)


  • 之前的写法
Collections.sort(inventory, new Comparator<Apple>() {
        public int compare(Apple a1, Apple a2){
            return a1.getWeight().compareTo(a2.getWeight());
        }
});

:此处使用的是匿名内部类,总体嘛,感受还能够app

  • java8的写法
invertory.sort(comparing(Apple:getWeight))

:此处使用的是Lambda表达式,它念起来就是“给库存排序,比较苹果的重量”编程语言

到此处,你可能不太明白Java8为神马能够一行代码搞定排序这个逻辑,不过,经过此处也见识了Java8的强大了,下面让咱们总体认识一下。函数

2. Lambda函数

编程语言中的函数一词一般指的是方法。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 方法;请注意,咱们也开始用函数表明方法了。稍后咱们会解释这个机制是如何工做的排序

3. 行为参数化传递代码

在软件工程中,一个众所周知的问题就是,无论你作神吗,用户的需求都会变。

一种可能的解决方案是对你的选择标准建模:你考虑的是苹果,须要根据 Apple 的某些属性(好比它是绿色的吗?重量超过150克吗?)来返回一个boolean 值。咱们把它称为谓词(即一个返回 boolean 值的函数)。

3.1. 建模

让咱们定义一个接口来对选择标准建模:

public interface ApplePredicate{
	boolean test (Apple apple);
}

3.2 写抽象实例类

如今你就能够用 ApplePredicate 的多个实现表明不一样的选择标准了,好比(如图2-1所示):

3.3根据抽象条件筛选

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类,从而去掉没必要要的代码。

其代码传递过程以下:

3.4 经过匿名内部类的方式比较简单,请自行尝试

3.5 经过Lambda表达式

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以前是不可能作到的!

相关文章
相关标签/搜索