How to Zip Two Java Lists

Java streams zip two lists

You could do so using :

public static void getNamesOfAdultsSortedByAge(Stream<Person> stream) {
List<String> sorted = stream.filter(p -> p.getAge() >= 18)
.sorted((x, y) -> Integer.compare(x.getAge(),y.getAge()))
.map(e -> e.getFirstName() + " " + e.getLastName())
.collect(Collectors.toList());
System.out.println(sorted);
}

Here we just map the sorted stream by concatenating the first name and then the last name, after which we use the .collect() terminal operation to collect it to a list.

Google Guava zip two lists

As of Guava 21, this is possible via Streams.zip():

List<Person> persons = Streams.zip(names.stream(), ages.stream(), Person::new)
.collect(Collectors.toList());

zip method in java

I found solution with IntStream

List<String> names1 = new ArrayList<>(Arrays.asList("John", "Charles", "Mike", "Dennis"));
List<String> names2 = new ArrayList<>(Arrays.asList("Jenny", "Christy", "Monica"));
IntStream
.range(0, Math.min(names1.size(), names2.size()))
.mapToObj(i -> names1.get(i) + ":" + names2.get(i))
.toList();

But better looks solution with JOOL library

Seq
.of("John","Charles", "Mike")
.zip(Seq.of("Jenny", "Christy", "Monica"));

Using Streams.zip method to use two streams simultaneously for LocalDate objects

You can use Stream.allMatch with a one to one comparison of your list elements:

static boolean validate(List<LocalDate> endDates, List<LocalDate> startDates) {
return IntStream.range(0, endDates.size())
.allMatch(i -> endDates.get(i).isAfter(startDates.get(i)));
}

This of course assumes that both lists are of the same length (if endDates is shorter than startDates, you have a bug; if startDates is shorter, an exception will be thrown on startDates.get(i))

Zip two lists into an immutable multimap in Java 8 with Guava?

I think your procedural code is the most optimal solution already (both in terms of memory and speed, assuming random access lists). With small corrections, so that your code compiles, it would be:

ImmutableListMultimap.Builder<Key, Value> builder = ImmutableListMultimap.builder();
for (int i = 0; i < Math.min(keys.size(), values.size()); i++) {
builder.put(keys.get(i), values.get(i));
}
return builder.build();

If you really want to use streams in order to "be functional", zipping two streams is the way to go, but you'd still have to create intermediate "pair" objects before collecting to multimap. You claim that "there isn't a publicly constructable list entry", but it's not true, there are JDK's SimpleImmutableEntry and Guava's Maps.immutableEntry you can use here (and they fit better than more generic Pair, which, in fact, cannot be found in both JDK or Guava.

Using Streams#zip requires passing streams, so the final code would look like this:

Streams.zip(keys.stream(), values.stream(), SimpleImmutableEntry::new)
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));

If you're open to using other "functional" Java libraries which allow more stream-related operations, you could use jOOL and its Seq.zip, which accept iterable parameters:

    Seq.zip(keys, values, SimpleImmutableEntry::new)
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));

Another library would be StreamEx, which exposes EntryStream - an abstraction for key-value pair streams.

JAVA process two stream into one single map

Guava Streams.zip for streams without random access

If Guava is available at runtime, then the following can help:

        List<String> keys = Arrays.asList("One", "Two");
List<Integer> values = Arrays.asList(1, 2);
Map<String, Integer> zipped = Streams.zip(keys.stream(), values.stream(), SimpleEntry::new)
.collect(Collectors.toMap(Collectors.toMap(Entry::getKey, Entry::getValue)));
System.out.println(zipped);


Related Topics



Leave a reply



Submit