条件:不修改原始列表; 仅限JDK,没有外部库.单行或JDK 1.3版本的奖励积分.
有没有比以下更简单的方法:
ListnewList = new ArrayList (); newList.addAll(listOne); newList.addAll(listTwo);
AdamC.. 543
在我的头顶,我可以缩短一行:
ListnewList = new ArrayList (listOne); newList.addAll(listTwo);
虽然你在技术上是正确的,但你已经将它缩短了一行,这种不对称性使我感到不安.够了,我更乐意"花"额外的路线. (145认同)
这里有没有问题,newList的interal数组将初始化为listOne的大小,然后在添加listTwo的所有项目时必须扩展?获取每个列表的大小并使用它来调整新数组的大小会更好吗? (13认同)
这是最适合我的解决方案.我对不同解决方案的性能进行了比较,这些解决方案获得了胜利,同时创建了空列表,然后创建了两个`addAll()`.我尝试了所有那些建议不复制列表的人,结果我们这次不需要很多开销. (2认同)
Dale Emery.. 523
在Java 8中:
ListnewList = Stream.concat(listOne.stream(), listTwo.stream()) .collect(Collectors.toList());
Gawd,这是Java 8中的一个东西吗?从技术上讲,你我赢了,但这是一个很长的路线:-) (65认同)
它很丑,但至少它流畅,可以在没有多线lambda的情况下使用.我真的希望有一个流畅的addAll返回到concatinated列表. (7认同)
对于休闲读者来说,这是一个使用Java _ Streams的更短的解决方案:http://stackoverflow.com/a/34090554/363573 (4认同)
我想值得注意的是,从中也可以很容易地得到一个独特的列表,就像这样:`List <String> newList = Stream.concat(listOne.stream(),listTwo.stream())。distinct()。 collect(Collectors.toList());` (4认同)
小智.. 276
您可以使用Apache commons-collections库:
ListnewList = ListUtils.union(list1, list2);
@Quantum7,对其他人仍然有用;)另外,apache公共甚至是外部库吗?没有它,我什么都没开始! (95认同)
很好,但需要apache公共.他指的是"没有外部图书馆" (49认同)
@Platinum不,根据文档ListUtils.union完全等同于OP的代码.但也许在列表上下文中使用SET操作("Union")会产生误导.我可以看到你如何期望这可以删除重复或类似的东西,但似乎该方法不会这样做. (28认同)
避免使用Apache Commons Collections.它不是类型安全的,没有泛型.如果你使用Java 1.4很好,但对于Java 5及更高版本,我更喜欢Google Guava. (24认同)
@MichaelPiefel最新的Apache Commons Collections 4是类型安全的.使用Java 8方法引用,这种静态实用程序变得非常重要. (9认同)
@Richard是的,但是`Iterables.concat()`怎么样?大多数时候它正是你想要的.如果您绝对需要新列表,请使用`Lists.newArrayList(Iterables.concat(...))`. (3认同)
Kevin K.. 85
您的一个要求是保留原始列表.如果创建新列表并使用addAll()
,则实际上会使列表中对象的引用数增加一倍.如果列表非常大,这可能会导致内存问题.
如果您不需要修改连接结果,则可以使用自定义列表实现来避免这种情况.自定义实现类不止一行,显然......但使用它很简短.
CompositeUnmodifiableList.java:
public class CompositeUnmodifiableListextends AbstractList { private final List list1; private final List list2; public CompositeUnmodifiableList(List list1, List 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(); } }
用法:
ListnewList = new CompositeUnmodifiableList (listOne,listTwo);
这是这个问题的真正答案. (12认同)
这是一个可行的解决方案,但请注意,如果基础列表对象发生更改(list1,list2),则此列表的内容会发生变化.您可能无法修改CompositeUnmodifiableList _itself_的实例,但如果您可以获得对原始列表的引用,则可以.对于那些不熟悉的人:最终修饰符只影响_reference_到列表对象本身不能改变但是列表内容仍然可以改变! (8认同)
@jwj都非常好点,谢谢.类名可能值得一些解释.我认为这个类与`Collections.unmodifiableList()`方法非常相似,它包装了一个列表以使其不可修改.`CompositeUnmodifiableList`做同样的事情,除了它包装两个列表并提供连接的视图.关于`CompositeUnmodifiableList`的所有要点也适用于`Collections.unmodifiableList()`. (3认同)
volley.. 84
可能不简单,但有趣和丑陋:
ListnewList = new ArrayList () { { addAll(listOne); addAll(listTwo); } };
不要在生产代码中使用它...;)
在我的头顶,我可以缩短一行:
ListnewList = new ArrayList (listOne); newList.addAll(listTwo);
在Java 8中:
ListnewList = Stream.concat(listOne.stream(), listTwo.stream()) .collect(Collectors.toList());
您可以使用Apache commons-collections库:
ListnewList = ListUtils.union(list1, list2);
您的一个要求是保留原始列表.如果创建新列表并使用addAll()
,则实际上会使列表中对象的引用数增加一倍.如果列表非常大,这可能会导致内存问题.
如果您不需要修改连接结果,则可以使用自定义列表实现来避免这种情况.自定义实现类不止一行,显然......但使用它很简短.
CompositeUnmodifiableList.java:
public class CompositeUnmodifiableListextends AbstractList { private final List list1; private final List list2; public CompositeUnmodifiableList(List list1, List 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(); } }
用法:
ListnewList = new CompositeUnmodifiableList (listOne,listTwo);
可能不简单,但有趣和丑陋:
ListnewList = new ArrayList () { { addAll(listOne); addAll(listTwo); } };
不要在生产代码中使用它...;)
不简单,但没有调整开销:
ListnewList = new ArrayList<>(listOne.size() + listTwo.size()); newList.addAll(listOne); newList.addAll(listTwo);
另一个Java 8单线程:
ListnewList = Stream.of(listOne, listTwo) .flatMap(x -> x.stream()) .collect(Collectors.toList());
作为奖励,因为Stream.of()
是可变参数,您可以根据需要连接多个列表.
ListnewList = Stream.of(listOne, listTwo, listThree) .flatMap(x -> x.stream()) .collect(Collectors.toList());
发现这个问题寻找连接任意数量的列表,而不是关注外部库.所以,也许它会帮助别人:
com.google.common.collect.Iterables#concat()
如果要将相同的逻辑应用于for()中的多个不同集合,则非常有用.
这是一个使用两行的java 8解决方案:
List
请注意,如果使用此方法,则不应使用此方法
原因newList
尚不清楚,可能已经与其他线程共享
修改的流newList
是并行流,并且访问 newList
不同步或线程安全
由于副作用的考虑.
上述两个条件都不适用于上述加入两个列表的情况,因此这是安全的.
基于这个答案的另一个问题.
建议的解决方案适用于三个列表,但它也可以应用于两个列表.在Java 8中,我们可以使用Stream.of或Stream.concat:
Listresult1 = Stream.concat(Stream.concat(list1.stream(),list2.stream()),list3.stream()).collect(Collectors.toList()); List result2 = Stream.of(list1,list2,list3).flatMap(Collection::stream).collect(Collectors.toList());
Stream.concat
将两个流作为输入并创建一个延迟连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素.由于我们有三个列表,我们使用了这个方法(Stream.concat
)两次.
我们还可以使用一个方法编写一个实用程序类,该方法可以获取任意数量的列表(使用varargs)并返回一个连接列表:
public staticList concatenateLists(List ... collections) { return Arrays.stream(collections).flatMap(Collection::stream).collect(Collectors.toList()); }
然后我们可以使用这个方法:
Listresult3 = Utils.concatenateLists(list1,list2,list3);
这很简单,只有一行,但会将listTwo的内容添加到listOne.你真的需要将内容放在第三个列表中吗?
Collections.addAll(listOne, listTwo.toArray());
稍微简单一些:
ListnewList = new ArrayList (listOne); newList.addAll(listTwo);
稍短一点就是:
ListnewList = new ArrayList (listOne); newList.addAll(listTwo);
您可以创建通用Java 8实用程序方法来连接任意数量的列表.
@SafeVarargs public staticList concat(List ... lists) { return Stream.of(lists).flatMap(List::stream).collect(Collectors.toList()); }
如果目标列表是预先声明的,则可以执行oneliner.
(newList = new ArrayList(list1)).addAll(list2);
在Java 8中(另一种方式):
List> newList = Stream.of(list1, list2).flatMap(List::stream).collect(Collectors.toList());
使用Java8
流的另一个线性解决方案,因为flatMap
已经发布了解决方案,这里是一个没有的解决方案flatMap
Listli = lol.stream().collect(ArrayList::new, List::addAll, List::addAll);
要么
Listints = Stream.of(list1, list2).collect(ArrayList::new, List::addAll, List::addAll);
码
List> lol = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6)); List
li = lol.stream().collect(ArrayList::new, List::addAll, List::addAll); System.out.println(lol); System.out.println(li);
产量
[[1, 2, 3], [4, 5, 6]] [1, 2, 3, 4, 5, 6]
我认为最聪明的是:
/** * @param smallLists * @return one big list containing all elements of the small ones, in the same order. */ public staticList concatenate (final List ... smallLists) { final ArrayList bigList = new ArrayList (); for (final List list: smallLists) { bigList.addAll(list); } return bigList; }
您可以使用静态导入和帮助程序类来完成此操作
注意这个类的generification很可能得到改善
public class Lists { private Lists() { } // can't be instantiated public static Listjoin(List ... lists) { List result = new ArrayList (); for(List list : lists) { result.addAll(list); } return results; } }
然后你可以做的事情
import static Lists.join; Listresult = join(list1, list2, list3, list4);
Java 8版本,支持按对象键加入:
public ListmergeLists(final List left, final List right, String primaryKey) { final Map