Java 将 ArrayList 缩小到新的大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1184636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:38:35  来源:igfitidea点击:

Shrinking an ArrayList to a new size

javaarraylist

提问by ripper234

Do I really need to implement it myself?

我真的需要自己实现吗?

private void shrinkListTo(ArrayList<Result> list, int newSize) {
  for (int i = list.size() - 1; i >= newSize; --i)
  list.remove(i);
}

采纳答案by mP.

Create a sublistwith the range of elements you wish to remove and then call clearon the returned list.

创建一个包含您希望删除的元素范围的子列表,然后调用clear返回的列表。

list.subList(23, 45).clear()

This approach is mentioned as an idiom in the documentation for both Listand ArrayList.

这种方法在ListArrayList的文档中被称为惯用语。



Here's a fully unit tested code example!

这是一个完全经过单元测试的代码示例!

// limit yourHappyList to ten items
int k = yourHappyList.size();
if ( k > 10 )
    yourHappyList.subList(10, k).clear();
    // sic k, not k-1

回答by dfa

use ArrayList#removeRange()method:

使用ArrayList#removeRange()方法:

protected void removeRange(int fromIndex, int toIndex)

Removes from this list all of the elements whose index is between fromIndex, inclusive, and toIndex, exclusive. Shifts any succeeding elements to the left (reduces their index). This call shortens the list by (toIndex - fromIndex) elements. (If toIndex==fromIndex, this operation has no effect.)

protected void removeRange(int fromIndex, int toIndex)

从此列表中删除其索引介于 fromIndex(包含)和 toIndex(不包含)之间的所有元素。将任何后续元素向左移动(减少它们的索引)。此调用通过 (toIndex - fromIndex) 元素缩短列表。(如果 toIndex==fromIndex,则此操作无效。)

then use ArrayList#trimToSize()method:

然后使用ArrayList#trimToSize()方法:

Trims the capacity of this ArrayList instance to be the list's current size. An application can use this operation to minimize the storage of an ArrayList instance.

将此 ArrayList 实例的容量修剪为列表的当前大小。应用程序可以使用此操作来最小化 ArrayList 实例的存储空间。

回答by akf

There is another consideration. You might want to shy away from using an ArrayListin your method signature, and instead work to the Listinterface, as it ties you into theArrayListimplementation, making changes down the line difficult if you find that, for example, a LinkedListis more suitable to your needs. Preventing this tight coupling does come at a cost.

还有另一个考虑。您可能希望避免ArrayList在您的方法签名中使用 a ,而是使用List接口,因为它会将您与ArrayList实现联系起来,如果您发现 aLinkedList更适合您的需要,则很难进行更改. 防止这种紧密耦合确实需要付出代价。

An alternative approach could look like this:

另一种方法可能如下所示:

private void shrinkListTo(List<Result> list, int newSize) {
  list.retainAll(list.subList(0, newSize);
}

Unfortunately, the List.retainAll()method is optional for subclasses to implement, so you would need to catchan UnsupportedOperationException,and then do something else.

不幸的是,该List.retainAll()方法对于子类实现是可选的,因此您需要先catch执行UnsupportedOperationException,然后再执行其他操作。

private void shrinkListTo(List<Result> list, int newSize) {
  try {
    list.retainAll(list.subList(0, newSize);
  } catch (UnspportedOperationException e) {
     //perhaps log that your using your catch block's version.
     for (int i = list.size() - 1; i >= newSize; --i)
        list.remove(i);
     }
  }
}

That is not as straight forward as your orginal. If you are not tied to the instance of the List that you are passing in, you could just as easily return a new instance by calling subList(int start, int end), and you wouldnt even need to make a method. This would also be a faster implementation, as (in Java 6), you would be getting an instance of an AbstractList.SubListthat contains your list, an offset into it and a size. There would be no need for iterating.

这不像你原来的那样直接。如果您没有绑定到您传入的 List 实例,您可以通过调用 轻松返回一个新实例subList(int start, int end),您甚至不需要创建方法。这也将是一个更快的实现,因为(在 Java 6 中),您将获得一个 an 实例,AbstractList.SubList其中包含您的列表、其中的偏移量和大小。不需要迭代。

If you are interested in the arguments for coding to Interfaces instead of classes, see this favorite article by Allen Holub

如果您对接口而不是类编码的参数感兴趣,请参阅Allen Holub 的这篇最喜欢的文章

回答by dfa

alternatively you can use subListmethod:

或者,您可以使用subList方法:

public static <T> List<T> shrinkTo(List<T> list, int newSize) {
    return list.subList(0, newSize - 1);
}

回答by Sergey Shustikov

My solution :

我的解决方案:

public static void shrinkTo(List list, int newSize) {
    int size = list.size();
    if (newSize >= size) return;
    for (int i = newSize; i < size; i++) {
        list.remove(list.size() - 1);
    }
}

Just use :

只需使用:

shrinkTo(yourList, 6);