将ArrayList缩小为新的大小

我真的需要自己实现吗?

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

用你希望删除的元素范围创build一个子列表 ,然后在返回的列表中调用clear

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

这种方法在List和ArrayList的文档中被称为成语。


这是一个完全的unit testing的代码示例!

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

或者你可以使用subList方法:

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

使用ArrayList#removeRange()方法:

protected void removeRange(int fromIndex,int toIndex)

从此列表中删除索引介于fromIndex和inclusive之间的所有元素。 将任何后续元素向左移(减less索引)。 这个调用通过(toIndex – fromIndex)元素来缩短列表。 (如果toIndex == fromIndex,则此操作无效。)

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

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

我的解决scheme

 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); } } 

只要使用:

 shrinkTo(yourList, 6); 

还有一个考虑。 您可能希望避免在方法签名中使用ArrayList ,而是使用List接口,因为它将您ArrayListArrayList实现中,如果发现LinkedList更多适合您的需求。 防止这种紧密耦合确实是有代价的。

另一种方法可能是这样的:

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

不幸的是, List.retainAll()方法对于子类来说是可选的,所以你需要catch一个UnsupportedOperationException,exceptionUnsupportedOperationException,然后做其他的事情。

 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); } } } 

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

如果你对代码类的编码参数感兴趣,请参阅Allen Holub的这篇文章