【问题标题】:Make an ArrayList of class C from a List of interface I从接口 I 的列表中创建一个 C 类的 ArrayList
【发布时间】:2018-04-24 21:56:58
【问题描述】:

考虑到这些元素:

一个接口I

public interface I {
    int getType();
}

一类C

public class C implements I {
    @Override
    public int getType() { return 0; }
}

给定 I 的列表,我如何使用 Java 8 制作 C 的 ArrayList?

这是我尝试过的:

public void foo(List<? extends I> listI) {

    List<C> listC = new ArrayList<>((List<C>)listI.stream()
            .filter(o -> o.getType() == 0)
            .collect(Collectors.toList())
    );
}

我收到的警告:

未经检查的演员表:'java.util.List&lt;capture&lt;? extends I&gt;&gt;''java.util.List&lt;C&gt;'

【问题讨论】:

  • filter(o -&gt; o instanceof C).map(o -&gt; (C) o).
  • 在 equals 函数之外使用 instanceof 不是一个坏习惯吗?
  • public class C extends I -- 这不是有效的 Java,一个类不能extend 一个接口。它只能implement一个接口。如果您需要帮助,您必须从 valid 可编译的 Java 代码开始。
  • @PaulLemarchand 如果你想检查某个东西是否是C 的实例,你会怎么做呢?
  • 如果List&lt;I&gt; 包含实现I 但不是C 或其子类之一的对象,你会怎么做?这就是为什么您最初的尝试不起作用的原因。

标签: java arraylist casting java-8 java-stream


【解决方案1】:

您首先需要执行filter 中间操作来保留C 类型的所有对象,然后执行map 来执行转换,即:

List<C> listC = listI.stream().filter(e -> e instanceof C).map(e -> (C) e).collect(Collectors.toCollection(ArrayList::new));

此外,当您执行收集操作时,您无需使用 ArrayList 构造函数来创建新列表,而只需使用 Collectors.toCollection(ArrayList::new) 并将其直接分配给 listC

【讨论】:

    【解决方案2】:

    C.getType() 可能返回 0,但 I 的其他实现也可能返回 0,因此您不能简单地检查 getType() == 0

    要获取C 的实例,您必须使用instanceof 进行过滤:

    .filter(o -> o instanceof C)
    

    产生Stream&lt;? extends I&gt;;然后转换为C 以获取Stream&lt;C&gt;

    .map(o -> (C) o)
    

    【讨论】:

      【解决方案3】:

      这是StreamEx的解决方案

      List<C> listC = StreamEx.of(listI).select(C.class).toList();
      

      对我来说简单、简短、简洁。

      【讨论】:

      • 从 API 设计的角度来看,我并不热衷于此。 “选择”是什么意思?的实例?完全一样的类?等于?等等。我会更喜欢标准 API,只是稍微冗长一些。
      • 基本上,我同意你所说的。当我第一次看到 API 时,我也有类似的感觉。但是在知道API的作用并使用了几次之后,现在使用它感觉很好。有时,接受与否真的取决于个人经历。
      猜你喜欢
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多