854

Conditions: do not modify 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:

List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);
Robert Atkins
  • 20,676
  • 14
  • 60
  • 92
  • 6
    If you are doing this solely for iteration purposes see another question - there are google guava and java 8 solutions http://stackoverflow.com/questions/4896662/combine-multiple-collections-into-a-single-logical-collection – Boris Treukhov Jul 07 '14 at 15:43
  • Java 8 solution with utility method: http://stackoverflow.com/a/37386846/1216775 – akhil_mittal Apr 29 '17 at 05:40

32 Answers32

708

In Java 8:

List<String> newList = Stream.concat(listOne.stream(), listTwo.stream())
                             .collect(Collectors.toList());
azro
  • 35,213
  • 7
  • 25
  • 55
Dale Emery
  • 7,261
  • 1
  • 12
  • 14
  • 108
    Gawd, that's a thing in Java 8? Technically you win I guess, but that's a heck of a long line :-) – Robert Atkins Sep 09 '13 at 20:03
  • 1
    I wonder if creating and running through two Streams has a noticeable performance impact. I suppose it shouldn't, compared to creating two Iterators. – Jorn Sep 05 '16 at 16:02
  • 5
    For the casual reader, here is a shorter solution using also Java _ Streams: http://stackoverflow.com/a/34090554/363573 – Stephan Oct 04 '16 at 13:16
  • 7
    It is ugly but at least its fluent and can be used without multi line lambdas. I really wish there was a fluent addAll that returned the concatinated list. – Usman Ismail Jan 11 '18 at 15:06
  • 10
    I guess it's worth noting that it's really easy to get a distinct list out of this too, like so: `List newList = Stream.concat(listOne.stream(), listTwo.stream()).distinct().collect(Collectors.toList());` – Roger Dec 30 '18 at 19:18
  • 6
    Alternative to concat: stream of streams `Stream.of(listOne, listTwo).flatMap(Collection::stream).collect(Collectors.toList())` – Peter Walser Apr 09 '19 at 11:17
  • This is basically the same thing of C# `List l = list1.Union(list2).ToList();`, but is much more verbose. – zh chen Dec 27 '19 at 07:08
  • 1
    @PeterWalser That should be a separate answer, since it also allows more than one list. `flatMap`, good call! – Raphael Aug 27 '20 at 12:05
  • Usually, when I get to a point where the only reasonable API is the one for streams, I realize that `listOne` and `listTwo` should have been streams all along. – Raphael Aug 27 '20 at 12:06
625

Off the top of my head, I can shorten it by one line:

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);
AdamC
  • 15,105
  • 7
  • 47
  • 65
  • 169
    While you're technically correct, you have shortened it by one line, the asymmetry of this bugs me. Enough that I'm happier to "spend" the extra line. – Robert Atkins Dec 15 '11 at 00:54
  • 17
    Isn't there a problem here where the newList's interal array will be initialized to the size of listOne and then have to potentially expand when adding all of the items from listTwo? Would it be better to take the size of each list and use that to size the new array? – Eric Mar 02 '16 at 08:38
  • 3
    This was the solution that worked best for me. I made a comparison on the performance of different solutions this came out winner, together with creating the empty list and then `addAll()` of both. I tried all those that suggest not copying the lists and they result having a lot of overhead we didn't need this time. – manuelvigarcia Sep 26 '16 at 06:46
  • Use a `LinkedList` over `ArrayList` for efficient adding. https://stackoverflow.com/a/322742/311420 – Raymond Chenon Apr 07 '20 at 14:49
346

You could use the Apache commons-collections library:

List<String> newList = ListUtils.union(list1, list2);
Neuron
  • 3,776
  • 3
  • 24
  • 44
Guillermo
  • 3,605
  • 1
  • 12
  • 2
  • 64
    Nice, but requires apache commons. He did specify 'no external libraries' – Quantum7 Apr 26 '11 at 01:17
  • 112
    @Quantum7, still useful for other people ;) Also, is apache commons even an external library? I don't start anything without it! – tster Mar 30 '12 at 23:31
  • 29
    @Platinum No, according to the docs ListUtils.union is exactly equivalent to OP's code. But perhaps it is misleading to use a SET operation ("Union") in a list context. I can see how you might expect this to remove duplicates or something, but it appears the method does not do that. – Quantum7 Dec 17 '12 at 23:52
  • 28
    Avoid Apache Commons Collections. It’s not typesafe, there are no generics. Great if you use Java 1.4, but for Java 5 and above, I’d prefer Google Guava. – Michael Piefel Sep 08 '13 at 19:37
  • 1
    @MichaelPiefel it seems the only method missing from Guava is a Lists.concat(...) method. – Richard Nov 22 '13 at 10:34
  • 3
    @Richard Yes, but how about `Iterables.concat()`? Most of the times its exactly what you want. If you absolutely need a new list, use `Lists.newArrayList(Iterables.concat(…))`. – Michael Piefel Nov 25 '13 at 09:35
  • 13
    @MichaelPiefel The latest Apache Commons Collections 4 is type-safe. With Java 8 method reference, this kind of static utilities become very important. – mingfai Jan 21 '14 at 18:17
  • Apache's ListUtils is a very good library, easy to use ListUtils.uniion(list1, list2) as you say, but do you need the other methods, for instance longestCommonSubsequence(...) or fixedSizeList(...)? Can be useful to consider what else is dragged in that you might not need when it is so easy to join lists as List.addAll() – Tzen Dec 15 '16 at 11:20
  • 2
    Upvoted as this is the only answer that didn't require multiple method calls. Streams are fun, but having to do n method calls for every...single...little....thing... seems error prone. Joining two lists SHOULD be a simple operation. – Michael Haefele Oct 25 '17 at 13:30
  • 1
    Unfortunately, ListUtils.union() does not support more than 2 parameters – Pat Myron May 09 '18 at 00:14
  • But the union of two lists includes only distinct elements. Joining two lists must include all elements (duplicates or not). – Kareem Jeiroudi Apr 19 '21 at 09:24
145

Another Java 8 one-liner:

List<String> newList = Stream.of(listOne, listTwo)
                            .flatMap(Collection::stream)
                            .collect(Collectors.toList());

As a bonus, since Stream.of() is variadic, you may concatenate as many lists as you like.

List<String> newList = Stream.of(listOne, listTwo, listThree)
                            .flatMap(Collection::stream)
                            .collect(Collectors.toList());
Littm
  • 4,895
  • 4
  • 28
  • 36
Mark
  • 2,067
  • 1
  • 12
  • 5
98

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<? extends E> list1;
    private final List<? extends E> list2;

    public CompositeUnmodifiableList(List<? extends E> list1, List<? extends 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);
ursa
  • 3,680
  • 1
  • 19
  • 36
Kevin K
  • 9,050
  • 2
  • 34
  • 58
  • 12
    This is a workable solution, but do note that if the underlying list objects change (list1, list2), the contents of this list change. You may not be able to modify an instance of the CompositeUnmodifiableList _itself_ but if you can get a reference to the original lists, then you can. Also for those that are unfamiliar: the final modifier just affects the _reference_ to the list object itself can't change but it's still possible for the contents of the list to change! – jwj Sep 16 '14 at 03:34
  • 3
    @jwj all very good points, thank you. The class name probably deserves some explanation. I see this class as doing something very similar to the `Collections.unmodifiableList()` method, which wraps a list to make it unmodifiable. `CompositeUnmodifiableList` does the same thing, except it wraps two lists and provides a concatenated view. All the points you make about `CompositeUnmodifiableList` are also true of `Collections.unmodifiableList()` as well. – Kevin K Feb 23 '15 at 16:22
  • 2
    The constructor can take `List extends E>` – Patrick Parker Feb 05 '17 at 13:48
92

Probably not simpler, but intriguing and ugly:

List<String> newList = new ArrayList<String>() { { addAll(listOne); addAll(listTwo); } };

Don't use it in production code... ;)

Tim Cooper
  • 144,163
  • 35
  • 302
  • 261
volley
  • 6,355
  • 1
  • 25
  • 28
  • 1
    Irresponsible use of annonymous class. As the OP said - don't use it in production code. – ddimitrov Oct 10 '08 at 13:55
  • 49
    Ugly and evil, just as almost any use of double brace initialization. It ís shorter, though ;) – Jorn Aug 15 '09 at 20:50
  • 1
    +1, nice. Although Eclipse splits over six lines for me, and tells me to `@SuppressWarnings("serial")`. :-) – MarnixKlooster ReinstateMonica May 07 '11 at 06:28
  • 5
    @MarnixKlooster: Eclipse *knows* that you should not use it and makes it unpleasant to use ;-) – Joachim Sauer Oct 03 '11 at 07:06
  • 1
    that is know as a "double brace object" which very handy in junit test code to create an object which returns a given value as you can invoke the protected setter right there and pass in some final reference to test data. then again with a good mocking framework... – simbo1905 Aug 01 '12 at 13:53
  • 23
    Though it is physically one line, I do not consider this a "one-liner". – splungebob Dec 13 '12 at 21:28
  • 11
    why do people hate anonymous block initializers – NimChimpsky Dec 21 '12 at 13:01
  • 20
    @NimChimpsky I think it's mostly because it's not just an anonymous block initializer, but you're actually creating an anonymous subclass of ArrayList. That being said, if you trust the results of this [Double Brace Initilization question](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization), it makes it seem like hating DBI is mostly a matter of stylistic taste and micro-optimization. As far as I can tell, there are no major penalties for doing it. The sneaky downside would be if you ever tried to compare its class because it won't be ArrayList. – Patrick Dec 27 '12 at 17:15
  • @MarnixKlooster it doesn't tell you to add suppress warnings, it tells you there's something wrong with the code, and of course "if you turn the log-level to FATAL you don't get DEBUG messages" – TWiStErRob Aug 28 '13 at 15:25
  • 2
    How does the use of double brace initialization makes it a one-liner? – Jimmy T. Sep 08 '13 at 23:14
  • 1
    @NimChimpsky another reason why anonymous block initializers may be evil is that they will leak the outer object instance same as any anonymous class in Java. However, should be safe to use in static methods. – riwnodennyk Dec 28 '16 at 12:31
  • 2
    @NimChimpsky You can check out this article about the disadvantages of double brace initialisation: [Don’t be “Clever”: The Double Curly Braces Anti Pattern](https://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/) – Alex May 30 '17 at 07:41
80

Not simpler, but without resizing overhead:

List<String> newList = new ArrayList<>(listOne.size() + listTwo.size());
newList.addAll(listOne);
newList.addAll(listTwo);
Martin
  • 1,917
  • 20
  • 22
56

Found this question looking to concatenate arbitrary amount of lists, not minding external libraries. So, perhaps it will help someone else:

com.google.common.collect.Iterables#concat()

Useful if you want to apply the same logic to a number of different collections in one for().

Yuri Geinish
  • 15,680
  • 5
  • 31
  • 35
  • 10
    For example: Lists.newArrayList(Iterables.concat(list1,list2)); – meilechh Feb 13 '14 at 17:14
  • you should call `com.google.common.collect.Iterators#concat(java.util.Iterator extends java.util.Iterator extends T>>)` instead of `Iterables#concat()`; because the later still copy elements into temp link! – bob Apr 14 '16 at 06:36
51

Java 8 (Stream.of and Stream.concat)

The proposed solution is for three lists though it can be applied for two lists as well. In Java 8 we can make use of Stream.of or Stream.concat as:

List<String> result1 = Stream.concat(Stream.concat(list1.stream(),list2.stream()),list3.stream()).collect(Collectors.toList());
List<String> result2 = Stream.of(list1,list2,list3).flatMap(Collection::stream).collect(Collectors.toList());

Stream.concat takes two streams as input and creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream. As we have three lists we have used this method (Stream.concat) two times.

We can also write a utility class with a method that takes any number of lists (using varargs) and returns a concatenated list as:

public static <T> List<T> concatenateLists(List<T>... collections) {
        return Arrays.stream(collections).flatMap(Collection::stream).collect(Collectors.toList()); 
}

Then we can make use of this method as:

List<String> result3 = Utils.concatenateLists(list1,list2,list3);
akhil_mittal
  • 18,855
  • 7
  • 83
  • 82
48

Here is a java 8 solution using two lines:

List<Object> newList = new ArrayList<>();
Stream.of(list1, list2).forEach(newList::addAll);

Be aware that this method should not be used if

  • the origin of newList is not known and it may already be shared with other threads
  • the stream that modifies newList is a parallel stream and access to newList is not synchronized or threadsafe

due to side effect considerations.

Both of the above conditions do not apply for the above case of joining two lists, so this is safe.

Based on this answer to another question.

SpaceTrucker
  • 11,729
  • 6
  • 48
  • 95
  • 15
    If I am not wrong this is actually not recommended - docs.oracle.com/javase/8/docs/api/java/util/stream/… Please see side -effects section. > Side-effects in behavioral parameters to stream operations are, in general, discouraged, as they can often lead to unwitting violations of the statelessness requirement, as well as other thread-safety hazards. So in this case it is better to use Collectors.toList() – Anton Balaniuc Mar 14 '17 at 15:31
  • @AntonBalaniuc Question is if whether this is really a side effect. At that point `newList` is not observable by any other thread. But you are correct that this probably shouldn't be done if it is unknown where the value of `newList`came from (for example if `newList` was passed as a parameter. – SpaceTrucker Jul 11 '17 at 05:45
  • 2
    I'm curious; why `.forEach(newList::addAll);` instead of `.collect(Collectors.toList());`? – 11684 Aug 22 '17 at 10:16
  • 5
    @11684 because the collector would collect a `List>`. What you may have in mind is something like this: https://stackoverflow.com/questions/189559/how-do-i-join-two-lists-in-java/37386846#37386846 – SpaceTrucker Aug 22 '17 at 11:23
  • @SpaceTrucker Oops, I overlooked that. Thanks for clearing up my confusion. Yes, I should have been thinking of `flatMap`. – 11684 Aug 22 '17 at 11:26
36

This is simple and just one line, but will add the contents of listTwo to listOne. Do you really need to put the contents in a third list?

Collections.addAll(listOne, listTwo.toArray());
ceklock
  • 5,596
  • 10
  • 52
  • 75
  • 14
    Not modifying the original lists was one of the criteria, but this is useful to have here as an example for situations where that's not a constraint. – Robert Atkins Sep 09 '13 at 20:01
  • 4
    Thanks, or even simpler listOne.addAll(listTwo) – Jay Jan 03 '20 at 16:23
31

Slightly simpler:

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);
Xaerxess
  • 25,634
  • 7
  • 81
  • 101
Tim
  • 6,531
  • 11
  • 38
  • 45
  • Would this cause duplicated Strings? Meaning a String that exists in both list will exist twice in the resulting list? – AgentKnopf Jun 13 '12 at 10:33
  • 4
    @Zainodis Yes, there could be duplicates. The `List` structure imposes no uniqueness constraints. You can remove dupes by doing the same thing with sets. `Set newSet = new HashSet<>(setOne); newSet.addAll(setTwo);` – Patrick Dec 27 '12 at 17:01
21

A little shorter would be:

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);
Jorn
  • 16,599
  • 15
  • 67
  • 103
18

You can create your generic Java 8 utility method to concat any number of lists.

@SafeVarargs
public static <T> List<T> concat(List<T>... lists) {
    return Stream.of(lists).flatMap(List::stream).collect(Collectors.toList());
}
Daniel Hári
  • 5,551
  • 4
  • 36
  • 48
13

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

(newList = new ArrayList<String>(list1)).addAll(list2);
deterb
  • 3,878
  • 1
  • 24
  • 33
12

In Java 8 (the other way):

List<?> newList = 
Stream.of(list1, list2).flatMap(List::stream).collect(Collectors.toList());
noufalcep
  • 2,996
  • 15
  • 28
  • 46
Nitin Jain
  • 169
  • 1
  • 8
10

another one liner solution using Java8 stream, since flatMap solution is already posted, here is a solution without flatMap

List<E> li = lol.stream().collect(ArrayList::new, List::addAll, List::addAll);

or

List<E> ints = Stream.of(list1, list2).collect(ArrayList::new, List::addAll, List::addAll);

code

    List<List<Integer>> lol = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
    List<Integer> li = lol.stream().collect(ArrayList::new, List::addAll, List::addAll);
    System.out.println(lol);
    System.out.println(li);

output

[[1, 2, 3], [4, 5, 6]]
[1, 2, 3, 4, 5, 6]
Saravana
  • 11,085
  • 2
  • 29
  • 43
  • 1
    I would add that this solution is probably more performant than the one using `flatMap`, because the lists are only iterated once when they are collected – Stefan Haberl May 23 '17 at 09:01
  • I dont think `flatMap` causes additional iteration, could you clarify? – wilmol Mar 30 '21 at 21:05
8

We can join 2 lists using java8 with 2 approaches.

    List<String> list1 = Arrays.asList("S", "T");
    List<String> list2 = Arrays.asList("U", "V");

1) Using concat :

    List<String> collect2 = Stream.concat(list1.stream(), list2.stream()).collect(toList());
    System.out.println("collect2 = " + collect2); // collect2 = [S, T, U, V]

2) Using flatMap :

    List<String> collect3 = Stream.of(list1, list2).flatMap(Collection::stream).collect(toList());
    System.out.println("collect3 = " + collect3); // collect3 = [S, T, U, V]
Himank Batra
  • 161
  • 1
  • 2
  • 3
    When answering an eleven year old question with thirty other answers be sure to point out what new aspects of the question your answer addresses, and to note if these techniques would have worked when the question was asked, or if they depend on features that have been introduced over the years. – Jason Aller Mar 25 '20 at 18:05
8

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

Raymond Chenon
  • 8,990
  • 10
  • 64
  • 97
7

The smartest in my opinion:

/**
 * @param smallLists
 * @return one big list containing all elements of the small ones, in the same order.
 */
public static <E> List<E> concatenate (final List<E> ... smallLists)
{
    final ArrayList<E> bigList = new ArrayList<E>();
    for (final List<E> list: smallLists)
    {
        bigList.addAll(list);
    }
    return bigList;
}
Olivier Faucheux
  • 2,242
  • 3
  • 27
  • 33
6

You could do it with a static import and a helper class

nb the generification of this class could probably be improved

public class Lists {

   private Lists() { } // can't be instantiated

   public static List<T> join(List<T>... lists) {
      List<T> result = new ArrayList<T>();
      for(List<T> list : lists) {
         result.addAll(list);
      }
      return results;
   }

}

Then you can do things like

import static Lists.join;
List<T> result = join(list1, list2, list3, list4);
FDinoff
  • 28,493
  • 5
  • 67
  • 88
Dave Cheney
  • 5,137
  • 2
  • 16
  • 23
6

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());
}
cslysy
  • 791
  • 6
  • 11
4

Use a Helper class.

I suggest:

public static <E> Collection<E> addAll(Collection<E> dest, Collection<? extends E>... src) {
    for(Collection<? extends E> c : src) {
        dest.addAll(c);
    }

    return dest;
}

public static void main(String[] args) {
    System.out.println(addAll(new ArrayList<Object>(), Arrays.asList(1,2,3), Arrays.asList("a", "b", "c")));

    // does not compile
    // System.out.println(addAll(new ArrayList<Integer>(), Arrays.asList(1,2,3), Arrays.asList("a", "b", "c")));

    System.out.println(addAll(new ArrayList<Integer>(), Arrays.asList(1,2,3), Arrays.asList(4, 5, 6)));
}
alex
  • 5,094
  • 1
  • 22
  • 33
4
public static <T> List<T> merge(List<T>... args) {
    final List<T> result = new ArrayList<>();

    for (List<T> list : args) {
        result.addAll(list);
    }

    return result;
}
martyglaubitz
  • 942
  • 9
  • 20
3
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;
  }
Langusten Gustel
  • 10,469
  • 9
  • 42
  • 56
0

I'm not claiming that it's simple, but you mentioned bonus for one-liners ;-)

Collection mergedList = Collections.list(new sun.misc.CompoundEnumeration(new Enumeration[] {
    new Vector(list1).elements(),
    new Vector(list2).elements(),
    ...
}))
Ryan Tenney
  • 1,805
  • 2
  • 16
  • 29
ddimitrov
  • 3,139
  • 3
  • 28
  • 44
  • why should someone never use those? – David Jun 03 '13 at 16:27
  • 6
    @David because it aimed to be used internally in JDK. If you used that in your code, your code will quite probably not running on non-Sun (or non-Oracle now) JDK/JRE. – Adrian Shum Jul 23 '13 at 07:06
  • @AdrianShum Are there other JDKs/JREs than Oracle? That would surprise me. Even if limited to the most common API functionality, rebuilding that whole stuff would probably take ages... – Egor Hans Sep 02 '17 at 10:52
  • 1
    There is quite a lot of JVM. Most commonly seen one in enterprise world should be the IBM one which is, iirc, bundled with websphere – Adrian Shum Sep 02 '17 at 11:41
  • whenever you see usages of `Vector`, take a 5 minute break. – bvdb Jul 22 '20 at 15:11
0

Here's an approach using streams and java 8 if your lists have different types and you want to combine them to a list of another type.

public static void main(String[] args) {
    List<String> list2 = new ArrayList<>();
    List<Pair<Integer, String>> list1 = new ArrayList<>();

    list2.add("asd");
    list2.add("asdaf");
    list1.add(new Pair<>(1, "werwe"));
    list1.add(new Pair<>(2, "tyutyu"));

    Stream stream = Stream.concat(list1.stream(), list2.stream());

    List<Pair<Integer, String>> res = (List<Pair<Integer, String>>) stream
            .map(item -> {
                if (item instanceof String) {
                    return new Pair<>(0, item);
                }
                else {
                    return new Pair<>(((Pair<Integer, String>)item).getKey(), ((Pair<Integer, String>)item).getValue());
                }
            })
            .collect(Collectors.toList());
}
shinzou
  • 4,689
  • 6
  • 48
  • 103
0

If you want to do this statically you can the following.

The examples uses 2 EnumSets in natural-order (==Enum-order) A, B and joins then in an ALL list.

public static final EnumSet<MyType> CATEGORY_A = EnumSet.of(A_1, A_2);
public static final EnumSet<MyType> CATEGORY_B = EnumSet.of(B_1, B_2, B_3);

public static final List<MyType> ALL = 
              Collections.unmodifiableList(
                  new ArrayList<MyType>(CATEGORY_A.size() + CATEGORY_B.size())
                  {{
                      addAll(CATEGORY_A);
                      addAll(CATEGORY_B);
                  }}
              );
Jan Weitz
  • 444
  • 4
  • 11
0

No way near one-liner, but I think this is the simplest:

List<String> newList = new ArrayList<String>(l1);
newList.addAll(l2);

for(String w:newList)
        System.out.printf("%s ", w);
Daniel Rikowski
  • 66,219
  • 52
  • 237
  • 318
nirmal
  • 9
  • 1
-3
import java.util.AbstractList;
import java.util.List;


/**
 * The {@code ConcatList} is a lightweight view of two {@code List}s.
 * <p>
 * This implementation is <em>not</em> thread-safe even though the underlying lists can be.
 * 
 * @param <E>
 *            the type of elements in this list
 */
public class ConcatList<E> extends AbstractList<E> {

    /** The first underlying list. */
    private final List<E> list1;
    /** The second underlying list. */
    private final List<E> list2;

