tags:

views:

159

answers:

3

Does anyone know if it's possible to merge two lists (or any collection) in constant time in Java ?

http://www.cppreference.com/wiki/stl/list/splice

It's so easy to do that using linked lists in C...

Thanks,

+6  A: 

The classes in the JDK library don't support this, as far as I know.

It's possible if you build your own implementation of List - which you're free to do, it's perfectly legal. You could use LinkedLists and recognize the special case that the collection to be added is also a LinkedList.

In documenting your class, you'd need to point out that the added object becomes part of the new object, in other words a lot of generality is lost. There's also lots of potential for error: Altering either of the original lists (if they're mutable) after joining would allow you to create a list with a gap in it, or with two tails. Also, most other operations wouldn't benefit from your hacked-up class. In other words, at first blush it seems like a crazy idea.

Note that "merging" lists usually has different connotations; when merging sorted lists, for example, one would expect the resultant list to have the same ordering. What you're talking about with joining two Linked Lists is really better termed as "splicing". Or maybe just "joining."

Carl Smotricz
Very nice, thanks.
Damien
A: 

If it's easy to do with a linked list in C, then I'd guess that the LinkedList class offers the same performance

All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.

List list1 = new LinkedList();
list1.add(...);
List list2 = new LinkedList();
list2.add(...);

list1.addAll(list2);

edit: Nevermind. Looks like LinkedList.addAll(Collection) invokes LinkedList.addAll(int, Collection) which iterates through the new collection.

matt b
This doesn't merge the two lists in constant time though - Performance is O(n).
Adamski
Yes, see my update
matt b
I looked only at the [OpenJDK code](http://www.docjar.com/html/api/java/util/LinkedList.java.html) for LinkedList, but as I suspected that doesn't have a special case for `addAll(LinkedList)`. `addAll` simply creates (using `new`) new links every element added from the other list.
Carl Smotricz
+2  A: 

You could implement a Composite "wrapper" around multiple Lists. For simplicity I've made my example immutable but you could always implement add to append to the "final" List stored within the composite object.

public class CompositeImmutableList<T> implements List<T> {
  private final List<T> l1;
  private final List<T> l2;

  public CompositeImmutableList(List<T> l1, List<T> l2) {
    this.l1 = l1;
    this.l2 = l2;
  }

  public boolean add(T t) {
    throw new UnsupportedOperationException();
  }

  public int size() {
    return l1.size() + l2.size();
  }

  public T get(int i) {
    int sz1 = l1.size();
    return i < s1 : l1.get(i) : l2.get(sz1 - i);
  }

  // TODO: Implement remaining List API methods.
}
Adamski