我使用這個 lambda 運算式來查找嵌套物件
Optional<? extends OnlineResource> onlineResourceOptional =
metadata.getDistributionInfo().stream()
.filter(Objects::nonNull)
.flatMap(distribution -> distribution.getTransferOptions().stream())
.filter(Objects::nonNull)
.flatMap(digitalTransferOptions -> digitalTransferOptions.getOnLines().stream())
.filter(Objects::nonNull)
.filter(onlineResource -> onlineResource.getProtocol().equals("OGC:STA"))
.findFirst()
;
Optional<? extends OnlineResource>由于該方法,它回傳一個泛型,flatmap但我希望它回傳一個Optional<OnlineResource>. 我怎樣才能做到這一點?
uj5u.com熱心網友回復:
似乎其中一個或兩個方法,getTransferOptions()和/或getOnLines()回傳具有通配符型別的集合,例如Collection<? extends …>. 強烈建議不要這樣做:
應該避免使用通配符作為回傳型別,因為它迫使程式員使用代碼來處理通配符。
這正是您遇到的問題。您最好修復這些方法而不是呼叫者。如果這不可能,您可以通過為flatMap操作指定顯式型別而不是依賴型別推斷來解決此問題。
例如,如果您有類似的代碼
public static void main(String[] args) {
Optional<? extends Number> result = Stream.of("")
.flatMap(x -> method(x).stream())
.filter(x -> true)
.findFirst();
}
private static List<? extends Number> method(Object arg) {
return Arrays.asList(42, 1.23);
}
將其更改為
public static void main(String[] args) {
Optional<Number> result = Stream.of("")
.<Number>flatMap(x -> method(x).stream())
.filter(x -> true)
.findFirst();
}
private static List<? extends Number> method(Object arg) {
return Arrays.asList(42, 1.23);
}
to flatMapto a Stream<Number>,而不是Stream<? extends Number>。這有效,因為flatMap已被宣告為
<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
允許指定的函式回傳子型別流。這是PECS規則的應用。
但如前所述,最好修復集合回傳方法。更多時候,它們還呼叫遵循 PECS 規則的方法,因此允許將元素型別從 更改? extends E為E。
了解以下功能可能會有所幫助:
如果您已經擁有像使用 創建的不可變集合List.of(…),則可以使用方法List.copyOf(…)或Set.copyOf(…)在沒有副本的情況下擴展其元素型別。
List<String> list1 = List.of("foo", "bar");
List<? extends Object> list2 = list1;
List<Object> list3 = List.copyOf(list2);
System.out.println(list1 == (Object)list3); // prints true
這是可行的,因為不變性阻止呼叫者Object向 this添加一個List<String>。同樣,您可以為任何集合創建不可修改的視圖以避免處理通配符型別:
List<String> list1 = List.of("foo", "bar");
List<? extends Object> list2 = list1;
List<Object> list3 = Collections.unmodifiableList(list2);
這會創建一個新List實體,但不會復制內容,所以它仍然很便宜。但是,如前所述,通常已經有一些方法允許通過在較早的位置插入顯式型別來將型別更改為所需的無通配符型別。
uj5u.com熱心網友回復:
添加演員表。這是安全的,因為所有? extends X的 s 都必然X是 s。
Optional<Number> foo = Optional.of("ABC")
.flatMap(Main::length); // Does not compile
Optional<Number> bar = Optional.of("DEFG")
.flatMap(Main::length)
.map(Number.class::cast); // Safe
private static Optional<? extends Number> length(String str) {
return Optional.ofNullable(str).map(String::length);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/510475.html
標籤:爪哇仿制药有界通配符
