[英]How is this method reference a valid one ? What is happeneing behind the scenes?
[英]what is the idea behind this unnecessary method reference?
java 8中的Predicate接口有一個靜態方法,如:
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
為什么不這樣做:
return (null == targetRef)
? null
: object -> targetRef.equals(object);
我的意思是,這個方法引用Objects::isNull
沒有帶來任何進一步的改進......並且正在減少一點可讀性......
if為null我返回true ...完成! 或者我在幕后錯過了一些陷阱......?
該方法需要返回Predicate<T>
。 盡管null
是 Predicate<T>
的有效值,但在這種情況下它並不是真正有用。
如果傳入的對象為null,我們如何確定其他東西是否等於它? 好吧,我們檢查“其他東西”是否也是空的! 代碼可能是:
object -> object == null
看看這是一個lambda表達式,而不是null
文字? 如果你想說“檢查某些東西是否為空”,你應該寫一個這樣的lambda表達式,而不是null
。
Objects::isNull
方法與上面的lambda大致相同。 他們之所以選擇Objects::isNull
是因為它更具可讀性。
編輯:我看到你編輯了你的問題並將null
更改為true
。 這也不正確。
首先, true
不是Predicate<T>
的有效值。 如果你想要一個總是返回true的謂詞,你需要
obj -> true
無論如何,這在邏輯上也是不正確的。 null對象並不總是等於另一個對象。
我認為這里的誤解是不測試targetRef為null,但是這個方法返回一個測試相等性的Predicate(一個函數)。
所以這樣的代碼可以寫成:
Predicate<String> writtenByAuthor = Predicate.isEqual("Firewall-Alien");
此實例可以在使用謂詞的其他方法中使用,例如java.util.stream.Stream.filter(Predicate<? super T> p)
。
回到你關於null
的問題,這個片段可以說明用法:
void printMatching(List<String> list, String s) {
printMatching(list, Predicate.isEqual(s));
}
void printMatching(List<String> list, Predicate<? super String> filter) {
Objects.requireNonNull(list);
Objects.requireNonNull(filter);
list.stream().filter(filter).forEach(System.out::println);
}
現在看一下這段代碼,無論s
是否為null
,都會構建一個測試相等性的Predicate,測試提供列表的每個元素並打印它。 此代碼還表明,如果您需要一些靈活性,謂詞和功能接口是您的朋友。 如果您的項目不需要這種靈活性,您可以安全地決定不使用它們並使用眾所周知的方法來測試您的參數。
如果要測試的對象等於引用對象,則該方法應返回一個謂詞,該謂詞的結果為true
,要檢查的是一種null
安全方式。
它本可以實現的
static <T> Predicate<T> isEqual(Object targetRef) {
return object -> Objects.equals(object, targetRef);
}
這相當於
static <T> Predicate<T> isEqual(Object targetRef) {
return object -> object==targetRef || targetRef!=null&&targetRef.equals(object);
}
但是,在謂詞構造之后, targetRef
是否為null
並且由於謂詞可能不止一次被評估,因此將不變屬性的測試移出謂詞並創建專門的謂詞函數會更有效。
實現等同於
static <T> Predicate<T> isEqual(Object targetRef) {
return null == targetRef? object -> object==null: object -> targetRef.equals(object);
}
返回兩個函數中的任何一個,一個函數只測試null
或函數調用equals
而不測試null
,具體取決於targetRef
是否為null
。
這也相當於
static <T> Predicate<T> isEqual(Object targetRef) {
return null == targetRef? Objects::isNull: targetRef::equals;
}
但是,目前還不清楚為什么JRE開發人員決定混合使用方法引用和lambda表達式...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.