如何压缩两个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 } }