javalistrandom-access

How to efficiently merge two lists in Java?


There are several ways to merge lists in Java

What would be the most memory and performance efficient way to merge two random access lists into a new random access list?


Solution

  • Try this to create an immutable list containing all the elements, by performing a shallow copy. Beware that changes to the source lists will be reflected in the resulting list (so the immutability in reality depends on the immutability / access to the input lists).

    public class MergedList<T> extends AbstractList<T> {
    
        private final List<T>[] lists;
        private final int size;
    
        @SafeVarargs
        MergedList(List<T>... lists) {
            this.lists = lists.clone();
            this.size = Arrays.stream(lists).mapToInt(list -> list.size()).sum();
        }
    
        @Override
        public T get(int index) {
            for (List<T> list : lists)
                if (index < list.size())
                    return list.get(index);
                else
                    index -= list.size();
            throw new IndexOutOfBoundsException("index");
        }
    
        @Override
        public int size() {
            return size;
        }
    
    }
    

    and

    List<Integer> a = List.of(1, 2, 3, 4);
    List<Integer> b = List.of(5, 6, 7);
    List<Integer> c = new MergedList<>(a, b);
    System.out.println(c);
    

    output

    [1, 2, 3, 4, 5, 6, 7]
    

    Considering that the original list is updated, it might be better to remove the field size and do this:

        @Override
        public int size() {
            return Arrays.stream(lists).mapToInt(list -> list.size()).sum();
        }