Shrinking an ArrayList to a new size

JavaArraylist

Java Problem Overview


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

Java Solutions


Solution 1 - Java

Create a sublist with the range of elements you wish to remove and then call clear on the returned list.

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

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


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

Solution 2 - Java

alternatively you can use subList method:

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

Solution 3 - Java

use ArrayList#removeRange() method:

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

then use ArrayList#trimToSize() method:

> 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.

Solution 4 - Java

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

Solution 5 - Java

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

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 catch an UnsupportedOperationException, and then do something else.

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.SubList that contains your list, an offset into it and a size. There would be no need for iterating.

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

Solution 6 - Java

I used:

if (list.size() > newSize) {
    list = list.subList(0, newSize);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionripper234View Question on Stackoverflow
Solution 1 - JavamP.View Answer on Stackoverflow
Solution 2 - JavadfaView Answer on Stackoverflow
Solution 3 - JavadfaView Answer on Stackoverflow
Solution 4 - JavaSergey ShustikovView Answer on Stackoverflow
Solution 5 - JavaakfView Answer on Stackoverflow
Solution 6 - JavaDimAView Answer on Stackoverflow