将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
接口,因为它将您ArrayList
到ArrayList
实现中,如果发现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的这篇文章