Объединение двух коллекций в одну с двумя полями

272
16 августа 2017, 16:58

Как объединить две коллекции Elements actors, roles в одну List<Actors>Actors есть два таких же поля) более элегантно, чем for() с итератором?

PS. Guava упрощает работу в мелочах, но может там есть что-то подходящее...

Answer 1

Ваше пожелание похоже на функцию расширения Zip<> из C#.
Подобного функционала в Java не припомню.
Если другие участники не помогут, можете использовать самостоятельную реализацию, это не так уж и сложно.

Ниже мой примерчик кода.

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));
    }
}
READ ALSO
Как правильно установить LayoutParams?

Как правильно установить LayoutParams?

Я использую в своем проекте эту библиотеку

227
Сборка APK файла из исходников

Сборка APK файла из исходников

Можно ли из исходников Android Studio проекта, собрать APK файл( вне студии ) через терминал(Linux)?

330
Spring: как загрузить таблицу из DB в память?

Spring: как загрузить таблицу из DB в память?

Здравствуйте, у меня есть небольшая таблица, которую я хочу загрузить в память в виде List<Country>, чтобы не дергать БДНо

317
Как выровнять блоки по верхней границе?

Как выровнять блоки по верхней границе?

Блоки с фиксированной высотой с inline-blockКак прижать их к верхней границе контейнера без абсолютного позиционирования?

214