【问题标题】:Differences between list.sublist() and stream.limit()list.sublist() 和 stream.limit() 的区别
【发布时间】:2022-01-02 17:36:47
【问题描述】:

我有两个版本的代码会截断现有列表:

版本 1:

List<String> myList = User.getAllNames();
myList = myList.stream().sorted(sortByName).limit(5).collect(Collectors.toList());

版本 2:

List<String> myList = User.getAllNames();
myList.sort(sortByName);
myList = myList.subList(0, 5 - 1);

版本 3:

List<String> myList = User.getAllNames();
myList = new ArrayList<BacktestResult>(myList.subList(0, 5 - 1));

您可以假设,没有其他对象引用被剪裁的元素。两个版本都通过重新分配截断myList。由于 version 2 仅使用由其原始列表烘焙的 subList,我怀疑 version 2 是否也完全从 java 堆中删除了裁剪的元素(之后垃圾收集)就像 版本 1 一样。

我需要知道的主要事情是,如果版本 2 也像版本 1 那样从 Java 堆(垃圾收集之后)中完全删除被剪裁的元素。

【问题讨论】:

  • 回答你用粗体表示的问题:总之,有很多不同。
  • 我需要知道的主要事情是,正如我在问题中所说:“如果版本 2 也像版本 1 一样从 Java 堆中(垃圾收集之后)完全删除剪辑元素”。
  • 原则上也不做。 subList 返回由原始列表支持的 视图,因此您可以认为所有列表元素都“固定”到堆中,因此至少在列表处于活动状态时可以通过强引用访问。
  • 而且,我可能不会称其为“截断”:两种情况下的原始列表均不受影响。使用remove() 删除元素真的会截断它。

标签: java collections


【解决方案1】:

我怀疑版本 2 是否也完全从 Java 堆中删除了裁剪的元素(在垃圾收集之后)

假设没有其他对象引用被剪裁的元素,那么在版本 1 的情况下,它们将有资格进行垃圾回收。

在版本 2 的情况下,由于生成的子列表是原始列表的“视图”,因此子列表需要保留对原始列表的引用,其中包含所有被裁剪的元素。因此,那些被剪裁的元素将不符合垃圾回收的条件。

版本 3 与版本 1 类似。您丢弃了由sublist 生成的视图,因此它将符合 GC 条件。 myList 成为一个新列表,它只引用原始的第一个元素。现在没有变量直接或间接引用原始列表的最后一个元素,因此它们有资格进行 GC。

也就是说,除非您的列表有 很多 个元素,否则这可能无关紧要。

【讨论】:

  • 谢谢。我想出了另一个版本(我在上面添加的版本 3)。也许你可以调整你的答案。我认为,version 3 的行为类似于 version 2 有资格进行垃圾收集..
  • @nimo23 这与版本 1 类似。您丢弃了 sublist 生成的视图,因此它将符合 GC 条件。 myList 成为一个新列表,它只引用原始的第一个元素,因此最后一个元素有资格进行 GC。
猜你喜欢
  • 2019-12-06
  • 1970-01-01
  • 2010-11-20
  • 2015-09-28
  • 2013-08-07
  • 2011-10-20
  • 2020-01-23
  • 1970-01-01
  • 2014-10-09
相关资源
最近更新 更多