如何压缩两个 Java 列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31963297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to zip two Java Lists
提问by ahad bahmanian
I have 2 Lists:
我有 2 个列表:
List<String> subjectArr = Arrays.asList<String>("aa", "bb", "cc");
List<Long> numArr = Arrays.asList<Long>(2L, 6L, 4L);
How do I create new List
and zip two Lists into it?
如何创建新List
列表并将两个列表压缩到其中?
List<?> subjectNumArr = zip(subjectArr, numArr);
// subjectNumArr == [{'aa',2},{'bb',6},{'cc',4}]
回答by vefthym
Use an ArrayList of Map.Entry<String, Long>
, checking that both arraylists have equal size (as it seems to be your requirement), like that:
使用 ArrayList Map.Entry<String, Long>
,检查两个数组列表是否具有相同的大小(因为这似乎是您的要求),如下所示:
List<Map.Entry<String,Long>> subjectNumArr = new ArrayList<>(numArr.size());
if (subjectArr.size() == numArr.size()) {
for (int i = 0; i < subjectArr.size(); ++i) {
subjectNumArr.add(new AbstractMap.SimpleEntry<String, Long>(subjectArr.get(i), numArr.get(i));
}
}
That's all the code you need!
这就是您需要的所有代码!
Then, to iterate over the results, use something like:
然后,要迭代结果,请使用以下内容:
for (Map.Entry<String, Long> entry : subjectNumArr) {
String key = entry.getKey();
Long value = entry.getValue();
}
or, you can simply get the pair at position i (keeping insertion order), by:
或者,您可以通过以下方式简单地在位置 i(保持插入顺序)处获取该对:
Map.Entry<String, Long> entry = subjectNumArr.get(i);
This can also hold duplicate entries, unlike the Map solution that I initially suggested, without requiring to define your own (Pair) class.
这也可以保存重复的条目,这与我最初建议的 Map 解决方案不同,不需要定义您自己的 (Pair) 类。
回答by Ankit
I agree with vefthym however if you have to do using list then create a class like below -:
我同意 vefthym 但是如果你必须使用 list 然后创建一个如下所示的类:
class DirtyCoding{
String subject;
int numbr;
}
Then iterate over the your list, create object of DirtyCoding
, populate it and add then add it to List<DirtyCoding>
.
然后遍历您的列表,创建 的对象DirtyCoding
,填充它并添加然后将其添加到List<DirtyCoding>
.
回答by kandarp
In Java 8:You can do this in one line using Stream and Collectors class.
在 Java 8 中:您可以使用 Stream 和 Collectors 类在一行中完成此操作。
In Java 7/6/5:
在 Java 7/6/5 中:
List list = new ArrayList();
if(subjectArr.size() == numArr.size())
{
for (int i = 0; i < subjectArr.size(); i++) { // Loop through every subject/name
list.add(subjectArr.get(i) + " " + numArr.get(i)); // Concat the two, and add it
}
}
回答by Kumar Abhinav
You should create an ArrayList of List:
您应该创建一个列表的 ArrayList:
ArrayList<List> subjectNumArr = new ArrayList<>();
Iterator iter = subjectArr.iterator();
int count=0;
while(iter.hasNext()){
subjectNumArr.add(Arrays.asList(iter.next(),numArr.get[count++]);
}
回答by slartidan
My ideas:
我的想法:
- Define a classfor your pairs. This makes your code extendable(i.e. if you want to add a third field).
- Define your Lists with the convinient method
Arrays.asList
. It is easy to understand, shortand automatically generates generic collections. - Use superclasses or interfaces as variable types. I used
List
in the example, maybeCollection
would be even better. Only declare variables asArrayList
if you need the list to be so specific. That will give you the possibility to use other implementations, without having to change much code.
- 为您的配对定义一个类。这使您的代码可扩展(即,如果您想添加第三个字段)。
- 使用方便的方法定义您的列表
Arrays.asList
。它易于理解、简短并自动生成泛型集合。 - 使用超类或接口作为变量类型。我
List
在例子中使用,也许Collection
会更好。只声明变量,就ArrayList
好像您需要列表如此具体一样。这将使您有可能使用其他实现,而无需更改太多代码。
I would create Pair
objects like this:
我会创建这样的Pair
对象:
import java.util.*;
class Pair {
String subject;
Long num;
}
public class Snippet {
public static void main(String[] args) {
List<String> subjectArr = Arrays.asList("aa", "bb", "cc");
List<Long> numArr = Arrays.asList(2l,6l,4l);
// create result list
List<Pair> pairs = new ArrayList<>();
// determine result size
int length = Math.min(subjectArr.size(), numArr.size());
// create pairs
for (int position = 0; position < length; position++) {
Pair pair = new Pair();
pair.subject = subjectArr.get(position);
pair.num = numArr.get(position);
pairs.add(pair);
}
}
}
回答by ZhekaKozlov
The operation you want is called zipping.
您想要的操作称为zipping。
First you need a data structure which holds two objects. Let's call it Pair
:
首先,您需要一个包含两个对象的数据结构。让我们称之为Pair
:
public final class Pair<A, B> {
private final A left;
private final B right;
public Pair(A left, B right) {
this.left = left;
this.right = right;
}
public A left() { return left; }
public B right() { return right; }
public String toString() {
return "{" + left + "," + right + "}";
}
}
Then you need to implement a method zip
:
然后你需要实现一个方法zip
:
public static <A, B> List<Pair<A, B>> zip(List<A> as, List<B> bs) {
Iterator<A> it1 = as.iterator();
Iterator<B> it2 = bs.iterator();
List<Pair<A, B>> result = new ArrayList<>();
while (it1.hasNext() && it2.hasNext()) {
result.add(new Pair<A, B>(it1.next(), it2.next()));
}
return result;
}
And finally the usage of zip
:
最后的用法zip
:
zip(subjectArr, numArr);
回答by Tagir Valeev
Here's Java-8 solution using the Pair
class (like in @ZhekaKozlov answer):
这是使用Pair
该类的 Java-8 解决方案(如@ZhekaKozlov 的回答):
public static <A, B> List<Pair<A, B>> zipJava8(List<A> as, List<B> bs) {
return IntStream.range(0, Math.min(as.size(), bs.size()))
.mapToObj(i -> new Pair<>(as.get(i), bs.get(i)))
.collect(Collectors.toList());
}
回答by tkruse
Use one of the answers from Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)to zip and apply a function at the same time
使用Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)中的答案之一 同时压缩和应用函数
e.g. Using a zipped Stream:
例如使用压缩流:
<A,B,C> Stream<C> zipped(List<A> lista, List<B> listb, BiFunction<A,B,C> zipper){
int shortestLength = Math.min(lista.size(),listb.size());
return IntStream.range(0,shortestLength).mapToObject( i -> {
return zipper.apply(lista.get(i), listb.get(i));
});
}
for which you may also use Guava's Streams.zip()
你也可以使用 Guava 的 Streams.zip()
回答by tkruse
As per related question, you can use Guava (>= 21.0) to do this:
根据相关问题,您可以使用 Guava (>= 21.0) 来执行此操作:
List<String> subjectArr = Arrays.asList("aa", "bb", "cc");
List<Long> numArr = Arrays.asList(2L, 6L, 4L);
List<Pair> pairs = Streams.zip(subjectArr.stream(), numArr.stream(), Pair::new)
.collect(Collectors.toList());
Note that the guava method is annotated as @Beta
, though what that means in practice is up to interpretation, the method has not changed since version 21.0.
请注意,guava 方法被注释为@Beta
,尽管这在实践中意味着什么取决于解释,但该方法自 21.0 版以来没有改变。
回答by Solomon Ucko
To get an Iterator<C>
from an Iterator<A>
, an Iterator<B>
, and a BiFunction<A, B, C>
:
要从Iterator<C>
an Iterator<A>
、 anIterator<B>
和 a获取 an BiFunction<A, B, C>
:
public static <A, B, C> Iterator<C> map(Iterator<A> a, Iterator<B> b, BiFunction<A, B, C> f) {
return new Iterator<C>() {
public boolean hasNext() {
return a.hasNext() && b.hasNext(); // This uses the shorter of the two `Iterator`s.
}
public C next() {
return f.apply(a.next(), b.next());
}
};
}