Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Collection addAll complexity

Is there a Java collection with a complexity of O(1) and not O(n) for the addAll operation, or must I implement my own collection ? With a efficient linked list the Collection1.addAll(Collection2) operation should append the second collection to the first adding the first node of collection2 to the last of collection 1 and the others follow. But it' s not that I read into the documentation it seems to use an Iterator so I guess the complexity is O( collection2.size).

Is that right ?

like image 553
Monsio Jérémie Béhi Avatar asked Jul 12 '16 08:07

Monsio Jérémie Béhi


People also ask

What is time complexity of collections in Java?

It iterates through the internal array and checks each element one by one, so the time complexity for this operation always requires O(n) time.

Is addAll faster than add?

AddAll is faster than Add Similarly, addAll provides higher operations per second when compared with add . So next time when you are adding something to an array make sure that you pile them and add it using addAll .

What is collections addAll in Java?

The addAll() method of java. util. Collections class is used to add all of the specified elements to the specified collection. Elements to be added may be specified individually or as an array. The behavior of this convenience method is identical to that of c.


2 Answers

ArrayList is probably as good as it gets in this respect, but it actually depends on the supplied collection as well. The best-case complexity is O(1), but only if the supplied Collection's toArray() method also has constant complexity.

The System.arrayCopy() call that does the actual allocation is O(1), anyway is complicated, see below:

// java.util.ArrayList.addAll
// Oracle JDK 1.8.0_91
public boolean addAll(Collection<? extends E> c) {
    Object[] a = c.toArray(); // O(?) <-- depending on other type
    int numNew = a.length;
    ensureCapacityInternal(size + numNew);  // Increments modCount
    System.arraycopy(a, 0, elementData, size, numNew); 
    size += numNew;
    return numNew != 0;
}

There's some disagreement on whether System.arrayCopy is a constant-time operation. Some say no. Others suggest it is.

According to this benchmark I hacked together, it's somewhere in the middle. Copy Times stay pretty much constant up to about 100 array items, but grow linear from there on, I am guessing some kind of paging is involved there. So effectively, System.arrayCopy has linear time complexity unless the arrays are very small.

like image 107
Sean Patrick Floyd Avatar answered Sep 29 '22 14:09

Sean Patrick Floyd


Even the optimization for linked lists can only work if you move items from one linked list to another.

You could build an own kind of collection, however, which has one more level of indirection, i. e. which contains a collection of collections. This way, adding whole collection is quite cheap, and so is iterating. Indexing or length determination can become quite expensive, however.

like image 27
glglgl Avatar answered Sep 29 '22 13:09

glglgl