2016-03-18 2 views
3

У меня есть строки List, которые на самом деле являются ключами и значениями: "key1", "value1", "key2", "value2", ... (каждый нечетный элемент - это ключ, каждый четный - значение). Как я могу преобразовать его в Map вот так "key1" -> "value1", "key2" -> "value2", ... красивым способом?Преобразование Java Перечень строк ключа/значения на карту

ответ

1

Я не уверен, что есть «красивый» способ, но это самый простой способ:

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

Я думаю, что вам нужно: .remove (0), я также проверил бы, если list.size()% 2 == 0 – agilob

+1

Это опасно, потому что он мутирует список, который может вызвать исключение. – Tunaki

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}.

+0

Мне было интересно, как вы думаете, можно ли использовать потоки Java8? –

+1

@ YassinHajaj sprinter ответил одним из них: http://stackoverflow.com/a/36087498/1743880 – Tunaki

1

Вот относительно аккуратный способ в Java 8:

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

Почему у этого нет больше болей? :) –

5

Вы можете просто сделать:

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

Это будет более эффективным, чем при использовании метода get(index) (в случае, если реализация списка не разрешить произвольный доступ)

+0

Мне это нравится, спасибо! – coquin

+0

Это генерирует исключение, если в списке есть «key1», «value1», «key2» ', т. Е. Равномерная длина. – Tunaki

+0

@ Тунаки. Да, наличие списка хорошо сформировано является обязательным условием. Проверки можно легко добавить, но на самом деле это не точка ответа. Я не думаю, что он заслуживает нисходящего движения, хотя ... –

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. Если у вас есть список 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.

Смежные вопросы