java1.8新特性-lambda表达式

  • 什么是lambda表达式

长期以来,java为了保持简单性和一致性,拒绝给变量赋值成“一段代码”,如果你想把“一段代码”赋给一个Java变量,应该怎么做呢?这个“一段代码”就是lambda表达式。

  • 为什么引入lambda表达式

lambo表达式是一个可传递的代码块,具体介绍语法之前,先来看看我们在java中的哪些地方用过这种代码块。比如:

public static void main(String[] args) {
   String[] planets = new String[] {  "宋大宝", "大沈阳", "张三疯子", "腾", "夏洛特", "赵四","刘小能" };
		Arrays.sort(planets, new Comparator<String>() {

			@Override
			public int compare(String first, String second) {
				return first.length() - second.length();
			}
		});

		System.out.println(Arrays.toString(planets));
  
    }

这段代码大家应该很熟悉,是用sort方法传入一个Comparator对象进行list排序。

这其中有一个特点是构造出Comparator对象,compare包含一段代码来完成对“一段代码”的传递。

到目前为止,在java中传递一个代码段并不容易,不能直接传递代码段。java是一种面向对象语言,所以必须构造一个对象。这个对象的类需要有一个方法能包含所需的代码。

  • lambda表达式的语法

再来考虑上面讨论排序的例子。我们传入代码来检查一个字符串是否比另一个字符串短。这里要计算:

first.length() - second.length()

first和second是什么?他们都是字符串。java是一种强类型语言,所以我们还要指定它们的类型:

(String first, String second)
    -> first.length() - second.length()

这就是你看到的第一个lambda表达式。lambda表达式就是一个代码块,以及必须传入代码的变量规范。

至此,我们可以看出lambda表达式形式:

(参数) -> 一个表达式或一段代码

如果想传入的代码很多无法放在一个表达式中,就可以像写方法一样,把这些代码放在{}中,并包含显示的return语句。例如:

(String first, String second) ->
{
    if(first.length() < second.length()) return -1;
    else if(first.length() > second.length()) return 1;
    else return 0;
}

如果没有参数怎么办?仍然要提供空括号,就像无参数方法一样:

() -> { for(int i = 100; i>=0; i++) System.out.println(i); }

如果可以推导出一个lambda表达式的参数类型,则可以忽略其类型。例如:

Comparator<String> comp = (first, second) -> first.length - second.length;

在这里,编译器可以推导出first和second必然是字符串。因为lambda表达式将赋给一个字符串比较器。

如果方法只有一个参数,而且这个参数的类型可以推导得出。那么甚至还可以省略小括号:

Timer t = new Timer(1000, event -> 
			System.out.println("The time is:" + new Date()));

实例代码:

package com.lambda;

import java.util.Arrays;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class LambdaTest {

	public static void main(String[] args) {
		String[] planets = new String[] { "宋大宝", "大沈阳", "张三疯子", "腾", "夏洛特", "赵四", "刘小能" };
		System.out.println(Arrays.toString(planets));
		System.out.println("排序:");
		Arrays.sort(planets);
		System.out.println(Arrays.toString(planets));
		System.out.println("根据长度排序:");
		Arrays.sort(planets, (first, second) -> first.length() - second.length());
		System.out.println(Arrays.toString(planets));

		Timer t = new Timer(1000, event -> 
			System.out.println("The time is:" + new Date()));
		t.start();

		JOptionPane.showMessageDialog(null, "退出?");
		System.exit(0);

	}

}
  • ArrayList的removeIf方法

试想如果当前我们需要清除list中所有null值,可以有如下写法:

 List<String> list = new ArrayList<String>();
		 list.add("宋大宝");
		 list.add("大沈阳");
		 list.add(null);
        System.out.println("初始时:"+ list.toString());
	        for(int i=0;i<list.size();i++) {
	        	if(list.get(i) == null) {
	        		list.remove(i);
	        	}
	        }
        System.out.println("过滤完:" + list.toString());

java1.8的ArrayList新增了一个removeIf方法,一行代码搞定:

list.removeIf(e -> e == null);

removeIf方法的参数是一个Predicate接口。这个接口专门用来传递lambda表达式:

public interface Predicate < T >
{
boolean test ( T t ) ;
// Additional default and static methods
}

猜你喜欢

转载自blog.csdn.net/wenwen513/article/details/82822918