I have a List of strings which are actually keys and values: "key1", "value1", "key2", "value2", ... (every odd item is a key, every even — value). How can I convert it to Map like this "key1" -> "value1", "key2" -> "value2", ... in a beautiful way?
5 Answers
You can simply do:
Iterator<String> it = list.iterator();
while(it.hasNext()) {
map.put(it.next(), it.next());
}
This will be more efficient than using the get(index) method (in case the list implementation does not allow random access)
2 Comments
"key1", "value1", "key2", i.e. non even length.If your list has random access, like an ArrayList, the straight-forward way is to loop over the elements in the list with a step of 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);
}
Note that this also handles correctly the case where the list doesn't have an even length. It will ignore the last element. For example, if the list is "key1", "value1", "key2", the output will be the map {key1=value1}.
2 Comments
With Eclipse Collections the following should work:
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 is an Eclipse Collections list interface. If you have a JDK list, following should work:
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);
The above uses chunk which generates intermediate lists. The code will succeed with a list with an odd number of elements, but the resulting map will have one entry where the key and value are the same. This code works with both random access and non-random access lists.
The code below may be more efficient for random access lists.
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);
Note: I am a contributor to Eclipse Collections.
Comments
I'm not sure there's a "beautiful" way, but this is the simplest way:
while (!list.isEmpty()) {
map.put(list.remove() ,list.remove());
}