[英]Java <? extends Collection>
我有以下Java代碼:
List<? extends Collection<String>> attributes = new ArrayList<HashSet<String>>(nrAttributes);
...
attributes.replaceAll((in) -> {
List<String> out = new ArrayList<>();
out.addAll(in);
return out;
});
但它給了我一個編譯器異常(最后一個是紅色)說:
類型不匹配:無法從List轉換為捕獲#2-of? 擴展集合
命令行說:
J:\WS\Java test>javac Main.java -Xdiags:verbose
Main.java:11: error: method replaceAll in interface List<E> cannot be applied to given types;
attributes.replaceAll((in) -> {
^
required: UnaryOperator<CAP#1>
found: (in)->{ Li[...]ut; }
reason: argument mismatch; bad return type in lambda expression
List<String> cannot be converted to CAP#1
where E is a type-variable:
E extends Object declared in interface List
where CAP#1 is a fresh type-variable:
CAP#1 extends Collection<String> from capture of ? extends Collection<String>
1 error
即?
capture,可能是List<String>
的子類型或兄弟,因此將List<String>
添加到List<? extends Collection>
是不安全的List<? extends Collection>
List<? extends Collection>
。 ...extends Collection
在這里...extends Collection
並不重要。
可能的方法:
List<? extends Collection<String>> attributes = new ArrayList<HashSet<String>>(nrAttributes);
...
List<List<String>> attribs2 = new ArrayList<>();
attributes.forEach((in) -> {
List<String> out = new ArrayList<>();
out.addAll(in);
attribs2.add(out);
});
要么:
List<Collection<String>> attributes = new ArrayList<>(nrAttributes);
...
attributes.replaceAll((in) -> {
List<String> out = new ArrayList<>();
out.addAll(in);
return out;
});
您的擴展只是確保您將從列表中讀取 Collection<String>
。 但你不能寫它。
有關非常好的解釋,請參閱此鏈接 ,我從中獲取以下內容:
你不能將任何對象添加到
List<? extends T>
List<? extends T>
因為你不能保證它實際指向哪種List,所以你不能保證該List中允許該對象。 唯一的“保證”是你只能讀取它,你將獲得T的T或子類。
您將attributes
變量定義為擴展字符串集合的列表 。 在編譯時,編譯器無法確定attributes
實際上是List<TreeSet<String>
的實例,還是List<LinkedList<String>
或甚至List<Vector<String>
的實例。 因此,編譯器不允許您修改屬性集合,因為存在將ArrayList<String>
添加到另一個字符串集合(例如TreeSet<String>
的集合的風險。
一般來說,如果你有一個List<? extends Something>
List<? extends Something>
,編譯器不允許你修改集合(添加/刪除/清除/ ...)。 任何列表的列表? extends T
? extends T
是只讀的!
編譯:
List<Collection<String>> attributes = new ArrayList<>(nrAttributes);
當你說List>你說“收集的特定子類型列表”所有這些? extends X在內部被命名為capture #n of? 擴展X(第一次捕獲#1 ......,第二次捕獲#2 ......等等),但每次都被認為是特定類型。 例如,以下代碼也沒有編譯,但具有相同的錯誤
為什么需要仿制葯? 以下示例可以包含Collection of String的任何子類(compiles,btw)
List<? extends Collection<String>> attributes = new ArrayList<HashSet<String>>(nrAttributes);
attributes.replaceAll((in) -> {
List<String> out = new ArrayList<>();
out.addAll(in);
return out;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.