[英]How to zip two Java Lists
我有 2 個列表:
List<String> subjectArr = Arrays.asList<String>("aa", "bb", "cc");
List<Long> numArr = Arrays.asList<Long>(2L, 6L, 4L);
如何創建新的List
和 zip 兩個 List 進去呢?
List<?> subjectNumArr = zip(subjectArr, numArr);
// subjectNumArr == [{'aa',2},{'bb',6},{'cc',4}]
這是使用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());
}
在 Java 9 之后,您可以使用Map.entry()
:
public static <A, B> List<Map.Entry<A, B>> zipJava8(List<A> as, List<B> bs) {
return IntStream.range(0, Math.min(as.size(), bs.size()))
.mapToObj(i -> Map.entry<>(as.get(i), bs.get(i)))
.collect(Collectors.toList());
}
根據相關問題,您可以使用 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());
請注意,番石榴方法被注釋為@Beta
,盡管這在實踐中意味着什么取決於解釋,但該方法自版本 21.0 以來沒有改變。
使用Map.Entry<String, Long>
的 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));
}
}
這就是您需要的所有代碼!
然后,要迭代結果,請使用以下內容:
for (Map.Entry<String, Long> entry : subjectNumArr) {
String key = entry.getKey();
Long value = entry.getValue();
}
或者,您可以通過以下方式簡單地在位置 i(保持插入順序)處獲取該對:
Map.Entry<String, Long> entry = subjectNumArr.get(i);
這也可以保存重復的條目,這與我最初建議的 Map 解決方案不同,不需要定義您自己的 (Pair) 類。
您想要的操作稱為zipping 。
您需要實現一個方法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<Map.Entry<A, B>> result = new ArrayList<>();
while (it1.hasNext() && it2.hasNext()) {
result.add(Map.entry(it1.next(), it2.next()));
}
return result;
}
你像這樣使用它:
zip(subjectArr, numArr);
要從Iterator<A>
、 Iterator<B>
和BiFunction<A, B, C>
獲取Iterator<C>
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());
}
};
}
我同意 vefthym 但是如果你必須使用 list 然后創建一個如下所示的類:
class DirtyCoding{
String subject;
int numbr;
}
然后遍歷您的列表,創建DirtyCoding
對象,填充它並添加然后將其添加到List<DirtyCoding>
。
我的想法:
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<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);
}
}
}
使用Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)中的答案之一同時壓縮和應用函數
例如使用壓縮流:
<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));
});
}
你也可以使用 Guava 的 Streams.zip()
您應該創建一個列表的 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++]);
}
在 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
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.