1.lambda表达式
- 为什么要用lambda表达式,因为可以让代码更加简练
举例:以下是常见的开启线程的方式(采用了匿名内部类的方式)
public static void main(String[] args) {//开启一个新的线程new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubSystem.out.println("新线程执行"+Thread.currentThread().getName());}}).start();System.out.println("主线程执行"+Thread.currentThread().getName());}
代码分析:代码写得很长,比较复杂,用lambda表达式的方式可以让代码精简很多,以下就是lambda表达式的写法
public static void main(String[] args) {//开启一个新的线程new Thread(() -> {System.out.println("开启一个新的lambda线程");}).start();System.out.println("主线程执行"+Thread.currentThread().getName());}
总结:简化了匿名内部类的使用,语法更加简单
- 使用前提:
方法的参数或者局部变量类型必须是接口
接口中有且仅有一个抽象方法
1、语法规则
(参数类型 参数名称)-> {代码体}
举例1:将main函数写法改成lambda方式
public static void main(String[] args) {}
(String[] args) -> {}
举例2:将以下的写法改成lambda表达式的方式
public static void main(String[] args) {toUserService(new UserService() {@Overridepublic void getName(String name) {System.out.println("你好"+name);return name;}});}public static void toUserService(UserService userService) {userService.getName("jf3q.com");}//UserServie接口如下public interface UserService {String getName(String name);}
public static void main(String[] args) {toUserService((String name) -> {System.out.println("你好-"+name); return name;});}public static void toUserService(UserService userService) {userService.getName("jf3q.com");}public interface UserService {String getName(String name);}
核心代码部分:toUserService((String name) -> {System.out.println(“你好-“+name);return name;});
2、省略写法
- ()内的参数类型可以省略
- 如果()内有且仅有一个参数,则小括号也可以省略
- 如果{}内有且仅有一个语句,可以省略大括号,return关键字以及语句分号
练习:将toUserService((String name) -> {System.out.println(“你好-“+name);return name;});简化
toUserService(name -> {System.out.println(“你好-“+name);return name;});
分析:因为{}内有两个语句,所以不满足条件3.
3、lambda和匿名内部类的对比
- 所需类型不一样
- 匿名内部类可以是类、抽象类、接口都行
- lambda表达式需要的只能是接口
- 抽象方法的数量不一样
- 匿名内部类所需接口中的抽象方法的数量是随意的
- lambda表达式所需接口中 只能有一个抽象方法
- 实现原理不一样
jdk8之前
interface 接口name{静态常量;抽象方法;}
jdk8之后增加了默认方法和静态方法
interface 接口name{静态常量;抽象方法;默认方法;静态方法;}
1、默认方法
背景
在jdk8以前会存在问题:接口中新增抽象方法的话,那么实现该接口的所有类都得重写新的抽象方法,非常不利于接口的扩展。
public class MoRenStudy {public static void main(String[] args) {A b=new B();A c=new C();}}interface A{void add();void delete();}class B implements A{@Overridepublic void add() {System.out.println("B里的add方法调用");}@Overridepublic void delete() {System.out.println("B里的delete方法调用");}}class C implements A{@Overridepublic void add() {System.out.println("C里的add方法调用");}@Overridepublic void delete() {System.out.println("C里的delete方法调用");}}
语法格式
interface 接口name{修饰符 default 返回值类型 方法名{方法体;}}
使用案例:
public class MoRenStudy {public static void main(String[] args) {A b=new B();b.delete();A c=new C();c.delete();}}interface A{void add();default void delete() {System.out.println("接口中的默认方法执行");};}class B implements A{@Overridepublic void add() {System.out.println("B里的add方法调用");}@Overridepublic void delete() {System.out.println("重写默认方法---B里的delete方法调用");}}class C implements A{@Overridepublic void add() {System.out.println("C里的add方法调用");}}
代码分析:核心代码部分
default void delete() {System.out.println("接口中的默认方法执行");};
打印出的结果就是:
这就解决了那个问题——不用重写所有接口中的抽象方法(C实现类就没重写delete方法)
2.静态方法
语法规则
interface 接口名{修饰符 static 返回值类型 方法名(){方法体}}
举例如下:
public static void main(String[] args) {A a=new B();//调用静态方法A.delete();}}interface A{void add();public static void delete(){System.out.println("静态方法执行了");}}class B implements A{@Overridepublic void add() {}//静态方法没法重写}
注意:接口中的静态方法是不能重写的,只能通过接口名.静态方法().
3.两者的区别
- 默认方法是通过实例调用,静态方法通过接口名调用
-
3.函数式接口
在jdk中提供了函数式接口的目的就是为了方便lambda表达式的。主要是在java.util.function包里
常用的几个接口:1.Supplier(生产者-生产数据的)
无参有返回值的接口,对应的lambda表达式需要提供一个返回数据的类型 ```java @FunctionalInterface public interface Supplier
{ /**
- Gets a result. *
- @return a result */ T get(); }
举例:求一个最大值的小案例1. 匿名内部类的写法(最原始的写法)```java//内部类的方法一public static void main(String[] args) {JsS jsS=new JsS();getMax(jsS);}public static void getMax(Js js){Integer max=js.jisuan();System.out.println("最大值"+max);}}interface Js{Integer jisuan();}class JsS implements Js{@Overridepublic Integer jisuan() {Integer[] integers={3,2,6,9,10};Arrays.sort(integers);return integers[integers.length-1];}}
//内部类方法二public static void main(String[] args) {getMax(new Js() {@Overridepublic Integer jisuan() {Integer[] integers={3,2,6,9,10};Arrays.sort(integers);return integers[integers.length-1];}});}public static void getMax(Js js){Integer max=js.jisuan();System.out.println("最大值"+max);}}interface Js{Integer jisuan();}
lambda表达式的写法 ```java public static void main(String[] args) {
getMax(() -> {Integer[] integers={3,2,6,9,10};Arrays.sort(integers);return integers[integers.length-1];});
}public static void getMax(Js js){Integer max=js.jisuan();System.out.println("最大值"+max);}
} interface Js{ Integer jisuan(); }
3. 采用lambda表达式和supplier结合的方法```javapublic static void main(String[] args) {getMax(() -> {Integer[] integers={3,2,6,9,10};Arrays.sort(integers);return integers[integers.length-1];});}public static void getMax(Supplier<Integer> supplier){Integer max=supplier.get();System.out.println("最大值"+max);}}
2.Consumer(消费者)
有参无返回值的接口,使用的时候需要指定一个泛型来定义参数类型
@FunctionalInterfacepublic interface Consumer<T> {/*** Performs this operation on the given argument.** @param t the input argument*/void accept(T t);
举例说明:
还是求最大值
public static void main(String[] args) {getMax((max) -> {System.out.println(max);});}public static void getMax(Consumer<Integer> consumer){Integer[] integers={3,2,6,9,10};Arrays.sort(integers);consumer.accept(integers[integers.length-1]);}
大写转小写
public static void main(String[] args) {zhuan((str) -> {System.out.println(str+"转成全小写"+str.toLowerCase());});}public static void zhuan(Consumer<String> consumer){consumer.accept("Hello word");}
3.Function
有参有返回值的接口 ```java @FunctionalInterface public interface Function
{ /**
- Applies this function to the given argument. *
- @param t the function argument
- @return the function result */ R apply(T t);
<a name="OVfi9"></a>## 4.Predicate有参且返回值是boolean类型的接口```java@FunctionalInterfacepublic interface Predicate<T> {/*** Evaluates this predicate on the given argument.** @param t the input argument* @return {@code true} if the input argument matches the predicate,* otherwise {@code false}*/boolean test(T t);
