第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 8 Predicate - 為什么不能加入通配符泛型謂詞?

Java 8 Predicate - 為什么不能加入通配符泛型謂詞?

寶慕林4294392 2021-08-19 18:50:59
考慮以下代碼:public class Main {    private static Predicate<? extends TestObject> predicate = testObject -> true;    private static Predicate<? extends TestObject> predicate1 = testObject -> true;    public static void main( String[] args ) {         List<TestObject> objects = Lists.newArrayList( new TestObject(), new TestObject() );         objects.stream().filter( predicate.or( predicate1 ) ).findFirst();    }}它不編譯,給出錯誤:Error:(17, 48) java: incompatible types: java.util.function.Predicate<capture#1 of ? extends test.test.TestObject> cannot be converted to java.util.function.Predicate<? super capture#2 of ? extends test.test.TestObject>似乎我們不能將這樣的謂詞與諸如“或”或“與”之類的邏輯運算符連接起來,但是為什么 Java 不能處理它們呢?它使用簡單的謂詞(如 )進行編譯Predicate<TestObject>,但不使用Predicate<? super TestObject>or 進行編譯Predicate<? extends TestObject>。
查看完整描述

3 回答

?
胡說叔叔

TA貢獻1804條經(jīng)驗 獲得超8個贊

您可能知道謂詞是兼容的,但編譯器不兼容。


想象一下這個例子:


Predicate<? extends Collection<Object>> p1 = (Set<Object> s) -> s.isEmpty();

Predicate<? extends Collection<Object>> p2 = (List<Object> l) -> l.get(0) != null;

我們開發(fā)人員可以看到,第一個謂詞在技術(shù)上可以處理所有集合,而第二個謂詞只能處理列表。但是想象一下謂詞在其他地方被初始化或者同時被改變。編譯器無法確定謂詞對象是為哪種類型的集合創(chuàng)建的。因此,您根本無法使用它們:


Set<Object> set = new HashSet<>();

List<Object> list = new ArrayList<>();

p1.test(set);

p2.test(list);

p1.test(list);

p2.test(set);

所有這些調(diào)用都不會編譯,因為編譯器無法確定背后的實際對象p1和p2can 是否完全適用于這些類型的集合。這就是意思? extends Collection<>:你知道它是一個特定的子類型,但你不能告訴編譯器究竟是哪一個。


用一個更簡單的例子來說明這一點:


Collection<Apple> appleBasket = ...;

appleBasket.add(new Apple());  // works

appleBasket.add(new Orange()); // does not work (obviously)


Collection<Fruit> mixedFruitBasket = ...;

mixedFruitBasket.add(new Apple());  // works

mixedFruitBasket.add(new Orange()); // works


// Now the tricky part

Collection<? extends Fruit> unknownButPureFruitBasket = ...;

unknownButPureFruitBasket.add(new Apple());  // does not work 

unknownButPureFruitBasket.add(new Orange()); // does not work

您不能將任何一種水果添加到您不知道其類型的籃子中。事實上,它可能是一個可以容納所有水果的籃子,但也可能是一個純蘋果籃子、橙色籃子,甚至是你還不知道的香蕉籃子。


在您的 IDE 中嘗試:


List<? extends String> l1 = new ArrayList<>();

List<? extends String> l2 = new ArrayList<>();

l1.addAll(l2);

Eclipse 告訴我:


類型 List<capture# 1 -of 中的addAll(Collection1-of ? extends String>) 方法 extends String> 不適用于參數(shù) (List<capture# 2 -of ? extends String>)


請注意不同的類型:addAll期望是 的集合capture#1,l2是 的集合capture#2。


查看完整回答
反對 回復(fù) 2021-08-19
?
aluckdog

TA貢獻1847條經(jīng)驗 獲得超7個贊

filter需要一個Predicate<? super TestObject>,而不是Predicate<? extends TestObject>。

為什么super TestObject?因為這里的 TestObject 是一個輸入?yún)?shù),一個消費者。根據(jù)PECS規(guī)則,它應(yīng)該被標(biāo)記為super。

Predicate<? extends TestObject>完全不同于Predicate<? super TestObject>.?前者可以接受TestObjectand 的所有子類TestObject。后者可以接受的所有超TestObjectTestObject。顯然,它們是不同的且不兼容的。


查看完整回答
反對 回復(fù) 2021-08-19
?
白豬掌柜的

TA貢獻1893條經(jīng)驗 獲得超10個贊

這實際上與 Java 如何處理謂詞無關(guān),而只是泛型問題。


簡而言之,答案是predicate和predicate1不一定兼容。參數(shù)的類型or為Predicate<? super T>,假設(shè)T在兩個Predicate對象中是相同的具體類型參數(shù)。但這種情況并非如此。


為了說明問題,假設(shè):


class TestObject2 extends TestObject {

    boolean isTrue() {

        return true;

    }

}

class TestObject3 extends TestObject {

    boolean isTrue3() {

        return true;

    }

}

并且(注意聲明的類型沒有改變,但實際的 lambda 表達式改變了):


private static Predicate<? extends TestObject> predicate = 

        (TestObject2 testObject) -> testObject.isTrue();

private static Predicate<? extends TestObject> predicate1 = 

        (TestObject3 testObject) -> testObject.isTrue3();

在這個例子中,or會得到錯誤的值(predicate接受一個TestObject2對象,但在這種情況下,它可以用一個TestObject3對象調(diào)用)。


你認(rèn)為predicate1這會如何工作filter?


Stream.of(new TestObject2(), new TestObject2()).filter(predicate.or(predicate1));

事實是,編譯器低保Predicate<? extends TestObject>是既兼容Predicate<TestObject2>和Predicate<TestObject3>(這是按照仿制藥的法律)


查看完整回答
反對 回復(fù) 2021-08-19
  • 3 回答
  • 0 關(guān)注
  • 255 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號