2009-07-26 44 views
47

我是否真的需要自己实现它?将ArrayList缩小至新大小

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

FWIW更合适的方式来写是“,而长度>限制,删除最后一个e“! – Fattie 2014-05-20 13:14:30

回答

95

与您要删除,然后调用返回的列表上clear元素的范围内创建一个sublist

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

这种方法被提到如文档中两个ListArrayList成语。


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

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

+1可能是保留最快的实现指向原始文件的指针 – akf 2009-07-26 14:56:47

4

使用ArrayList#removeRange()方法:

保护无效removeRange(INT的fromIndex, INT toIndex)

从该列表中移除其索引是fromIndex(包括)之间的元素,元素范围为,独家。将任何后续元素向左移(减少索引)。此调用通过(toIndex - fromIndex)元素缩短列表。 (如果toIndex == fromIndex,则此操作没有任何影响。)

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

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

+0

downvotes没有解释是毫无意义的 – dfa 2009-07-26 14:05:06

+6

受保护的方法??? – ripper234 2009-07-26 14:31:46

+0

如果你不能继承子类,试试subList(检查我的第二个答案) – dfa 2009-07-26 14:41:08

0

还有一个考虑因素。您可能想避开在方法签名中使用ArrayList,而是在List接口上工作,因为它将您与ArrayList实现联系在一起,如果发现某个LinkedList更符合要求适合您的需求。防止这种紧密耦合确实需要付出代价。

另一种方法看起来是这样的:

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

不幸的是,List.retainAll()方法是可选的子类实现,所以你需要一个catchUnsupportedOperationException,然后去做别的事情。

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)来轻松地返回一个新实例,而且你甚至不需要创建一个方法。这也将是一个更快的实现,因为(在Java 6中),您将得到一个AbstractList.SubList的实例,其中包含您的列表,它的偏移量和大小。不需要迭代。

如果您有兴趣的参数编码到接口,而不是类,请参见this favorite article by Allen Holub

+1

使用.retainAll()将会非常低效。它将不得不采取O(n^2),因为对于列表中的每个元素,它必须通过子列表来检查它(它不知道它是一个子列表) – newacct 2009-07-26 18:14:21

7

或者你可以使用subList方法:

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

我的解决办法:

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