如何在 Java 中连接两个列表?
有没有比以下更简单的方法:
List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);
条件:
- 不要修改原始列表。
- 仅限 JDK。
- 没有外部库。
单行版或 JDK 1.3 版本的奖励积分。
Is there a simpler way than:
List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);
Conditions:
- Do not modify the original lists.
- JDK only.
- No external libraries.
Bonus points for a one-liner or a JDK 1.3 version.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
Java 8 版本支持通过对象键连接:
Java 8 version with support for joining by object key:
使用助手类。
我建议:
Use a Helper class.
I suggest:
我最喜欢的方式是使用 Fluent api 和 Guava:
My favourite way, using fluent api and Guava:
我并不是说这很简单,但你提到了俏皮话的奖金;-)
编辑: ... 13 年后
I'm not claiming that it's simple, but you mentioned bonus for one-liners ;-)
Edit: ... and 13 years later
远不是一句简单的话,但我认为这是最简单的:
No way near one-liner, but I think this is the simplest:
如果您的列表具有不同的类型并且您想将它们组合到另一种类型的列表中,那么这里有一种使用流和 java 8 的方法。
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.
如果您想静态地执行此操作,可以执行以下操作。
这些示例使用 2 个按自然顺序 (==Enum-order)
A, B 的 EnumSet,然后连接到
ALL
列表中。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 anALL
list.在 Java 8 中:
Java 16+:
In Java 8:
Java 16+:
从我的头顶上看,我可以将其缩短一行:
Off the top of my head, I can shorten it by one line:
您可以使用 Apache commons-collections< /a> 库:
You could use the Apache commons-collections library:
另一个 Java 8 单行代码:
作为奖励,由于
Stream.of()
是可变参数,因此您可以连接任意数量的列表。Another Java 8 one-liner:
As a bonus, since
Stream.of()
is variadic, you may concatenate as many lists as you like.您的要求之一是保留原始列表。 如果您创建一个新列表并使用
addAll()
,则实际上会使列表中对象的引用数量增加一倍。 如果您的列表非常大,这可能会导致内存问题。如果您不需要修改串联结果,则可以使用自定义列表实现来避免这种情况。 显然,自定义实现类不止一行......但使用它又短又甜。
CompositeUnmodifyingList.java:
用法:
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:
Usage:
可能并不简单,但有趣且丑陋:
不要在生产代码中使用它......;)
Probably not simpler, but intriguing and ugly:
Don't use it in production code... ;)
并不简单,但无需调整开销:
Not simpler, but without resizing overhead:
发现这个问题希望连接任意数量的列表,而不介意外部库。 因此,也许它会对其他人有所帮助:
如果您想将相同的逻辑应用于一个 for() 中的多个不同集合,则很有用。
Found this question looking to concatenate arbitrary amount of lists, not minding external libraries. So, perhaps it will help someone else:
Useful if you want to apply the same logic to a number of different collections in one for().
建议的解决方案适用于三个列表,但也可以应用于两个列表。 在 Java 8 中,我们可以使用 Stream.of 或 Stream.concat as:
Stream.concat
将两个流作为输入并创建一个延迟连接其元素是第一个流的所有元素,后跟第二个流的所有元素的流。 由于我们有三个列表,因此我们使用了此方法 (Stream.concat
) 两次。我们还可以编写一个实用程序类,其方法采用任意数量的列表(使用 varargs) 并返回一个串联列表:
然后我们可以将此方法用作:
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:
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:
Then we can make use of this method as:
这是一个使用两行的 java 8 解决方案:
则不应使用此方法
newList
的来源未知,并且它可能已经与其他线程共享的流, 对 newList
的访问不是同步的或线程安全的newList 是并行流,出于副作用考虑,
。 上述两个条件不适用于上述连接两个列表的情况,因此这是安全的。
基于另一个问题的此答案。
Here is a java 8 solution using two lines:
Be aware that this method should not be used if
newList
is not known and it may already be shared with other threadsnewList
is a parallel stream and access tonewList
is not synchronized or threadsafedue 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.
这很简单,只有一行,但会将 listTwo 的内容添加到 listOne 中。 您真的需要将内容放在第三个列表中吗?
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?
稍微简单一点:
Slightly simpler:
稍微短一点的是:
A little shorter would be:
您可以创建通用的Java 8实用方法来连接任意数量的列表。
You can create your generic Java 8 utility method to concat any number of lists.
在 Java 8 中(另一种方式):
In Java 8 (the other way):
如果目标列表已预先声明,您可以做一个简短的说明。
You can do a oneliner if the target list is predeclared.
另一种使用 Java8 流的线性解决方案,由于
flatMap
解决方案已经发布,这里是一个没有flatMap
或
代码
输出的解决方案
another one liner solution using
Java8
stream, sinceflatMap
solution is already posted, here is a solution withoutflatMap
or
code
output
我们可以使用 java8 通过 2 种方法连接 2 个列表。
1)使用 concat :
2)使用 flatMap :
We can join 2 lists using java8 with 2 approaches.
1) Using concat :
2) Using flatMap :
我认为最聪明的是:
The smartest in my opinion:
几乎所有答案都建议使用 ArrayList。
更喜欢使用 LinkedList 进行高效的添加操作。
ArrayList add 的分摊时间复杂度为 O(1),但最坏情况为 O(n),因为必须调整数组大小并进行复制。
而 LinkedList add 始终是常数 O(1)。
更多信息https://stackoverflow.com/a/322742/311420
Almost of answers suggest to use an ArrayList.
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
您可以使用静态导入和辅助类
nb来完成该类的泛化可能会得到改进
然后您可以执行以下操作
You could do it with a static import and a helper class
nb the generification of this class could probably be improved
Then you can do things like