JDK1.8新特性1

JDK1.8新特性1

  • JDK1.8新特性:
    • Lambda表達式:
      • 使用:
        • 無參數無返回值:
        • 單參數無返回值:
        • 多參數無返回值:
        • 多參數有返回值:
      • 案例:
        • 案例1:
        • 案例2:
        • 案例3:
    • 函數式接口:
      • 四大核心函數式接口:
        • 衍生接口:
        • 使用:
          • 使用1:
          • 使用2:
    • 方法、構造方法和數組引用:
      • 方法引用:
        • 對象::實例方法
        • 類名::靜態方法
        • 類名::實例方法
      • 構造方法引用:
      • 數組引用:

JDK1.8新特性:

  1. 速度更快 - 優化底層源碼,比如HashMap、ConcurrentHashMap。
  2. 代碼更少 - 添加新的語法Lambda表達式。
  3. 強大的Stream API。
  4. 便于并行。
  5. 最大化減少空指針異常 - Optional。

?
?

Lambda表達式:

Lambda是一個匿名函數(方法), 允許把函數作為一個方法的參數 。
?
作用:

? ? ? ? ?1. 一般都是優化匿名內部類。

? ? ? ? ?2. 利用Lambda表達式可以寫出更簡潔、更靈活的代碼。

?

使用:

tips:

  1. 重寫方法的形參只有一個時,可以不加小括號。
  2. Lambda表達式當中不允許聲明一個與局部變量同名的參數或者局部變量。
  3. Lambda表達式中訪問外層的局部變量,外層的局部變量自動變成隱式常量,默認添加final。
  4. 重寫方法的形參同時加類型或同時不加類型。

?

無參數無返回值:

當匿名內部類中只有一個方法時。

public interface I1 {public void method();
}
public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic void method() {System.out.println("使用傳統匿名內部類的方式");}};i1.method();//當匿名內部類中只有一個方法時,才能使用lambda表達式這樣簡化。I1 i2 = ()->{System.out.println("使用lambda表達式的方式");};i2.method();//當匿名內部類中只有一個方法時,才能使用lambda表達式這樣簡化。I1 i3 = ()->System.out.println("使用lambda表達式的方式");i3.method();}
}

?
?

單參數無返回值:

當匿名內部類中只有一個方法,且該方法只有一個參數。

public interface I1 {public void method(String str);
}
public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic void method(String str) {System.out.println("使用傳統匿名內部類的方式:" + str);}};i1.method("今天天氣真好!");I1 i2 = (String str)->{System.out.println("使用lambda表達式的方式:" + str);};i2.method("今天天氣真好!");I1 i3 = (String str)->System.out.println("使用lambda表達式的方式:" + str);i3.method("今天天氣真好!");//省略參數的數據類型I1 i3 = (str)->System.out.println("使用lambda表達式的方式:" + str);i3.method("今天天氣真好!");//省略方法的小括號//方法的形參只有一個時,可以不加小括號。I1 i4 = str->System.out.println("使用lambda表達式的方式:" + str);i4.method("今天天氣真好!");}
}

?
?

多參數無返回值:

當匿名內部類中只有一個方法,且該方法只有多個參數。

public interface I1 {public void method(String str,int i);
}
public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic void method(String str, int i) {System.out.println("使用傳統匿名內部類的方式:" + str + " -- " + i);}};i1.method("今天天氣真好!", 666);I1 i2 = (String str,int i)->{System.out.println("使用lambda表達式的方式:" + str + " -- " + i);};i2.method("今天天氣真好!", 777);I1 i3 = (String str,int i)->System.out.println("使用lambda表達式的方式:" + str + " -- " + i);i3.method("今天天氣真好!", 888);//多個參數時,參數的數據類型要么全部去掉,要么全部保留。I1 i4 = (str, i)->System.out.println("使用lambda表達式的方式:" + str + " -- " + i);i4.method("今天天氣真好!", 999);}
}

