亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

更多QQ空间微信QQ好友腾讯朋友复制链接
您的位置:首頁/技術文章
文章詳情頁

淺談對Java雙冒號::的理解

【字号: 作者:豬豬瀏覽:64日期:2022-08-30 17:39:12

本文為個人理解,不保證完全正確。官方文檔中將雙冒號的用法分為4類,按照我的個人理解可以分成2類來使用。

官方文檔

官方文檔中將雙冒號的用法分為了以下4類:

用法 舉例 引用靜態方法 ContainingClass::staticMethodName 引用特定對象的實例方法 containingObject::instanceMethodName 引用特定類型的任意對象的實例方法 ContainingType::methodName 引用構造函數 ClassName::new

以下是我的理解

個人理解

雙冒號的作用

在使用雙冒號前我們要先搞清楚一個問題:為什么要使用雙冒號?也就是雙冒號的作用是什么。雙冒號的設計初衷是為了化簡Lambda表達式,不熟悉Lambda表達式的同學可以先了解一下。Lambda表達式的形式有兩種:

包含單獨表達式 :parameters -> an expression

list.forEach(item -> System.out.println(item));

包含代碼塊:parameters -> { expressions }

list.forEach(item -> { int numA = item.getNumA(); int numB = item.getNumB(); System.out.println(numA + numB);});

使用雙冒號可以省略第一種Lambda表達式中的參數部分,即item ->和調用方法的參數這兩部分。

例如:

//不使用雙冒號list.forEach(item -> System.out.println(item));//使用雙冒號list.forEach(System.out::println);

雙冒號的使用條件

使用雙冒號有兩個條件:

條件1條件1為必要條件,必須要滿足這個條件才能使用雙冒號。Lambda表達式內部只有一條表達式(第一種Lambda表達式),并且這個表達式只是調用已經存在的方法,不做其他的操作。

條件2由于雙冒號是為了省略item ->這一部分,所以條件2是需要滿足不需要寫參數item也知道如何使用item的情況。有兩種情況可以滿足這個要求,這就是我將雙冒號的使用分為2類的依據。

情況 舉例 Lambda表達式的參數與調用函數的參數完全一致 list.forEach(item -> System.out.println(item)) 調用的函數是參數item對象的方法且沒有參數 list.stream().map(item -> item.getId())

一些栗子

Lambda表達式的參數與調用函數的參數完全一致時

靜態方法調用

//化簡前list.forEach(item -> System.out.println(item));//化簡后list.forEach(System.out::println);

非靜態方法調用

StringBuilder stringBuilder = new StringBuilder();//化簡前IntStream.range(1, 101).forEach(item -> stringBuilder.append(item));//化簡后IntStream.range(1, 101).forEach(stringBuilder::append);

調用構造方法

官方給出的例子

先定義一個方法,這個方法的作用是將一個集合的內容復制到另一個集合

public <T, SOURCE extends Collection<T>, DEST extends Collection<T>>DEST transferElements(SOURCE sourceCollection, Supplier<DEST> collectionFactory) { DEST result = collectionFactory.get(); result.addAll(sourceCollection); return result;}

調用這個方法

//化簡前Set<Person> rosterSetLambda = transferElements(roster, () -> new HashSet<>());//化簡后Set<Person> rosterSet = transferElements(roster, HashSet::new);

稍微解釋一下:

調用時傳入的Lambda表達式相當于是對Supplier的繼承,并重寫Supplier的get()方法,下面是Supplier的源碼:

@FunctionalInterfacepublic interface Supplier<T> { /** * Gets a result. * * @return a result */ T get();}

在transferElements()方法中調用collectionFactory.get()時相當于調用重寫后的方法{return new HashSet<>();}

我自己寫的一個例子

第一個類:

@Datapublic class ModelA { private String id; public ModelA(String id) { this.id = id; } public ModelA() { }}

第二個類

class ClassB { private final List<ModelA> list = new ArrayList<>(); public void add(String string, Function<String, ModelA> function) { list.add(function.apply(string)); }}

測試代碼

ClassB classB = new ClassB();d//化簡前classB.add('ddd', item -> new ModelA(item));//化簡后classB.add('ddd', ModelA::new);

調用的函數是參數item對象的方法且沒有參數時

//化簡前List<String> stringList = list.stream().map(item -> item.getId()).collect(Collectors.toList());//化簡后List<String> stringList = list.stream().map(ModelA::getId).collect(Collectors.toList());

一種特殊情況

除了上述兩種情況可以使用雙冒號化簡Lambda表達式外,還存在一種特殊情況也可以使用雙冒號。當Lambda表達式的參數有兩個(形如(a,b) -> an expression)時,調用a的方法參數為b時,例如:

String[] stringArray = {'Barbara', 'James', 'Mary', 'John'};//化簡前Arrays.sort(stringArray, (a,b) -> a.compareToIgnoreCase(b));//化簡后Arrays.sort(stringArray, String::compareToIgnoreCase);

到此這篇關于淺談對Java雙冒號::的理解的文章就介紹到這了,更多相關Java雙冒號::內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 成年性网站| 在线91精品亚洲网站精品成人 | 久久久亚洲欧洲日产国码二区 | 国内精品51视频在线观看 | 日韩精品免费视频 | 国产肥老妇视频∵ | 一级在线观看视频 | 视频免费网站 | 国产不卡一区二区三区免费视 | 亚洲成在人天堂一区二区 | 18成人免费观看网站入口 | 国产福利91精品一区二区三区 | 欧美一级毛片欧美一级成人毛片 | 国产高清在线91福利 | 久久久久爽亚洲精品 | 午夜激情影院 | 国模大胆偷拍在线视频 | 欧美综合偷拍在线另类卡通小说 | 亚洲精品视频在线观看视频 | 久久永久免费中文字幕 | 伊人成伊人成综合网2222 | 国产精品高清一区二区三区不卡 | 国产成人精品亚洲77美色 | 国产午夜精品理论片久久影视 | 高清精品美女在线播放 | 99je全部都是精品视频在线 | 香蕉超级碰碰碰97视频在线观看 | 国内真实下药迷j在线观看 国内主播大秀福利视频在线看 | aⅴ在线免费观看 | 免费视频片在线观看 | 99热热热| 免费国产小视频 | 初女破苞国语在线观看免费 | 黄大色大片免费久久 | aaaa级毛片| 免费看日日麻批免费视频播放 | 国产成人精品久久一区二区三区 | 在线日韩国产 | 国产又黄又爽又色视频免费观看 | 真实男女xx00动态视频免费 | 男女激情在线观看 |