How do I join two lists in Java?

后端 未结 30 1686
旧巷少年郎
旧巷少年郎 2020-11-22 14:36

Conditions: do not modifiy the original lists; JDK only, no external libraries. Bonus points for a one-liner or a JDK 1.3 version.

Is there a simpler way than:

相关标签:
30条回答
  • 2020-11-22 15:14

    You can do a oneliner if the target list is predeclared.

    (newList = new ArrayList<String>(list1)).addAll(list2);
    
    0 讨论(0)
  • 2020-11-22 15:16

    Java 8 version with support for joining by object key:

    public List<SomeClass> mergeLists(final List<SomeClass> left, final List<SomeClass> right, String primaryKey) {
        final Map<Object, SomeClass> mergedList = new LinkedHashMap<>();
    
        Stream.concat(left.stream(), right.stream())
            .map(someObject -> new Pair<Object, SomeClass>(someObject.getSomeKey(), someObject))
            .forEach(pair-> mergedList.put(pair.getKey(), pair.getValue()));
    
        return new ArrayList<>(mergedList.values());
    }
    
    0 讨论(0)
  • 2020-11-22 15:16

    Almost of answers suggest to use an ArrayList.

    List<String> newList = new LinkedList<>(listOne);
    newList.addAll(listTwo);
    

    Prefer to use a LinkedList for efficient add operations.

    ArrayList add is O(1) amortized, but O(n) worst-case since the array must be resized and copied. While LinkedList add is always constant O(1).

    more infos https://stackoverflow.com/a/322742/311420

    0 讨论(0)
  • 2020-11-22 15:17

    One of your requirements is to preserve the original lists. If you create a new list and use addAll(), you are effectively doubling the number of references to the objects in your lists. This could lead to memory problems if your lists are very large.

    If you don't need to modify the concatenated result, you can avoid this using a custom list implementation. The custom implementation class is more than one line, obviously...but using it is short and sweet.

    CompositeUnmodifiableList.java:

    public class CompositeUnmodifiableList<E> extends AbstractList<E> {
    
        private final List<E> list1;
        private final List<E> list2;
    
        public CompositeUnmodifiableList(List<E> list1, List<E> list2) {
            this.list1 = list1;
            this.list2 = list2;
        }
    
        @Override
        public E get(int index) {
            if (index < list1.size()) {
                return list1.get(index);
            }
            return list2.get(index-list1.size());
        }
    
        @Override
        public int size() {
            return list1.size() + list2.size();
        }
    }
    

    Usage:

    List<String> newList = new CompositeUnmodifiableList<String>(listOne,listTwo);
    
    0 讨论(0)
  • 2020-11-22 15:17

    Slightly simpler:

    List<String> newList = new ArrayList<String>(listOne);
    newList.addAll(listTwo);
    
    0 讨论(0)
  • 2020-11-22 15:17
    public static <T> List<T> merge(@Nonnull final List<T>... list) {
        // calculate length first
        int mergedLength = 0;
        for (List<T> ts : list) {
          mergedLength += ts.size();
        }
    
        final List<T> mergedList = new ArrayList<>(mergedLength);
    
        for (List<T> ts : list) {
          mergedList.addAll(ts);
        }
    
        return mergedList;
      }
    
    0 讨论(0)
提交回复
热议问题