Java8新特性
接口中默认方法修饰为普通方法
在jdk8之前,interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的,由于这些修饰符都是默认的。
接口定义方法:public 抽象方法 需要子类实现
接口定义变量:public、static、final
在JDK 1.8开始 支持使用static和default 修饰 可以写方法体,不需要子类重写。
方法:
普通方法 可以有方法体
抽象方法 没有方法体需要子类实现 重写。
代码案例
/**
* @ClassName JDK8Interface
* @Author
* @Version V1.0
**/
public interface JDK8Interface {
void addOrder();
/**
* 默认方法 可以写方法体
*/
default void getDefaultOrder() {
System.out.println("我是默认方法 我可以写方法体");
}
static void getStaticOrder() {
System.out.println("我是静态的方法 可以写方法体");
}
}
/**
* @ClassName JDK8InterfaceImpl
* @Author
* @Version V1.0
**/
public class JDK8InterfaceImpl implements JDK8Interface {
/**
* 默认和静态方法不是我们的抽象方法 ,所以不需要重写
*/
@Override
public void addOrder() {
System.out.println("addOrder");
}
}
Lambda表达式
什么是Lambda表达式
LAMBADA 好处: 简化我们匿名内部类的调用。
Lambda+方法引入 代码变得更加精简。
Lambda 表达式(lambda expression)是一个匿名函数,简化我们调用匿名函数的过程。
百度百科介绍:
https://baike.baidu.com/item/Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F/4585794?fr=aladdin
为什么要使用Lambda表达式
可以非常简洁的形式调用我们的匿名函数接口。
public static void main(String[] args) {
// 1.使用new的实现类的形式调用接口
OrderService orderSerivce1 = new OrderSerivceImpl();
orderSerivce1.addOrder();
// 2.使用匿名内部接口调用
new OrderService() {
@Override
public void addOrder() {
System.out.println("使用匿名内部类的形式调用接口");
}
}.addOrder();
// 3.使用lambda调用接口
OrderService orderSerivce2= ()-> System.out.println("使用lambda调用接口");
orderSerivce2.addOrder();
}
Lambda表达式的规范
使用Lambda表达式 依赖于函数接口
-
在接口中只能够允许有一个抽象方法
-
在函数接口中定义object类中方法
-
使用默认或者静态方法
-
@FunctionalInterface 表示该接口为函数接口
Java中使用Lambda表达式的规范,必须是为函数接口
函数接口的定义:在该接口中只能存在一个抽象方法,该接口称作为函数接口
Java中的Lambda表达式的规范,必须是为函数接口。
函数接口的定义:在该接口中只能存在一个抽象方法,该接口称作为函数接口
JDK中自带的函数接口:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
我们也可以使用@FunctionalInterface修饰为函数接口
函数接口定义
-
在接口中只能有一个抽象方法
-
@FunctionalInterface 标记为该接口为函数接口
-
可以通过default 修饰为普通方法
-
可以定义object类中的方法
@FunctionalInterface
public interface MyFunctionalInterface {
void add();
default void get() {
}
String toString();
}
Java系统内置那些函数接口
消费型接口:
Conusmer<T>
void accept(T t);
BiConusmer<T,U>
void accept(T t,U u);//增加一种入参类型
供给型接口
Supplier<T>
void get();
函数型接口
Function<T ,R>
R apply(T t);
UnaryOperator<T>
T apply(T t);//入参与返回值类型一致
BiFunction <T ,U,R>
R apply(T t,U u);//增加一个参数类型
BinaryOperator<T>
T apply(T t1,T t2);//l两个相同类型入参与同类型返回值
ToIntFunction<T>//限定返回int
ToLongFunction<T>//限定返回long
ToDoubleFunction<T>//限定返回double
IntFunction<R>//限定入参int,返回泛型R
LongFunction<R>//限定入参long,返回泛型R
DoubleFunction<R>//限定入参double,返回泛型R
断言型接口
Predicate<T>
boolean test(T t);
Lambda基础语法
()—参数列表
-> 分隔
{} 方法体
(a,b)->{}
无参方法调用
带参数方法调用
(函数接口的参数列表 不需要写类型 需要定义参数名称)->{方法体}
():函数方法参数列表
->分隔 {}方法体
(a,b)->{ Sout(a,b) }
Lambda语法:
():参数列表
->分隔
{}:方法体
()->{}
无参方法调用
public interface AcanthopanaxInterface {
void get();
}
AcanthopanaxInterface acanthopanaxInterface = () -> {
System.out.println("使用lamdba表达式调用方法");
};
acanthopanaxInterface.get();
带参数和返回值
@FunctionalInterface
public interface YouShenInterface {
String get(int i, int j);
}
/**
* @ClassName Test04
* @Author
* @Version V1.0
**/
public class Test04 {
public static void main(String[] args) {
// 1.使用匿名内部类调用有参数函数方法
// String result = new YouShenInterface() {
// @Override
// public String get(int i, int j) {
// return i + "-" + j;
// }
// }.get(1, 1);
// System.out.println(result);
//2.使用lamdba 调用有参数函数方法
YouShenInterface youShenInterface = (i, j) -> {
System.out.println("kt:" + i + "," + j);
return i + "-" + j;
};
System.out.println(youShenInterface.get(1, 1));
}
}
精简语法
// 1.精简写法优化
// AcanthopanaxInterface acanthopanaxInterface = () -> {
// System.out.println("kt");
// };
// acanthopanaxInterface.get();
// 2.精简改为: 如果方法体中只有一条语句的情况下 可以不需要写{}
AcanthopanaxInterface acanthopanaxInterface2 = () ->
System.out.println("kt");
acanthopanaxInterface2.get();
;
//3.如果方法体只有一条return的情况下不需要些{} 和return
// YouShenInterface youShenInterface = (i, j) -> {
// return i + "-" + j;
// };
// 优化后
YouShenInterface youShenInterface2 = (i, j) -> i + "-" + j;
System.out.println(youShenInterface2.get(1, 2));
方法引入
什么是方法引入
方法引入:需要结合lambda表达式能够让代码变得更加精简。
-
匿名内部类使用
-
Lambda调用匿名内部类
-
方法引入
方法引入
-
静态方法引入: 类名::(静态)方法名称
-
对象方法引入 类名:: 实例方法名称
-
实例方法引入 new对象 对象实例::方法引入
-
构造函数引入 类名::new
需要遵循一个规范:
方法引入 方法参数列表、返回类型与函数接口参数列表与返回类型必须
要保持一致。
Lambda: 匿名内部类使用代码简洁问题。
类型 | 语法 | 对应lambda表达式 |
---|---|---|
构造器引用 | Class::new | (args) -> new 类名(args) |
静态方法引用 | Class::static_method | (args) -> 类名.static_method(args) |
对象方法引用 | Class::method | (inst,args) -> 类名.method(args) |
实例方法引用 | instance::method | (args) -> instance.method(args) |
方法引用提供了非常有用的语法,可以直接引用已有的java类或对象的方法或构造器。方法引用其实也离不开Lambda表达式,
与lambda联合使用 ,方法引用可以使语言的构造更加紧凑简洁,减少冗余代码。
方法引用提供非常有用的语法,可以直接引用已有的java类或者对象中方法或者构造函数,
方法引用需要配合Lambda表达式语法一起使用减少代码的冗余性问题。
构造器引入
静态方法引入
对象方法引入
实例方法引入
方法引入规则
方法引入实际上就是lambda表达式中直接引入的方法。
必须遵循规范:引入的方法参数列表返回类型必须要和函数接口参数列表、返回
类型保持一致。
静态方法引入
import com.kt.service.MessageInterface;
/**
* @ClassName MethodReference
* @Author
* @Version V1.0
**/
public class MethodReference {
public static void main(String[] args) {
// 1.使用匿名内部类的形式 调用get方法
// new MessageInterface() {
// @Override
// public void get() {
// MethodReference.getMethod();
// }
// }.get();
MessageInterface messageInterface2 = () -> {
MethodReference.getStaticMethod();
};
messageInterface2.get();
// 使用方法引入调用方法 必须满足:方法引入的方法必须和函数接口中的方法参数列表/返回值一定保持一致。
MessageInterfa