日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【java8新特性】——方法引用(四)

發(fā)布時間:2025/3/12 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【java8新特性】——方法引用(四) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、簡介

方法引用是java8的新特性之一, 可以直接引用已有Java類或?qū)ο蟮姆椒ɑ驑?gòu)造器。方法引用與lambda表達式結(jié)合使用,可以進一步簡化代碼。
來看一段簡單代碼:

public static void main(String[] args) {List<String> strList = Arrays.asList(new String[] { "a", "c", "b" });strList.stream().sorted((s1, s2) -> s1.compareToIgnoreCase(s2)).forEach(s -> System.out.println(s));}

上述程序生成一個Stream流,對流中的字符串進行排序并遍歷打印。程序中采用lambda表達式的方式代替匿名類簡化了代碼,然而代碼中兩處lambda表達式都僅僅調(diào)用的是一個已存在的方法:String.compareToIgnoreCase、System.out.println,這種情況可以用方法引用來簡化:

public static void main(String[] args) {List<String> strList = Arrays.asList(new String[] { "a", "c", "b" });strList.stream().sorted(String::compareToIgnoreCase).forEach(System.out::println);}

對比一下可以看到,上述程序分別采用了類的任意對象的實例方法引用和特定對象的實例方法引用兩種方法引用形式(下一章會講述),采用方法引用的方式可以簡化lambda表達式的寫法。

二、方法引用的具體使用

java8方法引用有四種形式:

  • 靜態(tài)方法引用       :   ClassName :: staticMethodName
  • 構(gòu)造器引用        :   ClassName :: new
  • 類的任意對象的實例方法引用:   ClassName :: instanceMethodName
  • 特定對象的實例方法引用  :   object :: instanceMethodName

lambda表達式可用方法引用代替的場景可以簡要概括為:lambda表達式的主體僅包含一個表達式,且該表達式僅調(diào)用了一個已經(jīng)存在的方法。方法引用的通用特性方法引用所使用方法的入?yún)⒑头祷刂蹬clambda表達式實現(xiàn)的函數(shù)式接口的入?yún)⒑头祷刂狄恢隆?/strong>

2.1 靜態(tài)方法引用

靜態(tài)方法引用的語法格式為: 類名::靜態(tài)方法名 ,如
System.out::println 等價于lambda表達式 s -> System.out.println(s) ,代碼示例:

public class Test {public static void main(String[] args){//lambda表達式使用:Arrays.asList(new String[] {"a", "c", "b"}).stream().forEach(s -> Test.println(s));//靜態(tài)方法引用:Arrays.asList(new String[] {"a", "c", "b"}).stream().forEach(Test::println);}public static void println(String s){System.out.println(s);} }

靜態(tài)方法引用適用于lambda表達式主體中僅僅調(diào)用了某個類的靜態(tài)方法的情形。

2.2 構(gòu)造器引用

構(gòu)造器引用的語法格式為: 類名::new ,如() -> new ArrayList() 等價于 ArrayList::new,代碼示例:

Supplier<List<String>> supplier1= () -> new ArrayList<String>();

等價于

Supplier<List<String>> supplier = ArrayList<String>::new;

構(gòu)造器引用適用于lambda表達式主體中僅僅調(diào)用了某個類的構(gòu)造函數(shù)返回實例的場景。

2.3 類的任意對象的實例方法引用

類的任意對象的實例方法引用的語法格式為: 類名::實例方法名 , 這種方法引用相對比較復(fù)雜,我們來看示例:

一、示例1

Arrays.sort(strs,(s1,s2)->s1.compareToIgnoreCase(s2));

等價于

Arrays.sort(strs, String::compareToIgnoreCase);

上述示例中,strs為一個String數(shù)組,lambda表達式(s1,s2)->s1.compareToIgnoreCase(s2)實現(xiàn)函數(shù)式接口的是Comparator接口, 我們看下jdk8中Comparator接口的源碼(截取部分):

@FunctionalInterfacepublic interface Comparator<T> {int compare(T o1, T o2);}

而String類的compareToIgnoreCase方法源碼為:

public int compareToIgnoreCase(String str) {return CASE_INSENSITIVE_ORDER.compare(this, str);}

可以發(fā)現(xiàn)函數(shù)式接口Comparator的compare方法比String類的compareToIgnoreCase方法多了一個String類型的入?yún)ⅰ?吹竭@里對類的任意對象的實例方法引用的使用可能似懂非懂,下面我們看一個自己實現(xiàn)一個類的任意對象的實例方法引用的示例(示例2)。

二、示例2

public class Student {private String name;private Integer score;public void setNameAndScore(String name, Integer score){this.name = name;this.score = score;System.out.println("Student "+ name +"'s score is " + score);}public static void main(String[] args){/*lambda表達式的用法:TestInterface testInterface = (student, name, score) -> student.setNameAndScore(name, score);*///類的任意對象的實例方法引用的用法:TestInterface testInterface = Student::setNameAndScore;testInterface.set(new Student(), "DoubleBin", 100);}@FunctionalInterfaceinterface TestInterface{// 注意:入?yún)⒈萐tudent類的setNameAndScore方法多1個Student對象,除第一個外其它入?yún)㈩愋鸵恢?/span>public void set(Student d, String name, Integer score);} }

看完上述代碼,我們可以總結(jié)出類的任意對象的實例方法引用的特性為:

1、方法引用的通用特性:方法引用所使用方法的入?yún)⒑头祷刂蹬clambda表達式實現(xiàn)的函數(shù)式接口的入?yún)⒑头祷刂狄恢?#xff1b;
2、lambda表達式的第一個入?yún)閷嵗椒ǖ恼{(diào)用者,后面的入?yún)⑴c實例方法的入?yún)⒁恢隆?/strong>

2.4 特定對象的實例方法引用

特定對象的實例方法引用的語法格式為: 對象::實例方法名 , 示例代碼:

public class Test {public static void main(String[] args){Test test = new Test();// lambda表達式使用:Arrays.asList(new String[] {"a", "c", "b"}).stream().forEach(s -> test.println(s));// 特定對象的實例方法引用:Arrays.asList(new String[] {"a", "c", "b"}).stream().forEach(test::println);}public void println(String s){System.out.println(s);} }

特定對象的實例方法引用適用于lambda表達式的主體中僅僅調(diào)用了某個對象的某個實例方法的場景。

三、總結(jié)

方法引用使用運算符::連接類(或?qū)ο?與方法名稱(或new)實現(xiàn)在特定場景下lambda表達式的簡化表示,使用時要注意方法引用的使用場景及各種方法引用的特性。使用方法引用的好處是能夠更進一步簡化代碼編寫,使代碼更簡潔。
然而作者認(rèn)為,方法引用代替lambda表達式對代碼的簡化程度遠遠沒有l(wèi)ambda表達式代替匿名類的簡化程度大, 有時反而增加了代碼的理解難度(如2.3節(jié):類的任意對象的實例方法引用),且使用場景的局限性不利于增加或修改代碼,個人認(rèn)為有時沒有必要刻意使用方法引用~


  • 【java8新特性】——lambda表達式與函數(shù)式接口詳解(一)

  • 【java8新特性】——Stream API詳解(二)

  • 【java8新特性】——Optional詳解(三)

  • 【java8新特性】——方法引用(四)

  • 【java8新特性】——默認(rèn)方法(五)

總結(jié)

以上是生活随笔為你收集整理的【java8新特性】——方法引用(四)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。