如何压缩两个Java列表

我有2个列表:

List subjectArr = Arrays.asList("aa", "bb", "cc"); List numArr = Arrays.asList(2L, 6L, 4L); 

如何创建新List并将两个列表压缩到其中?

 List subjectNumArr = zip(subjectArr, numArr); // subjectNumArr == [{'aa',2},{'bb',6},{'cc',4}] 

这是使用Pair类的Java-8解决方案(如@ZhekaKozlov答案):

 public static  List> zipJava8(List as, List bs) { return IntStream.range(0, Math.min(as.size(), bs.size())) .mapToObj(i -> new Pair<>(as.get(i), bs.get(i))) .collect(Collectors.toList()); } 

使用Map.Entry的ArrayList,检查两个arraylists是否具有相同的大小(因为它似乎是你的要求),如下所示:

 List> subjectNumArr = new ArrayList<>(numArr.size()); if (subjectArr.size() == numArr.size()) { for (int i = 0; i < subjectArr.size(); ++i) { subjectNumArr.add(new AbstractMap.SimpleEntry(subjectArr.get(i), numArr.get(i)); } } 

这就是你需要的所有代码!

然后,迭代结果,使用类似于:

 for (Map.Entry entry : subjectNumArr) { String key = entry.getKey(); Long value = entry.getValue(); } 

或者,您可以通过以下方式简单地获得位置i(保持插入顺序)的对:

 Map.Entry entry = subjectNumArr.get(i); 

与我最初建议的Map解决方案不同,这也可以保留重复条目,而无需定义自己的(Pair)类。

根据相关问题 ,您可以使用Guava(> = 21.0)来执行此操作:

 List subjectArr = Arrays.asList("aa", "bb", "cc"); List numArr = Arrays.asList(2L, 6L, 4L); List pairs = Streams.zip(subjectArr.stream(), numArr.stream(), Pair::new) .collect(Collectors.toList()); 

您想要的操作称为压缩 。

首先,您需要一个包含两个对象的数据结构。 我们称之为Pair

 public final class Pair { 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 + "}"; } } 

然后你需要实现一个方法zip

 public static  List> zip(List as, List bs) { Iterator it1 = as.iterator(); Iterator it2 = bs.iterator(); List> result = new ArrayList<>(); while (it1.hasNext() && it2.hasNext()) { result.add(new Pair(it1.next(), it2.next())); } return result; } 

最后使用zip

 zip(subjectArr, numArr); 

我同意vefthym但是如果你必须使用list然后创建一个类如下 – :

 class DirtyCoding{ String subject; int numbr; } 

然后遍历列表,创建DirtyCoding对象,填充它并添加然后将其添加到List

使用带有lambda(java.util.stream.Streams.zip)的JDK8的Zipping流中的一个答案来压缩并同时应用一个函数

例如,使用压缩流:

  Stream zipped(List lista, List listb, BiFunction 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)); }); } 

您也可以使用Guava的Streams.zip()

你应该创建一个列表的ArrayList: –

 ArrayList subjectNumArr = new ArrayList<>(); Iterator iter = subjectArr.iterator(); int count=0; while(iter.hasNext()){ subjectNumArr.add(Arrays.asList(iter.next(),numArr.get[count++]); } 

我的想法:

  • 为你的对定义一个类 。 这使您的代码可扩展 (即,如果您要添加第三个字段)。
  • Arrays.asList方法Arrays.asList定义列表。 它易于理解简短并自动生成通用集合。
  • 使用超类或接口作为变量类型 。 我在示例中使用了List ,也许Collection会更好。 如果您需要将列表设置为特定的,则仅将变量声明为ArrayList 。 这将使您可以使用其他实现,而无需更改太多代码。

我会像这样创建Pair对象:

 import java.util.*; class Pair { String subject; Long num; } public class Snippet { public static void main(String[] args) { List subjectArr = Arrays.asList("aa", "bb", "cc"); List numArr = Arrays.asList(2l,6l,4l); // create result list List 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); } } } 

在Java 8中:您可以使用Stream和Collectors类在一行中完成此操作。

在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 } }