1. lambda表达式。
-
Lambda表达式:特殊的匿名内部类,语法更简洁。
-
Lambda表达式允许把函数作为一个方法的参数(函数作为方法参数传递),将代码像数据一样传递。
-
基本语法
`` Lambda引入了新的操作符:–>(箭头操作符),->将表达式分成两部分
左侧: (参数1,参数2...)表示参数列表
右侧:{}内部是方法体
- 注意事项
- 形参列表的数据类型会自动推断
- 如果形参列表为空,只需保留()
- 如果形参只有1个,()可以省略,只需要参数的名称即可
- 如果执行语句只有一句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有一句
- Lambda不会生成一个单独的内部类文件
代码(接口不能实例化对象新发现)
public class Lamdb {
public static void main(String[] args) {
// Runnable runnable = new Runnable() {//匿名内部类对象
// @Override
// public void run() {
// System.out.println("这里是使用匿名内部类方法创建线程");
// }
// };
// ===================================================
//JDK1.8 知道里面的方法就一个方法。 表达式 ->
// (方法的形参)->{方法体} 必须接口中只有一个抽象方法。
// 如果方法体中只有一条语句,那么可以省略{}
// lambda表达式 ///
// (壹) Runnable runnable=()-> System.out.println("这里是使用lamdb方法创建线程");;
//(贰)
Runnable runnable = () -> {
System.out.println("哈哈,这里执行多条语句");
System.out.println("这里是使用lamdb方法创建线程");
};
// Thread thread = new Thread(runnable);
// thread.start();//启动线程执行run方法
// ==================================================
//最精简版使用lambda表达式 由 壹知左右等价,将这个类直接当成参数进行使用
Thread thread = new Thread(() -> System.out.println("这里是使用lamdb方法创建线程"));
thread.start();
}
treeset排序详情看集合框架Java10;treeset中的comparable默认比较String类,比较其它类会报错!其它实体类需要实现自然比较器Comparable接口!
lambda例子贰
public class Test01 {
public static void main(String[] args) {
// 情况壹
// TreeSet<String> treeSet = new TreeSet<>();//treset中存在排序功能
// treeSet.add("java02");
// treeSet.add("java03");
// treeSet.add("java05");
// treeSet.add("java01");
// treeSet.add("java06");
// treeSet.add("java04");
// System.out.println(treeSet);
//==========================================================
// 情况贰
// TreeSet<Person> treeSet = new TreeSet<>();
// treeSet.add(new Person(1,"张三1"));
// treeSet.add(new Person(3,"张三3"));
// treeSet.add(new Person(5,"张三5"));
// treeSet.add(new Person(2,"张三2"));
// treeSet.add(new Person(4,"张三4"));
// System.out.println(treeSet);
//=====================================================================
// 情况叁
// Comparator<Person> comparator=new Comparator<Person>() {
// @Override
// public int compare(Person o1, Person o2) {
// return o1.getId()-o2.getId();
// }
// }; //匿名内部类对象编译后会产生class文件
//lamda表达式编译后不会产生class文件
Comparator<Person> comparator=(Person o1, Person o2)->
{return o1.getId()-o2.getId();};
// Comparator<Person> comparator=( o1, o2)-> o1.getId()-o2.getId();
TreeSet<Person> treeSet = new TreeSet<>(comparator);
treeSet.add(new Person(1,"张三1"));
treeSet.add(new Person(3,"张三3"));
treeSet.add(new Person(5,"张三5"));
treeSet.add(new Person(2,"张三2"));
treeSet.add(new Person(4,"张三4"));
System.out.println(treeSet);
}
}//Comparable:自然比较器。要求类必须实现Comparable接口。如果该类没有实现comparable接口。
/*@Data
@NoArgsConstructor
@AllArgsConstructor//情况贰 解决方案实现Comparable接口
class Person implements Comparable<Person>{
private Integer id;
private String name;
@Override//0:两个元素相同。 >0表示比新添的元素大往后放(小到大) <0
public int compareTo(Person o) {
System.out.println(this.name+"========="+o.name);
return -(this.id-o.id);//this表示调用这个方法的对象,o表示传入的对象
//return -1/0/1;
}
}*/
@Data
@NoArgsConstructor
@AllArgsConstructor//情况叁 解决方案实现Comparable接口
class Person {
private Integer id;
private String name;
}
2. 函数式接口
如果一个接口只有一个抽象方法,则该接口称之为函数式接口,函数式接口可以使用Lambda表达式,Lambda表达式会被匹配到这个抽象方法上。
@Functionallnterface注解检测接口是否符合函数式接口 (可以回想@override注解)
public class Test02 {
public static void main(String[] args) {
USB upan=new USB() {
@Override //重写的方法的检验
public void service() {
System.out.println("使用upan");
}//匿名内部类
};
useUSB(upan);//调用静态方法useUSB(upan),该方法调用匿名内部类
USB shubiao=()->System.out.println("使用鼠标");//lambda表达式修改函数式接口
useUSB(shubiao);//形式贰
useUSB(()->System.out.println("使用键盘"));//形式叁,以参数形式传入进去
}
//函数式接口的应用:作为方法的参数。 调用方法时可以使用lamdba表达式。主函数中是实例
public static void useUSB(USB usb){
usb.service();
}
}
//函数式接口:接口中只有一个抽象方法。该接口就是函数式接口。
@FunctionalInterface //检验该接口是否为函数式接口
interface USB{
public void service();//服务
// void aa();加上会报错
//JDK8以后新增的特性。
default void show(){ }
static void print(){ }
}
3.JDK内置的函数式接口
常见得函数式接口
(1)消费性函数式接口:重写方法 void accept(T t)由一个参数,但是没有返回值
public class Test03 {
public static void main(String[] args) {
// 方式壹 最传统的方式进行操作
// MyConsumer myConsumer=new MyConsumer();
// fun(myConsumer,15.5);
// 方式二 匿名内部类方式
// Consumer<Double> consumer=new Consumer<Double>() {
// @Override
// public void accept(Double aDouble) {
// System.out.println("你今天洗脚消费:"+aDouble);
// }
// };
// fun(consumer,200.0);
//方式叁 lambda方式 只有一个参数可以使用下面的方式传参
// Consumer<Double> consumer= aDouble->System.out.println("你今天按摩消费:"+aDouble);
//
// fun(consumer,300.0);
=================== //供给型函数式接口方式=================================
// Supplier<String> s1=()->{
// return "你们今天只上了2个半小时,怎么办!";
// };
//
// String s = fun2(s1);
// System.out.println(s);
=========================//函数型函数式接口=================================
//R apply(T t);R表示返回类型,T表示输入值的类型
Function<Double,String> f1=t->{
return "你今天洗脚消费:"+t/10;
};
System.out.println(fun3(f1));
}
//------------------------------------------------------------------------
========================= //消费性函数式接口的使用。======================
public static void fun(Consumer<Double> consumer,Double param){
consumer.accept(param);//有形参无返回值 多态:
}
============================== //供给型函数式接口=========================
public static String fun2(Supplier<String> supplier){
return supplier.get();
}
======================//函数型函数式接口=========================
public static String fun3(Function<Double,String> function){
return function.apply(200.0);
}
}
class MyConsumer<Double> implements Consumer<Double>{
@Override
public void accept(Double aDouble) {
System.out.println("我的消费金额:"+aDouble);
}
}
=============================//断言型函数=====================================
//boolean test(T t); 断言函数式接口 有参返回值为boolean值
public static void main(String[] args) {
Predicate<Integer> predicate=t->{
boolean value= t>=18?true:false;
return value;
};
System.out.println(fun(predicate,18));
}
public static boolean fun(Predicate<Integer> predicate,int age){
return predicate.test(age);
}