多個參數時,參數的數據類型要么全部去掉,要么全部保留。

?
?

多參數有返回值:

當匿名內部類中只有一個方法,且該方法只有多個參數,且有返回值時。

public interface I1 {public String method(int a,int b);
}
public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic String method(int a, int b) {return "使用傳統匿名內部類的方式:" + (a+b);}};String method = i1.method(10, 10);System.out.println(method);I1 i2 = (int a,int b)->{return "使用lambda表達式的方式:" + (a+b);};String method = i2.method(20, 20);System.out.println(method);I1 i3 = (a, b)-> "使用lambda表達式的方式:" + (a+b);String method = i3.method(30, 30);System.out.println(method);}
}

?
?

案例:

案例1:

調用Collections.sort()方法,通過定制排序比較兩個Student對象(先按年齡比較,年齡相同按照薪資比較),使用Lambda表達式作為參數傳遞。

//枚舉
public enum Course {JAVA,HTML,PYTHON;
}
public class Student {private String name;private int age;private double salary;private Course course;public Student() {}public Student(String name, int age, double salary, Course course) {this.name = name;this.age = age;this.salary = salary;this.course = course;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((course == null) ? 0 : course.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());long temp;temp = Double.doubleToLongBits(salary);result = prime * result + (int) (temp ^ (temp >>> 32));return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Student other = (Student) obj;if (age != other.age)return false;if (course != other.course)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))return false;return true;}@Overridepublic String toString() {StringBuilder builder = new StringBuilder();builder.append("Student [name=");builder.append(name);builder.append(", age=");builder.append(age);builder.append(", salary=");builder.append(salary);builder.append(", course=");builder.append(course);builder.append("]");return builder.toString();}}
public static void main(String[] args) {List<Student> stuList = Arrays.asList(new Student("張三", 28, 4800,Course.JAVA),new Student("李四", 36, 7200,Course.JAVA),new Student("王五", 19, 9600,Course.HTML),new Student("趙六", 42, 6100,Course.HTML),new Student("孫七", 23, 9600,Course.PYTHON),new Student("吳八", 28, 3000,Course.PYTHON));//匿名內部類的方式
//		Collections.sort(stuList, new Comparator<Student>() {
//			@Override
//			public int compare(Student o1, Student o2) {
//				if(o1.equals(o2)){
//					return 0;
//				}
//				
//				int compare = Integer.compare(o1.getAge(), o2.getAge());
//				if(compare != 0){
//					return compare;
//				}
//				
//				return Double.compare(o1.getSalary(), o2.getSalary());
//			}
//		});Collections.sort(stuList, (o1,o2)->{if(o1.equals(o2)){return 0;}int compare = Integer.compare(o1.getAge(), o2.getAge());if(compare != 0){return compare;}return Double.compare(o1.getSalary(), o2.getSalary());});for (Student stu : stuList) {System.out.println(stu);}}

?
?

案例2:

創建I1接口,創建抽象方法:public String getValue(String str),在測試類中編寫方法使用接口作為參數,將一個字符串轉為大寫,并作為方法的返回值。

public class Test01 {public static void main(String[] args) {String str = method("abc", (x)-> {return x.toUpperCase();});System.out.println(str);}public static String method(String str,I1 i1){return i1.getValue(str);}
}interface I1{public String getValue(String str);
}

?
?

案例3:

創建I1<T,R>接口,泛型T為參數,R為返回值,創建抽象方法:public R add(T t1,T t2),在測試類中編寫方法使用接口作為參數,計算兩個long類型的和。

public class Test01 {public static void main(String[] args) {long addLong = addLong(100,200,(a,b)->{return a+b;});System.out.println(addLong);}public static long addLong(long l1,long l2,I1<Long,Long> i1){return i1.add(l1, l2);}
}interface I1<T,R>{public R add(T t1,T t2);
}

?
?
?

函數式接口:

? 函數式接口:是指僅僅只包含一個抽象方法的接口,jdk1.8提供了一個@FunctionalInterface注解來定義函數式接口,如果我們定義的接口不符合函數式的規范便會報錯。配合Lambda表達式一起使用。

?
?

四大核心函數式接口:

? 應用場景:當項目中需要一個接口,并且該接口中只有一個抽象方法,就沒必要去創建新的接口,直接選擇Java提供的使用合適的函數式接口即可。

函數式接口參數類型返回類型用途
Consumer 消費型接口Tvoidvoid accept(T t);
Supplier 供給型接口voidTT get();
Function<T, R> 函數型接口TRR apply(T t);
Predicate 斷言型接口Tbooleanbooelan test(T t);

?

衍生接口:
函數式接口參數類型返回類型用途
BiConsumer<T, U>T,Uvoid對類型為T,U參數應用操作。包含方法為void accept(T t,U u);
BiFunction<T, U, R>T,UR對類型為T,U參數應用操作,并返回R類型的結果。包含方法為R apply(T t,U u);
UnaryOperator extends Function<T, T>TT對類型為T的對象進行一元運算,并返回T類型的結果。包含方法為T apply(T t);
BinaryOperator extends BiFunction<T,T,T>T,TT對類型為T的對象進行二元運算,并返回T類型的結果。包含方法為T apply(T t1,T t2);
ToIntFunction ToLongFunction ToDoubleFunctionTint long double分別計算int、long、double值的函數
IntFunction LongFunction DoubleFunctionint long doubleR參數為int、long、double類型的函數

?
?
?

使用:
使用1:

創建I1接口,創建抽象方法:public String getValue(String str),在測試類中編寫方法使用接口作為參數,將一個字符串轉為大寫,并作為方法的返回值。

public class Test01 {public static void main(String[] args) {String str = method("abc", (x)-> {return x.toUpperCase();});System.out.println(str);}//Function函數式接口public static String method(String str,Function<String, String> fun){//apply函數式接口的方法return fun.apply(str);}
}

?
?
再更新:

public class Test01 {public static void main(String[] args) {String str = method("abc", (x)->{return x.toUpperCase();});System.out.println(str);}//UnaryOperator函數式接口public static String method(String str,UnaryOperator<String> uo){apply函數式接口的方法return uo.apply(str);}
}

?
?
?

使用2:

創建I1<T,R>接口,泛型T為參數,R為返回值,創建抽象方法:public R add(T t1,T t2),在測試類中編寫方法使用接口作為參數,計算兩個long類型的和。

public class Test01 {public static void main(String[] args) {long addLong = addLong(100,200,(a,b)->{return a+b;});System.out.println(addLong);}public static long addLong(long l1,long l2,BiFunction<Long,Long,Long> bf){return bf.apply(l1, l2);}
}

?
?

再更新:

public class Test01 {public static void main(String[] args) {long addLong = addLong(100,200,(a,b)->{return a+b;});System.out.println(addLong);}public static long addLong(long l1,long l2,BinaryOperator<Long> bo){return bo.apply(l1, l2);}
}

?
?
?

方法、構造方法和數組引用:

方法、構造方法和數組引用就是Lambda的另一種表現形式,可以簡化Lambda表達式。

?
?

方法引用:

若Lamdba表達式中的內容由方法已經實現了,可以使用方法引用這個技能,當你需要使用方法引用時,目標引用放在分隔符::前,方法的名稱放在后面。

?

對象::實例方法

Lambda表達式中調用方法的參數類型和返回值必須和函數式接口中的抽象方法一致。

public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic void method(String str) {//println方法無返回值,一個參數,參數類型是StringSystem.out.println(str);}};i1.method("今天天氣真好!");I1 i2 = (str)->System.out.println(str);i2.method("今天天氣真好!");// 因為  method方法無返回值,一個參數,參數類型是String,//且println方法無返回值,一個參數,參數類型是String//故可以使用方法的引用I1 i3 = System.out::println;i3.method("今天天氣真好!");}
}interface I1{//method無返回值,一個參數,參數類型是Stringpublic void method(String str);
}

因為 method 方法無返回值,一個參數,參數類型是 String ,且 println 方法無返回值,一個參數,參數類型是 String ,一 一對應,故可以使用方法的引用。

?
?

類名::靜態方法

Lambda表達式中調用方法的參數類型和返回值必須和函數式接口中的抽象方法一致。

public class Test01 {public static void main(String[] args) {Comparator<Integer> comparator = new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return Integer.compare(o1, o2);}};int compare1 = comparator.compare(10, 20);System.out.println(compare1);Comparator<Integer> comparator = (o1,o2)-> Integer.compare(o1, o2);int compare2 = comparator.compare(10, 20);System.out.println(compare2);Comparator<Integer> comparator = Integer::compare;int compare3 = comparator.compare(10, 20);System.out.println(compare3);}
}

