前提
之前的博客中讲过lambda的使用以及语法,官方对lambda的使用还做了进一步的优化。
方法引用
传递给Lambda体的操作,已经有实现的方法了,就可以使用方法引用!实现抽象方法的参数列表,必须与方法引用方法的参数列表与返回值类型保持一致。使用操作符“::”将方法名和对象或类名分隔开。
(可以理解为方法引用是Lambda表达式的另外一种表现形式)
1、对象::实例方法
// 使用lambda表达式
Consumer<String> com = (e) -> System.out.println(e);
com.accept("def");
// 使用的方法引用
Consumer<String> con = System.out::println;
con.accept("abc");
Employess employess = new Employess();
//使用lambda
Supplier<String> supplier = () -> employess.getName();
String str = supplier.get();
System.out.println(str);
// 方法引用
Supplier<Integer> sup2 = employess::getAge;
System.out.println(sup2.get());
2、类::静态方法
//使用lambda
Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
int compare = comparator.compare(18, 23);
System.out.println(compare);
//方法引用
Comparator<Integer> com2 = Integer::compare;
int i = com2.compare(18, 23);
System.out.println(i);
3、类::实例方法名
BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
BiPredicate<String, String> bp2 = String::equals;
注意:lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method
构造器引用
1、ClassName::new
//lambda 表达式
Supplier<Employess> sup = () -> new Employess();
Employess emp1 = sup.get();
//构造器引用方式
Supplier<Employess> sup2 = Employess::new;
Employess emp2 = sup2.get();
注意:需要调用的构造器的参数列表与函数式接口中抽象方法的参数列表保持一致!
数组引用
1、type[]::new
Function<Integer, String[]> fun = (x) -> new String[x];
String[] strs = fun.apply(10);
System.out.println(strs.length);
Function<Integer, String[]> fun2 = String[]::new;
String[] str2 = fun2.apply(20);
System.out.println(str2.length);
接口中默认方法
Java 8中允许接口中包含具有具体实现的方法,该方法称为“默认方法”,默认方式使用defalut关键字修饰。
@FunctionalInterface
public interface MyFunction {
/**
* 接口
* @param string 字符串
* @return 是否
*/
String getValue(String string);
/**
* 默认方法
* @param name 姓名
*/
default void getName(String name) {
System.out.println(name);
}
}
@Test
public void test8() {
MyFunction myFunction = new MyFunction() {
@Override
public String getValue(String string) {
return string;
}
};
myFunction.getName("接口的默认方法");
}
接口默认方法的“类优先”原则
若一个接口中定义了一个默认方法,另外一个父类或接口中同样定义了一个同名方法的时候
1、选择父类中的方法,如果父类提供具体实现,那么接口中具有相同名称和参数的默认方法会被忽视
2、接口冲突。同时实现的两个接口具有同样名称和参数列表的方法(不管是不是默认方法),都必须通过覆盖方法来解决冲突。
注意:默认方法的作用域是default
Java四种作用域
1.public:可以被其他所有类访问
2.protected:可以被自身,子类,以及同一包下的类访问。
3.default:可以被自身和同一包中的类访问。
4.private:只可以被自身访问。
结合自身项目结合微服务来说,针对服务内部自身使用的接口,在service层就可以写成默认方法,这样可以在一定程度上提高开发以及调试的速度。
接口中静态方法
Java8 中,接口中允许添加静态方法
@FunctionalInterface
public interface MyFunction {
/**
* 静态方法
*/
static void show() {
System.out.println("我是接口中的静态方法");
}
}
@Test
public void test9() {
MyFunction.show();
}
总结
Java8 中这几种新特性简化开发步骤,进一步提高开发效率!面对新的事物,积极的去尝试,相信没有一种付出会被荒废!