ArrayList clear vs removeAll

(From: http://blog.csdn.net/liuxiao723846/article/details/53908870 )

 

Many times we want to reset an ArrayList in order to reuse it. Reset here means to clear the list or remove all the elements of the list. In Java, there are two methods that can help us to implement reset clearor removeAll. In the case of small list length (eg: 10 or 100 elements), you can safely use these two methods. But if the list is very large (eg: 10M elements), choosing clear or removeAll can have a huge impact on the performance of your java application. Even sometimes, when the list is too large, the reset can take a lot of time, so recreating a new list is better than resetting the old one. But it should be reminded that it is necessary to ensure that the old list can be garbage collected, otherwise, there is a great risk that it will appear java.lang.OutOfMemoryError: Java Heap Space. Closer to home, let's look at the clear() and removeAll() methods. You should often choose to use clear(), because its complexity is O(n), while the performance of removeAll(Collection C) is worse, and its complexity is O(n^2). This is why there is a huge difference between the two methods when resetting large lists. If you read their source code and run the example program below, the difference will be more obvious.

 

Clear() vs RemoveAll(Collection c)

 

In order to better compare the two methods, it is important to read their source code. The clear() method can be found in the java.utils.ArrayListclass, but I've included it here for convenience. The code below is from JDK 1.7.0_40 version. If you want to learn more about performance monitoring and tuning, I highly recommend reading Scott Oaksit Java Performance the Definitive Guide, which includes java 7 and a little java 8. Here is the code snippet for clear():

/**
 * Removes all of the elements from this list.The list will
 * be empty after this call returns.
 */
 public void clear() {
 	modCount++; // clear to let GC do its work
 	for (int i = 0; i < size; i++)
 		elementData[i] = null;
 	size = 0;
 }

 As you can see, clear() loops through the ArrayList and sets each element to null so that they can be garbage collected without being externally referenced. Similarly, we can java.util.AbstractCollectionview the code of removeAll(Collition c) in the class, the following is the code snippet:

public boolean removeAll(Collection<?> c) {
	//Check if the object is null
      Objects.requireNonNull(c);
      boolean modified = false;
      Iterator<?> it = iterator();
      while (it.hasNext()) {
          if (c.contains(it.next())) {
              it.remove();
              modified = true;
          }
      }
      return modified;
  }

 This method checks whether each element returned in sequence by the iterator is contained in a particular collection. If it exists, call the iterator's remove method to remove it from the collection. Because the contains method will be used, the complexity of removeAll is O(n^2). So this method is definitely not advisable when you want to reset a large ArrayList. Let's compare the performance difference between the two when resetting a 100K element.

remove all elements in a list of 100k elements

I was thinking of trying to reset a list with 10M elements in the example, but after waiting for more than half an hour for removeAll() to finish, I decided to reduce the number of elements to 100K. In this case, the gap between the two methods is also obvious. removeAll() took 10000 times longer than clear(). In fact, the purpose of the clear() and removeAll(Collection c) methods in the API is different. The clear() method is to reset the list by removing all elements, while removeAll(Collection c) is to remove some elements from the collection that are present in another provided collection, not to remove all elements from the collection . So if your purpose is to remove all elements, use clear(), if your purpose is to remove some elements that exist in another collection, then choose the removeAll(Collection c) method.

import java.util.ArrayList;
/**
 * Java Program to remove all elements from list in Java and comparing
 * performance of clearn() and removeAll() method.
 * * @author Javin Paul
 */
 public class ArrayListResetTest {
 
 	private static final int SIZE = 100_000;
 	public static void main(String args[]) {
 	
 	// Two ArrayList for clear and removeAll
 	ArrayList numbers = new ArrayList(SIZE);
 	ArrayList integers = new ArrayList(SIZE);
 	// Initialize ArrayList with 10M integers
 	for (int i = 0; i < SIZE; i++) {
 		numbers.add(new Integer(i));
 		integers.add(new Integer(i));
 	}
 	// Empty ArrayList using clear method
 	long startTime = System.nanoTime ();
 	numbers.clear();
 	long elapsed = System.nanoTime() - startTime;
 	System.out.println("Time taken by clear to empty ArrayList of 1M elements (ns): " + elapsed);
 	// Reset ArrayList using removeAll method
 	startTime = System.nanoTime ();
 	integers.removeAll(integers);
 	long time = System.nanoTime() - startTime;
 	System.out.println("Time taken by removeAll to reset ArrayList of 1M elements (ns): " + time);
 	}
 }
 	
 	Output:
 	Time taken by clear to empty ArrayList of 100000 elements (ns): 889619
 	Time taken by removeAll to reset ArrayList of 100000 elements (ns): 36633112126

 Since the program uses two arrayLists to store Integers, make sure you have enough memory at runtime, especially if you want to compare the performance difference between the two methods when the list has 1M elements. In addition, java7 is required to run due to the use of the feature of adding underscores to numbers. If you don't have JDK7, you can also remove the underscore in the SIZE constant.

 

That's all about how to reset an ArrayList. Not only did we learn the two methods for removing elements from a list, we also learned the difference between the clear() and removeAll() methods. We see why removeAll() performs poorly when the list is too large.
PS: When using the clear() method also takes a long time, consider creating a new list, because java can create a new object very quickly.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326707421&siteId=291194637