Romonov
Romonov

Reputation: 8605

Convert List<String> to Map<String, String> in Java

I want to convert a list to a map where the key is just a counter and it needs to adhere to the order of the list. I currently have this code:

private static Map<String, String> convertListToMap(final List<String> list) {
    AtomicInteger counter = new AtomicInteger(0);
    Map<String, String> map = list.stream().collect(Collectors.toMap((c) -> {
        Integer integer = counter.incrementAndGet();
        return integer.toString();
    }, (c) -> c));

    return map;
}

I have two questions:

  1. In a simple console app test on my desktop, the counter is preserving the order of the list. Can we be sure the order will always be preserved when executed anywhere else?
  2. Is there a better way to code this?

Upvotes: 2

Views: 243

Answers (3)

WJS
WJS

Reputation: 40047

Try it this way.

static Map<String, String> convert(List<String> list) {
    return IntStream.range(0, list.size()).boxed()
            .collect(Collectors.toMap(n -> String.valueOf(n+1), list::get,
                    (a, b) -> a, LinkedHashMap::new));
}

Notes:

  • The Merge function (a, b) -> a is not really contributing to this.
  • The supplier of LinkedHashMap::new ensures order is retained. Unfortunately, there is not a Collector.toMap that permits a Supplier without the merge function.

Upvotes: 5

Ryuzaki L
Ryuzaki L

Reputation: 40078

Probably you can use IntStream to map index as key to value, and use LinkedHashMap for preserving order

    IntStream.range(0, list.size())
             .mapToObj(i -> new AbstractMap.SimpleEntry<>(String.valueOf(i+1), list.get(i)))
             .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> 1, LinkedHashMap::new));

Upvotes: 3

Vincentklw
Vincentklw

Reputation: 61

Regarding your first question: As long as your number will not change, your order would be preserved. A better solution would be a LinkedList (https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html) where entries are ordered by the sequence you add them (It may be easier, I do not know your application).

Regarding your second question: The AtomicInteger mainly advances due to better thread safety (Performance Difference of AtomicInteger vs Integer). If you are not performing any concurrent operations there should be no noticable difference. Therefore one could use a normal Integer.

Upvotes: 0

Related Questions