Java将键/值字符串列表转换为Map

6

我有一个字符串列表,其中实际上是键和值:"key1", "value1", "key2", "value2", ...(每个奇数项都是键,每个偶数项都是值)。如何以优美的方式将其转换为这样的Map"key1" -> "value1", "key2" -> "value2", ...

5个回答

7

您可以简单地执行以下操作:

Iterator<String> it = list.iterator();
while(it.hasNext()) {
    map.put(it.next(), it.next());
}

如果列表实现不允许随机访问,使用此方法会比使用get(index)方法更有效率。


如果列表是 "key1", "value1", "key2",即长度为奇数,则会抛出异常。 - Tunaki
@Tunaki 是的,拥有良好形式的列表是前提条件。检查可以很容易地添加,但这并不是答案的重点。我认为它不应该被投票否决... - Jean Logeart

7

以下是一个相对简洁的方法:

var map = IntStream.range(0, list.size() / 2).boxed()
    .collect(Collectors.toMap(i -> list.get(i * 2), i -> list.get(i * 2 + 1)));

6
如果您的列表具有随机访问功能,例如ArrayList,直接的方法是以步长为2循环遍历列表中的元素:
public static void main(String[] args) {
    List<String> list = Arrays.asList("key1", "value1", "key2", "value2");

    Map<String, String> map = new HashMap<>();
    for (int i = 0; i < list.size() - 1; i += 2) {
        map.put(list.get(i), list.get(i + 1));
    }

    System.out.println(map);
}

请注意,这个方法也能很好地处理列表长度不是偶数的情况。它会忽略最后一个元素。例如,如果列表是 "key1", "value1", "key2",输出将是一个包含 {key1=value1} 的映射。


我在想,你认为使用Java8流是否可能? - Yassin Hajaj
1
@YassinHajaj sprinter已经回答了 :) https://dev59.com/YZXfa4cB1Zd3GeqPbjUy#36087498 - Tunaki

4

使用Eclipse Collections,以下内容应该可以工作:

MutableList<String> list = 
    Lists.mutable.of("key1", "value1", "key2", "value2", "key3", "value3");
Map<String, String> map = 
    list.asLazy().chunk(2).toMap(Iterate::getFirst, Iterate::getLast);

Verify.assertMapsEqual(
    Maps.mutable.of("key1", "value1", "key2", "value2", "key3", "value3"), map);

MutableList 是 Eclipse Collections 的列表接口。如果您有一个 JDK 列表,以下应该可以工作:

List<String> list = 
    Arrays.asList("key1", "value1", "key2", "value2", "key3", "value3");
Map<String, String> map =
    ListAdapter.adapt(list).asLazy().chunk(2).toMap(Iterate::getFirst, Iterate::getLast);

Verify.assertMapsEqual(
    Maps.mutable.of("key1", "value1", "key2", "value2", "key3", "value3"), map);

上述代码使用了chunk,它生成中间列表。该代码可以成功处理具有奇数个元素的列表,但是生成的映射将具有一个键和值相同的条目。此代码适用于随机访问和非随机访问列表。
下面的代码可能更适用于随机访问列表。
MutableList<String> list = 
    Lists.mutable.of("key1", "value1", "key2", "value2", "key3", "value3");
MutableMap<String, String> map = Maps.mutable.empty();
IntInterval.oneToBy(list.size(), 2).each(i -> map.put(list.get(i - 1), list.get(i)));

Verify.assertMapsEqual(
    Maps.mutable.of("key1", "value1", "key2", "value2", "key3", "value3"), map);

注意:我是Eclipse Collections的贡献者。

1

我不确定是否有“美观”的方法,但这是最简单的方法:

while (!list.isEmpty()) {
    map.put(list.remove() ,list.remove());
}

1
我认为你需要使用 .remove(0) 方法,同时我也会检查 list.size()%2 == 0。 - agilob
1
这是有风险的,因为它会改变列表,可能会抛出异常。 - Tunaki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接