How to combine two Elements actors, roles into one List<Actors> ( Actors has two of the same fields) more elegantly than for () with an iterator?

Ps. Guava makes it easy to work in the details, but maybe there is something suitable there ...

  • Show the code. And now the essence of the question is not clear. - Mikhail Vaysman
  • It's not entirely clear how you want to connect. Each with one or one to one. If the latter, is the sequence important? It sounds like "I have a set of hands and people, how can I connect them?" - Victor

1 answer 1

Your wish is similar to the Zip <> extension function from C #.
I do not recall a similar functionality in Java.
If other participants do not help, you can use a standalone implementation, it is not so difficult.

Below is my sample code.

 import java.util.*; import java.util.function.*; import java.util.stream.*; import static java.util.stream.Collectors.toList; public class Example { public static class MyUtils { public static <I,J,R> List<R> ZipLists(List<I> list_1, List<J> list_2, BiFunction<? super I, ? super J, R> merge) { return IntStream.range(0, Math.min(list_1.size(), list_2.size())) .mapToObj(i -> merge.apply(list_1.get(i), list_2.get(i))) .collect(toList()); } public static <I,J,R> Collection<R> ZipCollections(Collection<I> collection_1, Collection<J> collection_2, BiFunction<? super I, ? super J, R> merge) { Iterator<I> iterator_1 = collection_1.iterator(); Iterator<J> iterator_2 = collection_2.iterator(); return IntStream.range(0, Math.min(collection_1.size(), collection_2.size())) .mapToObj(i -> merge.apply(iterator_1.next(), iterator_2.next())) .collect(toList()); } private static class ZippedIterator<I,J,R> implements Spliterator<R> { Iterator<I> iterator_1; Iterator<J> iterator_2; BiFunction<? super I, ? super J, R> merge; ZippedIterator(Stream<I> stream_1, Stream<J> stream_2, BiFunction<? super I, ? super J, R> merge) { this.iterator_1 = stream_1.iterator(); this.iterator_2 = stream_2.iterator(); this.merge = merge; } @Override public int characteristics() { return Spliterator.IMMUTABLE; } @Override public long estimateSize() { return Long.MAX_VALUE; } @Override public boolean tryAdvance(Consumer<? super R> action) { if ( iterator_1.hasNext() && iterator_2.hasNext() ) { action.accept(merge.apply(iterator_1.next(), iterator_2.next())); return true; } else return false; } @Override public Spliterator<R> trySplit() { return null; } } public static <I,J,R> Stream<R> ZipStreams(Stream<I> stream_1, Stream<J> stream_2, BiFunction<? super I, ? super J, R> merge) { return StreamSupport.stream(new ZippedIterator<>(stream_1, stream_2, merge), false); } } public static class Actor { public int actors; public long roles; Actor(int actors, long roles) { this.actors = actors; this.roles = roles; } } public static void main(String[] args) { List<Integer> actors = Arrays.asList(0, 1, 2, 3); List<Long> roles = Arrays.asList(5L, 6L, 7L, 8L, 9L); /* List<Actor> results = IntStream.range(0, Math.min(actors.size(), roles.size())) .mapToObj(i -> new Actor(actors.get(i), roles.get(i))) .collect(toList()); */ //List<Actor> results = MyUtils.ZipLists(actors, roles, Actor::new); Stream<Actor> results = MyUtils.ZipStreams(actors.stream(), roles.stream(), Actor::new); results.forEach(item -> System.out.format("actors = %d, roles = %d\n", item.actors, item.roles)); } }