Прошло некоторое время с тех пор, как этот вопрос был задан, но в эти дни я неравнодушен к чему-то вроде:
public static <K, V> Map<K, V> zipToMap(List<K> keys, List<V> values) {
return IntStream.range(0, keys.size()).boxed()
.collect(Collectors.toMap(keys::get, values::get));
}
Для тех, кто не знаком с потоками, он получает IntStream
от 0 до длины, затем упаковывает его, превращая его в Stream<Integer>
, чтобы его можно было преобразовать в объект, а затем собирает их, используя Collectors.toMap
который принимает двух поставщиков, один из которых генерирует ключи, другой - значения.
Это может выдержать некоторую проверку (например, требование, чтобы keys.size()
было меньше, чем values.size()
), но прекрасно работает как простое решение.
EDIT:
Вышеприведенное прекрасно работает для всего, что связано с поиском в постоянном времени, но если вы хотите что-то, что будет работать в том же порядке (и при этом использовать такой же шаблон), вы можете сделать что-то вроде:
public static <K, V> Map<K, V> zipToMap(List<K> keys, List<V> values) {
Iterator<K> keyIter = keys.iterator();
Iterator<V> valIter = values.iterator();
return IntStream.range(0, keys.size()).boxed()
.collect(Collectors.toMap(_i -> keyIter.next(), _i -> valIter.next()));
}
Вывод такой же (опять же, пропуски проверок длины и т. Д.), Но сложность по времени не зависит от реализации метода get
для любого используемого списка.