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

1. java8新特性

1.1 新特性介绍

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

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

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

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

:此处使用的是匿名内部类,整体嘛,感觉还可以

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

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

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

2. Lambda函数

编程语言中的函数一词通常指的是方法。java8中新增了函数----值得一种新形式。作为值的函数有何益处,Java8的设计者允许方法作为值,让编程更轻松。

java8的第一个新功能就是方法引用。比方说你想要筛选一个目录中所有隐藏的文件。你需要编写一个方法,然后给它一个File,它就会告诉你文件是不是隐藏的。幸好,File 类面有一个叫做isHidden的方法。我们可以把它看做一个函数,接受一个File,返回一个boolean值.但要用它做筛选,你需要把它包在一个 FileFilter 对象里,然后传递给 File.listFiles 方法,如下所示:

File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
	public boolean accept(File file) {
		return file.isHidden();
	}
});

呃!真可怕!虽然只有三行,但这三行可真够绕的。我们第一次碰到的时候肯定都说过:“非 得这样不可吗?”我们已经有一个方法 isHidden 可以使用,为什么非得把它包在一个啰嗦的 FileFilter 类里面再实例化呢?因为在Java 8之前你必须这么做!

java8的做法如下,

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值