?
?

類名::實例方法

? Lambda表達式參數列表中第一個參數必須是實例方法的調用者,第二個參數必須是實例方法的參數

public class Test01 {public static void main(String[] args) {I1<String> i1 = new I1<String>() {@Overridepublic boolean method(String t1, String t2) {return t1.equals(t2);}};boolean method = i1.method("abc", "abc");System.out.println(method);I1<String> i2 = (str1,str2)->str1.equals(str2);boolean method2 = i2.method("abc", "abc");System.out.println(method2);//重寫method方法,該方法的第一個參數調用equals,第二個參數是傳入equals里的數據I1<String> i3 = String::equals;boolean method3 = i3.method("abc", "abc");System.out.println(method3);}
}interface I1<T>{public boolean method(T t1,T t2);
}

?
?

構造方法引用:

類名::new

需要調用的構造方法的參數列表必須和函數式接口中抽象方法的參數列表一致。

public class Test01 {public static void main(String[] args) {I1 i = new I1() {@Overridepublic Student method() {return new Student();}};Student st = i.method();System.out.println(st);//調用無參構造去創建學生對象//I1的method方法無參數I1 i1 = Student::new;Student stu1 = i1.method();System.out.println(stu1);//調用有參構造去創建學生對象//I2的method方法有參數I2 i2 = Student::new;Student stu2 = i2.method("小明", 23, 12000, Course.JAVA);System.out.println(stu2);}
}
interface I1{public Student method();
}
interface I2{public Student method(String name, int age, double salary, Course course);
}

?
?

數組引用:

type[]::new

public class Test01 {public static void main(String[] args) {//參數            方法里面的語句I1<String[]> i = (capacity)->new String[capacity];String[] s = i.method(3);System.out.println(Arrays.toString(s));I1<String[]> i1 = String[]::new;String[] ss = i1.method(3);System.out.println(Arrays.toString(ss));}
}interface I1<T>{public T method(int capacity);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20635.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20635.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20635.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

代碼隨想錄訓練營Day 42|力扣62.不同路徑、63. 不同路徑 II

1.不同路徑 代碼隨想錄 視頻講解&#xff1a;動態規劃中如何初始化很重要&#xff01;| LeetCode&#xff1a;62.不同路徑_嗶哩嗶哩_bilibili 代碼&#xff1a; class Solution { public:int uniquePaths(int m, int n) {// dp[i][j] 表示從起點走到坐標為i&#xff0c;j的地方…

全自動打包封箱機:解析其在產品質量與安全保障方面的作用

在當今快節奏的生產環境中&#xff0c;全自動打包封箱機以其高效、精準的特點&#xff0c;正逐漸成為生產線上的得力助手。它不僅提升了生產效率&#xff0c;更在產品質量與安全保障方面發揮著舉足輕重的作用。星派將詳細解析全自動打包封箱機在產品質量與安全保障方面的作用。…

css簡單介紹

1.css介紹 css指的是層疊樣式(Cascadingstyle sheets)&#xff0c;是用來給HTML標簽添加樣式的語言。他可以設置HTML頁面中 文字大小&#xff0c;顏色&#xff0c;對齊方式及元素的 寬高&#xff0c; 位置 等樣式。 一個完整的網頁是由HTML、CSS、Javascript三部分組成。HT…

CLIP--Learning Transferable Visual Models From Natural Language Supervision

參考&#xff1a;CLIP論文筆記--《Learning Transferable Visual Models From Natural Language Supervision》_visual n-grams模型-CSDN博客 openAI&#xff0c;2021&#xff0c;將圖片和文字聯系在一起&#xff0c;----->得到一個能非常好表達圖片和文字的模型主題&#…

網絡安全-釣魚篇-利用cs進行釣魚

一、環境 自行搭建&#xff0c;kill&#xff0c;Windows10&#xff0c;cs 二、原理 如圖所示 三、釣魚演示 首先第一步&#xff1a;打開System Profiler-分析器功能 選擇克隆www.baidu.com頁面做釣魚 之后我們通過包裝域名&#xff0c;各種手段讓攻擊對象訪問&#xff1a;h…

Java面試題:Redis1_Redis的使用場景和如何解決Redis緩存穿透問題

Redis使用場景常見問題 緩存 緩存三兄弟(穿透,擊穿,雪崩) 雙寫一致 持久化 數據過期策略 數據淘汰策略 分布式鎖 setnx,redisson 消息隊列,延遲隊列 … 解決Redis緩存穿透問題 緩存穿透問題 請求->redis緩存->mysql數據庫 當一個新請求到來時,先會訪問redi…

JVM(Java虛擬機)筆記

面試常見&#xff1a; 請你談談你對JVM的理解?java8虛擬機和之前的變化更新?什么是OOM&#xff0c;什么是棧溢出StackOverFlowError? 怎么分析?JVM的常用調優參數有哪些?內存快照如何抓取&#xff1f;怎么分析Dump文件&#xff1f;談談JVM中&#xff0c;類加載器你的認識…

前端最新面試題(基礎模塊HTML/CSS/JS篇)

目錄 一、HTML、HTTP、WEB綜合問題 1 前端需要注意哪些SEO 2 img的title和alt有什么區別 3 HTTP的幾種請求方法用途 4 從瀏覽器地址欄輸入url到顯示頁面的步驟 5 如何進行網站性能優化 6 HTTP狀態碼及其含義 7 語義化的理解 8 介紹一下你對瀏覽器內核的理解? 9 html…

【C++】vector常見的使用方式

前言&#xff1a;在上一篇中我們講到了string類的模擬實現&#xff0c;今天我們將進一步的去學習vector的一些常用的使用方法。 &#x1f496; 博主CSDN主頁:衛衛衛的個人主頁 &#x1f49e; &#x1f449; 專欄分類:高質量&#xff23;學習 &#x1f448; &#x1f4af;代碼倉…

命運方舟臺服注冊 命運方舟臺服怎么注冊?不會操作看這里

命運方舟臺服注冊 命運方舟臺服怎么注冊&#xff1f;不會操作看這里 命運方舟作為今年備受矚目的一款MMORPG類型游戲&#xff0c;在上線前的預約數量已經一次又一次創下新高。這款游戲的開發商Smile gate真是給玩家們帶來了一款讓人眼前一亮的作品。游戲創建在虛幻引擎的基礎…

USACO 2019 December Contest, BronzeProblem 2. Where Am I? 題解

這道題目通過例子可以看出查找最長的相同子串&#xff0c;下一個長度如果沒有找到相同的子串就是結果&#xff0c;需要寫三個循環&#xff0c;第一個循環是是否存在長度為len的相同子串&#xff0c;第二個循環是從左往右截取長度為len的子串&#xff0c;第三個循環的條件是j<…

用esp prog燒錄ESP32-C3板踩坑

附ESP32C3的GPIO一覽&#xff1a; vscode選擇Jtag燒錄&#xff0c;終端輸出esp_usb_jtag: could not find or open device&#xff1a; D:\Devtools\Espressif\tools\openocd-esp32\v0.12.0-esp32-20230921\openocd-esp32\bin\openocd.exe -f board/esp32s3-builtin.cfgOpen O…

【電路筆記】-帶阻濾波器

帶阻濾波器 文章目錄 帶阻濾波器1、概述2、典型帶阻濾波器配置3、帶阻濾波器示例14、陷波濾波器5、帶阻濾波器示例26、總結帶阻濾波器也稱為陷波濾波器,阻止并拒絕位于其兩個截止頻率點之間的頻率,并傳遞該范圍兩側的所有這些頻率。 1、概述 通過將基本 RC 低通濾波器與 RC …

Docker基礎命令(三)

同步docker容器中的時間和本地時間一致 背景: 在很多時候, 訓練模型的時候, 記錄的log日志中標記的時間和實際的時間不一致, 往往是容器時間和本地時間不一致照成的. 方案 場景一: 正在運行的容器&#xff0c;可以宿主機直接執行命令給某個容器同步時間 #方法1 直接在宿主機…

ElasticSearch教程(詳解版)

本篇博客將向各位詳細介紹elasticsearch&#xff0c;也算是對我最近學完elasticsearch的一個總結&#xff0c;對于如何在Kibana中使用DSL指令&#xff0c;本篇文章不會進行介紹&#xff0c;這里只會介紹在java中如何進行使用&#xff0c;保證你看完之后就會在項目中進行上手&am…

Arduino燒錄esp8266

default_encoding: cp936 Assume aggressive ‘core.a’ caching enabled. Note: optional global include file ‘arduino_modified_sketch_764314\Blink.ino.globals.h’ does not exist. Read more at https://arduino-esp8266.readthedocs.io/en/latest/faq/a06-global-bui…

【計劃】裝修相關感想

計劃 Summary 從去年年底開始規劃、設計、落實家里的裝修&#xff0c;2024年4月正式開始裝修&#xff0c;一個人探索和學習了很多知識和概念。 準備把這些東西做一些記錄和分享&#xff0c;一方面記錄一些裝修的流程和中間的小細節便于第二次裝修的時候避免&#xff1b;另一方…

Android設備實時監控藍牙的連接、配對、開關3種狀態

一、簡介 Android設備&#xff0c;需要實時監控本機藍牙連接其他藍牙設備的狀態&#xff0c;包含&#xff1a;連接、配對、開關3種狀態。本文介紹了2種方法&#xff0c;各有優勢&#xff0c;下面來到我的Studio一起瞅瞅吧~ 二、定時器任務 Handler 功能方法 定時器任務 Hand…

寫字靜不下心?不如試試這些“笨方法”

夏天悄悄熱起來啦&#xff5e;有人說&#xff0c;想踏踏實實寫一會兒&#xff0c;但又靜不下心&#xff0c;耐不住性子&#xff0c;快收下這四個小錦囊&#xff0c;與古人一起笨拙精進吧&#xff01;    1、不論輸贏      每次課前&#xff0c;暄桐林曦老師總會強調&am…

AlloyTeam Web前端大會:深入探索前端的無限可能

AlloyTeam Web前端大會&#xff1a;深入探索前端的無限可能 在數字化浪潮的推動下&#xff0c;Web前端技術日新月異&#xff0c;成為引領行業發展的重要力量。AlloyTeam Web前端大會作為業界的盛會&#xff0c;匯聚了眾多前端領域的精英&#xff0c;共同探討前端的未來發展趨勢…