Using Google Guava (Google Commons), is there a way to merge two equally sized lists into one list, with the new list containing composite objects of the two input lists?
Example:
public class Person {
public final String name;
public final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "(" + name + ", " + age + ")";
}
}
and
List<String> names = Lists.newArrayList("Alice", "Bob", "Charles");
List<Integer> ages = Lists.newArrayList(42, 27, 31);
List<Person> persons =
transform with a function that converts (String, Integer) to Person
System.out.println(persons);
Would output:
[(Alice, 42), (Bob, 27), (Charles, 31)]
As of Guava 21, this is possible via Streams.zip()
:
List<Person> persons = Streams.zip(names.stream(), ages.stream(), Person::new)
.collect(Collectors.toList());
Looks like this is not currently in Guava, but is a desired feature. See this github issue, in particular Iterators.zip()
.
Just pretend this is a Guava method:
for (int i = 0; i < names.size(); i++) {
persons.add(new Person(names.get(i), ages.get(i)));
}
You can refer to underscore-java library.
Underscore-java
is a port of Underscore.js
for Java, and the zip
method can achieve the goal.
Following is a sample code & output :
$.zip(Arrays.asList("moe", "larry", "curly"), Arrays.asList("30", "40", "50"));
=> [[moe, 30], [larry, 40], [curly, 50]]
Here's a generic way to zip lists with vanilla Java. Lacking tuples, I opted to use a list of map entries (If you don't like to use map entries, introduce an additional class ZipEntry
or something).
public static <T1,T2> List<Map.Entry<T1,T2>> zip(List<T1> zipLeft, List<T2> zipRight) {
List<Map.Entry<T1,T2>> zipped = new ArrayList<>();
for (int i = 0; i < zipLeft.size(); i++) {
zipped.add(new AbstractMap.SimpleEntry<>(zipLeft.get(i), zipRight.get(i)));
}
return zipped;
}
To support arrays as well:
@SuppressWarnings("unchecked")
public static <T1,T2> Map.Entry<T1,T2>[] zip(T1[] zipLeft, T2[] zipRight) {
return zip(asList(zipLeft), asList(zipRight)).toArray(new Map.Entry[] {});
}
To make it more robust add precondition checks on list sizes etc, or introduce left join / right join semantics similar to SQL queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With