Google Guava "zip" два списка

Используя Google Guava (Google Commons), есть ли способ объединить два одинаковых размера списка в один список, с новым списком, содержащим составные объекты из двух входных списков?

Пример:

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 + ")";
    }
}

и

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);

Вывести:

[(Alice, 42), (Bob, 27), (Charles, 31)]

Ответы

Ответ 1

Похоже, что этого нет в Guava, но это желаемая функция. См. этот вопрос github, в частности Iterators.zip().

Ответ 2

Как и в случае с Guava 21, это возможно через Streams.zip():

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

Ответ 3

Просто притворись, что это метод Гува:

for (int i = 0; i < names.size(); i++) {
    persons.add(new Person(names.get(i), ages.get(i)));
}

Ответ 4

Здесь версия без явной итерации, но она становится довольно уродливой.

List<Person> persons = ImmutableList.copyOf(Iterables.transform(
    ContiguousSet.create(Range.closedOpen(0, names.size()),
        DiscreteDomain.integers()),
    new Function<Integer, Person>() {
      @Override
      public Person(Integer index) {
        return new Person(names.get(index), ages.get(index));
      }
    }));

Это действительно не намного лучше, чем наличие явной итерации, и вы, вероятно, хотите, чтобы какой-то уровень проверки границ гарантировал, что два входа действительно имеют одинаковый размер.

Ответ 5

Вы можете обратиться к библиотеке underscore-java.

Underscore-java - это порт Underscore.js для Java, а метод zip может достичь цели.

Ниже приведен пример кода и вывод:

$.zip(Arrays.asList("moe", "larry", "curly"), Arrays.asList("30", "40", "50"));

= > [[moe, 30], [larry, 40], [curly, 50]]