【问题标题】:How to solve "add all in list cannot be applied to"如何解决“无法应用到列表中的所有添加”
【发布时间】:2020-05-26 04:53:41
【问题描述】:

我有这个方法:

filteredListIn.addAll(Stream.of(listRef)
    .filter(results ->
            results.getTitle().contains(query.toString().toLowerCase())
     ));

使用这两个变量:

private List<Results> listRef = new ArrayList<>();
List<Results> filteredListIn = new ArrayList<>();

但我得到了

为 addAll(Stream) 找到 filtersListIn.addAll(Stream.of(listRef) ^ 方法 Collection.addAll(Collection) 不适用 (参数不匹配;Stream 无法转换为 Collection) 方法 List.addAll(Collection) 不适用

有什么问题,我该如何解决?

这可能是因为我使用外部库来支持 api 24 下的流吗?

【问题讨论】:

    标签: java android java-stream


    【解决方案1】:

    您必须收集列表中的所有流元素才能将其添加到集合中:

    filteredListIn.addAll(listRef.stream()
      .filter(results -> results.getTitle().contains(query.toString().toLowerCase()))
      .collect(Collectors.toList());
    

    【讨论】:

    • Stream.of(listRef) 将返回 List&lt;Results&gt; 并且在 List 上没有方法 .getTitle()。所以这段代码应该会报错。
    • 所以应该是listRef.stream() 你在说什么?
    【解决方案2】:

    仅供参考 Stream.of(listRef) 将返回 List&lt;Results&gt; 并且在 List 上没有方法 .getTitle()。我认为您的意思是使用listRef.stream().filter... 而不是Stream.of(listRef).filter...

    无论如何,这是一个标准示例,它表明您不应该对每个操作都使用流。您可以将流减少为:

    listRef.removeIf(results -> !results.getTitle().contains(query.toString().toLowerCase()));
    filteredListIn.addAll(listRef);
    

    注意:.removeIf 将有效地在listRef 上运行,因此如果需要,您应该clone。

    【讨论】:

    • Stream.of 返回一个结果流,它与 listRef.stream() 相同,所以我看不到那里的问题。 developer.android.com/reference/java/util/stream/…
    • @raven1981 在你的 ide 中试试。 Stream.of( 接受 var-args,而不是 Collection 或 List。
    • 是的,你是对的,没有注意到输入参数。无论如何,我认为使用 stream() 方法更容易。
    • 用这种方法比用流方法有什么好处?
    • @Titulum 最大的优点是简洁。此外,Stream API 会创建额外的对象,因为这看起来不像是对大列表的操作,所以它会比流更高效。
    【解决方案3】:

    addAll 需要一个 Collection 参数。只要不收集流,它就是Stream 类型,它独立于Collection。其他答案给你一个简单的解决方案:收集到一个列表,然后添加这个列表。

    我想提一下,虽然这不是最有效的解决方案,并且引入了相当多的内存开销:首先将流收集到一个新列表中,然后将该列表中的所有项目复制到您现有的列表中,最后是垃圾收集器将释放临时列表的占用空间。

    可以通过不收集流,而是使用forEach 终端操作迭代其元素来避免这种开销(为临时列表的后备数组分配内存):

    Stream.of(listRef)
            .filter(results -> results.getTitle().contains(query.toString().toLowerCase()))
            .forEach(filteredListIn::add);
    

    如果您的列表一开始是空的,最好的解决方案是直接收集它:

    final List<...> filteredListIn = Stream.of(listRef)
            .filter(results -> results.getTitle().contains(query.toString().toLowerCase()))
            .collect(Collectors.toList()); // or .toUnmodifiableList
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多