`
xiao1zhao2
  • 浏览: 38962 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java中lambda表达式的使用

阅读更多

lambda表达式在SE1.8中引入,与接口中的唯一的抽象方法相匹配,语法:(参数列表)->返回值,返回值也可以通过{}和return实现.

 

1.引入lambda之前,先对一个String列表进行排序
import java.util.*;

public class LambdaDemo1 {
	public static void main(String[] args) {
		List<String> name = Arrays.asList("James", "Kobe", "Yao");
		Collections.sort(name, new Comparator<String>() {
			public int compare(String s1, String s2) {
				return s1.compareTo(s2);
			}
		});
	}
}

 静态方法Collections.sort接收一个list和一个Comparator接口作为输入参数,实现对输入的list中的元素进行比较并排序.通常可以用创建匿名Comparator对象,重写compare方法,并作为参数传递给sort方法.

如果使用lambda表达式,可以使代码更加简短易读:

Collections.sort(name, (String s1, String s2) -> {
	return s1.compareTo(s2);
});

 而且,它还可以更简短:

Collections.sort(name, (String s1, String s2) -> s1.compareTo(s2));

此段代码已经省略了{}和return,但是它还可以更短:

Collections.sort(name, (s1, s2) -> s1.compareTo(s2));

 编译器能够自动识别参数类型,类型也可以省略不写.

 

2.函数式接口

 

一个函数式接口必须有且仅有一个抽象方法声明,可以通过@FunctionalInterface标识,每个与之对应的lambda表达式必须与此相匹配.任何一个只包含一个抽象方法的接口,都可以做成lambda表达式.例:

@FunctionalInterface
interface MapDemo<K, V> {
	V get(K k);
}

public class LambdaDemo2 {

	public static void main(String[] args) {
		MapDemo<String, Integer> map = (k) -> Integer.valueOf(k);
		System.out.println(map.get("10"));
	}
}

 

考虑极端一点的话,我们可以将函数式接口中的方法定义为无参无返回值的,lambda同样可以相匹配:

@FunctionalInterface
interface MapDemo<K, V> {
	void get();
}

public class LambdaDemo2 {

	public static void main(String[] args) {
		MapDemo<String, Integer> map = () -> {};
	}
}

 

这里只是举个例子,在实际编程中并不实用.

 

3.lambda对方法及构造方法的引用

 

3.1.lambda可以通过关键字来获取方法的引用,可使第2节中的代码更加简短:
public class LambdaDemo3 {

	public static void main(String[] args) {
		MapDemo<String, Integer> map = Integer::valueOf;
		System.out.println(map.get("10"));
	}
}

 

注意,此段代码中等号右边的Integer是指Integer.valueOf()方法返回值的类型,与上一节代码中的意义不同.

 

3.2.lambda也可以通过关键字new获取构造方法的引用,例:
class A {
	String name;

	public A() {
	}

	public A(String name) {
		this.name = name;
	}
}

interface AFactory<T extends A> {
	T create(String name);
}

public class LambdaDemo3 {

	public static void main(String[] args) {
		AFactory<A> afactory = A::new;
		A a = afactory.create("name");
		System.out.println(a.name);
	}
}

 

通过A::new创建一个A类构造函数的引用.编译器会自动选择合适的构造函数来匹配A.create方法,并调用正确的构造函数.

 

4.lambda的可访问范围

 

4.1.访问局部变量,例:
public class LambdaDemo4 {

	public static void main(String[] args) {
		String s = "20";
		MapDemo<String, Integer> map = (k) -> Integer.valueOf(k + s);
		System.out.println(map.get("10"));
	}
}

 

虽然s不是final的,但此段代码是合法的,运行结果:1020.但下面的代码不合法:

		String s = "20";
		MapDemo<String, Integer> map = (k) -> Integer.valueOf(k + s);
		System.out.println(map.get("10"));
		s="30";

 可见,s在编译的时候被隐式的当做final变量来处理,在lambda内部改变s也是不可以的.

 

4.2.访问成员变量,例:
public class LambdaDemo4 {
	String s1;
	static String s2;

	public void test() {
		MapDemo<String, Integer> map1 = (k) -> {
			s1 = "100";
			return Integer.valueOf(s1);
		};

		MapDemo<String, Integer> map2 = (k) -> {
			s2 = "200";
			return Integer.valueOf(s2);
		};
	}
}

 

4.3.访问接口的静态方法和默认方法,例:
interface MapDemo<K, V> {
	V get(K k);

	static void getStatic() {

	}

	default void getDefault() {
	}
}

public class LambdaDemo4 {

	public void test() {
		MapDemo<String, Integer> map1 = (k) -> {
			MapDemo.getStatic();
			return Integer.valueOf(k);
		};
		MapDemo<String, Integer> map2 = (k) -> {
			// MapDemo.getDefault();
			return Integer.valueOf(k);
		};
	}
}

 

编译发现,静态方法在lambda表达式可以被访问,而默认方法是不可以的.

 

小结:java SE在1.8引入的lambda表达式实现了与函数式接口中方法的匹配,同时提供很多新的函数式接口,如Comparator等,使程序变得更加简短易读.

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics