如何在Java中加入两个列表?

How do I join two lists in Java?

条件:不修改原始列表;仅JDK,无外部库。一行程序或JDK 1.3版本的奖励积分。

有没有比以下更简单的方法:

1
2
3
List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);


从顶部的我的头,我可以是一个线Shorten):

1
2
List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);


8:在Java

1
2
List<String> newList = Stream.concat(listOne.stream(), listTwo.stream())
                             .collect(Collectors.toList());


你可以使用Apache Commons -收藏的图书馆

1
List<String> newList = ListUtils.union(list1, list2);


你的要求是一个保留原来的列表。如果你创建一个新的列表和使用addAll()倍增,你是从数量的对象的引用在您的名单。这可能会导致内存问题,如果你的名单是非常大的。

如果你需要,你可以修改的concatenated避免这种结果,使用自定义列表实现。自定义类的实现是一个以上的线,它是...but显然使用短和甜蜜。

compositeunmodifiablelist.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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();
    }
}

用法:

1
List<String> newList = new CompositeUnmodifiableList<String>(listOne,listTwo);


不可能simpler和丑陋的,但intriguing:

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

不使用它在生产代码。);


不simpler大小,但没有间接费用:

1
2
3
List<String> newList = new ArrayList<>(listOne.size() + listTwo.size());
newList.addAll(listOne);
newList.addAll(listTwo);

一个java的一套8。

1
2
3
List<String> newList = Stream.of(listOne, listTwo)
                             .flatMap(x -> x.stream())
                             .collect(Collectors.toList());

的奖金,因为你可以Stream.of()是可变的连接列表,有你喜欢的。

1
2
3
List<String> newList = Stream.of(listOne, listTwo, listThree)
                             .flatMap(x -> x.stream())
                             .collect(Collectors.toList());


发现这一问题的量表,对任意连接,不minding外部库。所以,也许这将帮助别人。

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

如果你想用相同的逻辑应用到不同的集合在一个数是()。


在Java中使用的是双线:8

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

要知道,这不应该被用于该法

  • newList没有已知的起源和它可能已经被其他线程共享。
  • 这是一modifies newList小溪流和并行访问是不同步和线程安全的newList

由于对侧效应考虑。

上述两个条件的情况下,不申请加入两个以上的操作系统列表,这是安全的。

基于这一问题的答案到另一个。


这是一个简单的,只是将网站的内容,但listtwo Listone添加到。你真的需要放在第三个表的内容?

1
Collections.addAll(listOne, listTwo.toArray());


建议的解决方案是,它可以用三个列表的列表的双阱。在Java中使用8,我们可以做的:stream.of或stream.concat

1
2
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以扩展其在lazily concatenated流元素的所有元素的所有元素的第一流的大学之后,第二个流。我们已经用这种方法,我们有三个表(Stream.concat)的两倍。

我们也可以写的工具类和方法,以任何数量的列表(用concatenated varargs)和返回的列表:

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

然后,我们可以使用这种方法制造的。

1
List<String> result3 = Utils.concatenateLists(list1,list2,list3);


simpler点:

1
2
List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);


小短将是:

1
2
List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);

你的目标可以是一oneliner如果是清单。

1
(newList = new ArrayList<String>(list1)).addAll(list2);


您可以创建通用Java 8实用工具方法来记录任意数量的列表。

1
2
3
4
@SafeVarargs
public static <T> List<T> concat(List<T>... lists) {
    return Stream.of(lists).flatMap(List::stream).collect(Collectors.toList());
}

一个一个解决方案,利用线性Java8流解决方案,从一flatMap已经发布的解决方案,这是不flatMap

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

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

代码

1
2
3
4
    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);

输出

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


在Java 8中(另一种方式):

1
2
List<?> newList =
Stream.of(list1, list2).flatMap(List::stream).collect(Collectors.toList());


在我看来:"smartest

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * @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;
}


你可以做它与静态导入和辅助类

这个类可以在generification Nb是可能的改进

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
   }

}

你可以喜欢的东西

1
2
import static Lists.join;
List<T> result = join(list1, list2, list3, list4);


支持对象键连接的Java 8版本:

1
2
3
4
5
6
7
8
9
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());
}

使用助手类。

我suggest:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)));
}

1
2
3
4
5
6
7
8
9
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;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
  }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import java.util.AbstractList;
import java.util.List;


/**
 * The {@code ConcatList} is a lightweight view of two {@code List}s.
 * <p>

 * This implementation is not 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;
    }

}


如果您想静态地执行此操作,可以执行以下操作。

示例使用2个自然顺序的枚举(=enum order)A, B,然后联接到ALL列表中。

1
2
3
4
5
6
7
8
9
10
11
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);
                  }}
              );


我不称这是简单的,但你提到的是一个额外的衬垫;-)

1
2
3
4
5
Collection mergedList = Collections.list(new sun.misc.CompoundEnumeration(new Enumeration[] {
    new Vector(list1).elements(),
    new Vector(list2).elements(),
    ...
}))


这一方法使用流的,如果你有一个表8和Java的不同类型,你想把他们的另一个类型的列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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());
}

在附近的一个线性的方式,但我认为这是最简:

1
2
3
4
5
List<String> newList = new ArrayList<String>(l1);
newList.addAll(l2);

for(String w:newList)
        System.out.printf("%s", w);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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"));

}

}


I can’t提高在线两套通用案例中没有介绍自己的效用的方法,但如果你有一个字符串列表(和你愿意承担这些字符串不包含commas,你可以拉这一套:龙

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

如果你丢的仿制药,这应该是兼容的JDK 1.4(虽然我已经测试,T)。建议的代码也不生产的;-)