繁体   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