    /**
     * Constructs a new {@code ConcatList} from the given two lists.
     * 
     * @param list1
     *            the first list
     * @param list2
     *            the second list
     */
    public ConcatList(final List<E> list1, final List<E> list2) {
        this.list1 = list1;
        this.list2 = list2;
    }

    @Override
    public E get(final int index) {
        return getList(index).get(getListIndex(index));
    }

    @Override
    public E set(final int index, final E element) {
        return getList(index).set(getListIndex(index), element);
    }

    @Override
    public void add(final int index, final E element) {
        getList(index).add(getListIndex(index), element);
    }

    @Override
    public E remove(final int index) {
        return getList(index).remove(getListIndex(index));
    }

    @Override
    public int size() {
        return list1.size() + list2.size();
    }

    @Override
    public boolean contains(final Object o) {
        return list1.contains(o) || list2.contains(o);
    }

    @Override
    public void clear() {
        list1.clear();
        list2.clear();
    }

    /**
     * Returns the index within the corresponding list related to the given index.
     * 
     * @param index
     *            the index in this list
     * 
     * @return the index of the underlying list
     */
    private int getListIndex(final int index) {
        final int size1 = list1.size();
        return index >= size1 ? index - size1 : index;
    }

    /**
     * Returns the list that corresponds to the given index.
     * 
     * @param index
     *            the index in this list
     * 
     * @return the underlying list that corresponds to that index
     */
    private List<E> getList(final int index) {
        return index >= list1.size() ? list2 : list1;
    }

}
benez
  • 1,244
  • 12
  • 19
-6

I can't improve on the two-liner in the general case without introducing your own utility method, but if you do have lists of Strings and you're willing to assume those Strings don't contain commas, you can pull this long one-liner:

List<String> newList = new ArrayList<String>(Arrays.asList((listOne.toString().subString(1, listOne.length() - 1) + ", " + listTwo.toString().subString(1, listTwo.length() - 1)).split(", ")));

If you drop the generics, this should be JDK 1.4 compliant (though I haven't tested that). Also not recommended for production code ;-)

Dov Wasserman
  • 2,536
  • 16
  • 13
  • 2
    That is one disgusting line of code. Probably highly more performance intensive than all the other solutions (combined), makes a ton of assumptions you should really not have to make, not really a one-liner (you can put an entire program into one line _technically_). – luk2302 Aug 17 '16 at 15:03
  • 2
    @luk2302 Contains no semicolons though (except at the end), so it can be considered a one-liner. – Egor Hans Sep 02 '17 at 09:24
  • oh boy, what if the items in the list have comma in them? – regulus Aug 26 '20 at 22:36
-7
public class TestApp {

/**
 * @param args
 */
public static void main(String[] args) {
    System.out.println("Hi");
    Set<List<String>> bcOwnersList = new HashSet<List<String>>();
    List<String> bclist = new ArrayList<String>();
    List<String> bclist1 = new ArrayList<String>();
    List<String> object = new ArrayList<String>();
    object.add("BC11");
    object.add("C2");
    bclist.add("BC1");
    bclist.add("BC2");
    bclist.add("BC3");
    bclist.add("BC4");
    bclist.add("BC5");
    bcOwnersList.add(bclist);
    bcOwnersList.add(object);

    bclist1.add("BC11");
    bclist1.add("BC21");
    bclist1.add("BC31");
    bclist1.add("BC4");
    bclist1.add("BC5");

    List<String> listList= new ArrayList<String>();
    for(List<String> ll : bcOwnersList){
        listList = (List<String>) CollectionUtils.union(listList,CollectionUtils.intersection(ll, bclist1));
    }
    /*for(List<String> lists : listList){
        test = (List<String>) CollectionUtils.union(test, listList);
    }*/
    for(Object l : listList){
        System.out.println(l.toString());
    }
    System.out.println(bclist.contains("BC"));

}

}
Daniel Rikowski
  • 66,219
  • 52
  • 237
  • 318