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);
}