使用for (String item: list)
会很好,但是它只会遍历一个列表,并且您需要一个显式的迭代器来处理另一个列表。或者,您可以对这两者使用显式迭代器。
下面是这个问题的一个例子,以及一个使用索引for
循环的解决方案:
import java.util.*;
public class ListsToMap {
static public void main(String[] args) {
List<String> names = Arrays.asList("apple,orange,pear".split(","));
List<String> things = Arrays.asList("123,456,789".split(","));
Map<String,String> map = new LinkedHashMap<String,String>(); // ordered
for (int i=0; i<names.size(); i++) {
map.put(names.get(i), things.get(i)); // is there a clearer way?
}
System.out.println(map);
}
}
输出:
{apple=123, orange=456, pear=789}
有没有更清晰的方法?也许在某个地方的集合API中?
发布于 2009-12-03 20:52:34
由于键-值关系通过列表索引是隐式的,我认为显式使用列表索引的for循环解决方案实际上非常清楚-也很简短。
发布于 2016-07-22 06:03:41
这个问题提出已经有一段时间了,但这些天我偏爱这样的问题:
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));
}
对于那些不熟悉流的人来说,它所做的是获取一个从0到长度的IntStream
,然后对它进行装箱,使它成为一个Stream<Integer>
,这样它就可以被转换为一个对象,然后使用Collectors.toMap
收集它们,其中一个供应商生成关键字,另一个供应商生成值。
这可以经得起一些验证(比如要求keys.size()
小于values.size()
),但作为一个简单的解决方案,它工作得很好。
编辑:上面的方法适用于任何具有固定时间查找的东西,但是如果你想要在相同的顺序上工作(仍然使用相同的模式),你可以这样做:
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
方法的实现。
发布于 2009-12-03 21:09:09
我经常使用下面的成语。我承认它是否更清晰是有争议的。
Iterator<String> i1 = names.iterator();
Iterator<String> i2 = things.iterator();
while (i1.hasNext() && i2.hasNext()) {
map.put(i1.next(), i2.next());
}
if (i1.hasNext() || i2.hasNext()) complainAboutSizes();
它的优点是,它也适用于集合和类似的东西,没有随机访问或没有有效的随机访问,如LinkedList,TreeSets或SQL ResultSets。例如,如果你在LinkedLists上使用原始算法,你会得到一个很慢的Shlemiel the painter algorithm,它实际上需要对长度为n的列表进行n*n次操作。
正如13ren所指出的,当长度不匹配时,如果您试图在一个列表的末尾进行读取,则Iterator.next会抛出NoSuchElementException。所以你会得到更简洁但可能有点令人困惑的变体:
Iterator<String> i1 = names.iterator();
Iterator<String> i2 = things.iterator();
while (i1.hasNext() || i2.hasNext()) map.put(i1.next(), i2.next());
https://stackoverflow.com/questions/1839668
复制相似问题