簡體   English   中英

Java <?擴展集>

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM