java中lambda中使⽤三元,java中lambda表达式的使⽤
[最近Java 8的正式版已经推出,今天闲着没事就下载好了java 8 的jdk和jre来尝尝鲜。环境安装⾸先安装java 8的jdk 和 jre, 下载地址,安装好基础环境后, 可能对于稍微⽼⼀
lambda表达式在SE1.8中引⼊,与接⼝中的唯⼀的抽象⽅法相匹配,语法:(参数列表)->返回值,返回值也可以通过{}和return实现.
1.引⼊lambda之前,先对⼀个String列表进⾏排序
import java.util.*;
public class LambdaDemo1 {
public static void main(String[] args) {
List name = Arrays.asList("James", "Kobe", "Yao");
Collections.sort(name, new Comparator() {
public int compare(String s1, String s2) {
return s1pareTo(s2);
}
});
}
}
静态⽅法Collections.sort接收⼀个list和⼀个Comparator接⼝作为输⼊参数,实现对输⼊的list中的元素进⾏⽐较并排序.通常可以⽤创建匿名Comparator对象,重写compare⽅法,并作为参数传递给sort⽅法.
如果使⽤lambda表达式,可以使代码更加简短易读:
Collections.sort(name, (String s1, String s2) -> {
return s1pareTo(s2);
});
⽽且,它还可以更简短:
Collections.sort(name, (String s1, String s2) -> s1pareTo(s2));
此段代码已经省略了{}和return,但是它还可以更短:
Collections.sort(name, (s1, s2) -> s1pareTo(s2));
编译器能够⾃动识别参数类型,类型也可以省略不写.
2.函数式接⼝
⼀个函数式接⼝必须有且仅有⼀个抽象⽅法声明,可以通过@FunctionalInterface标识,每个与之对应的lambda表达式必须与此相匹配.任何⼀个只包含⼀个抽象⽅法的接⼝,都可以做成lambda表达式.例:
@FunctionalInterface
interface MapDemo {
V get(K k);
}
public class LambdaDemo2 {
public static void main(String[] args) {
MapDemo map = (k) -> Integer.valueOf(k);
System.out.("10"));
}
}
考虑极端⼀点的话,我们可以将函数式接⼝中的⽅法定义为⽆参⽆返回值的,lambda同样可以相匹配:
@FunctionalInterface
interface MapDemo {
void get();
}
public class LambdaDemo2 {
public static void main(String[] args) {
MapDemo map = () -> {};
}
}
这⾥只是举个例⼦,在实际编程中并不实⽤.
3.lambda对⽅法及构造⽅法的引⽤
[Java 8已经发⾏两年多,但很多⼈仍然在使⽤JDK7。对企业来说,技术上谨慎未必是坏事,但对个⼈学习⽽⾔,不去学习新技术就很可能被技术抛弃。Java 8⼀个重要的变更是引⼊L
3.1.lambda可以通过关键字来获取⽅法的引⽤,可使第2节中的代码更加简短:
public class LambdaDemo3 {
public static void main(String[] args) {
MapDemo map = Integer::valueOf;
System.out.("10"));
}
}
注意,此段代码中等号右边的Integer是指Integer.valueOf()⽅法返回值的类型,与上⼀节代码中的意义不同.
3.2.lambda也可以通过关键字new获取构造⽅法的引⽤,例:
class A {
String name;
public A() {
}
public A(String name) {
this.name = name;
}
}
interface AFactory {
T create(String name);
}
public class LambdaDemo3 {
public static void main(String[] args) {
AFactory afactory = A::new;
A a = ate("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 map = (k) -> Integer.valueOf(k + s);
System.out.("10"));
}
}
虽然s不是final的,但此段代码是合法的,运⾏结果:1020.但下⾯的代码不合法:
String s = "20";
lambda编程MapDemo map = (k) -> Integer.valueOf(k + s);
System.out.("10"));
s="30";
可见,s在编译的时候被隐式的当做final变量来处理,在lambda内部改变s也是不可以的.
4.2.访问成员变量,例:
public class LambdaDemo4 {
String s1;
static String s2;
public void test() {
MapDemo map1 = (k) -> {
s1 = "100";
return Integer.valueOf(s1);
};
MapDemo map2 = (k) -> {
s2 = "200";
return Integer.valueOf(s2);
};
}
}
4.3.访问接⼝的静态⽅法和默认⽅法,例:
interface MapDemo {
V get(K k);
static void getStatic() {
}
default void getDefault() {
}
}
public class LambdaDemo4 {
public void test() {
MapDemo map1 = (k) -> {
return Integer.valueOf(k);
};
MapDemo map2 = (k) -> {
// Default();
return Integer.valueOf(k);
};
}
}
编译发现,静态⽅法在lambda表达式可以被访问,⽽默认⽅法是不可以的.
⼩结:java SE在1.8引⼊的lambda表达式实现了与函数式接⼝中⽅法的匹配,同时提供很多新的函数式
接⼝,如Comparator等,使程序变得更加简短易读.[Lambda表达式主要是替换了原有匿名内部类的写法,也就是简化了匿名内部类的写法。lambda语法结构:(参数1,参数2...)-> {重写⽅法的内容,不定义⽅法名}先看⼀个使⽤匿名内