4

I'd like to do something like so

SortedMap<Integer, String> stuff = new TreeMap<Integer, String>({1:"a",2:"b"});

much like you would do in python but is that possible in Java, or is the only way to call .put() twice?

Harshal Parekh
  • 5,918
  • 4
  • 21
  • 43
asdf
  • 117
  • 1
  • 8

5 Answers5

8

Starting Java 9, you could do:

SortedMap<Integer, String> stuff = new TreeMap<>(Map.of(1, "a", 2, "b"));

Javadoc links:

TreeMap(Map<? extends K, ? extends V> m)

Map<K, V> of(K k1, V v1, K k2, V v2)

M A
  • 71,713
  • 13
  • 134
  • 174
  • 4
    Ah, I'm on Java 8 so I guess I'll have to do it the old fashioned way – asdf May 14 '20 at 21:06
  • Yeah, that's one of the reasons devs upgrade their Java these days ;) Otherwise, you could use Guava's ImmutableSortedMap: https://guava.dev/releases/snapshot-jre/api/docs/com/google/common/collect/ImmutableSortedMap.html, but therefore need to add a third-party library. – M A May 14 '20 at 21:17
  • Note that if you're wanting a Map that is sorted by *insertion* order (not natural sorting order), then you want a `LinkedHashMap`. And you can't use `Map.of` to construct it (because it doesn't maintain insertion order), so you need to construct it then use `.put` to add each value. – stwr667 Mar 03 '23 at 06:59
2

The following holds true according to the Javadoc of SortedMap from both Java-8 and Java-14. It reads for a SortedMap :

The expected "standard" constructors for all sorted map implementations are:

  1. A void (no arguments) constructor, which creates an empty sorted map sorted according to the natural ordering of its keys.

  2. A constructor with a single argument of type Comparator, which creates an empty sorted map sorted according to the specified comparator.

  3. A constructor with a single argument of type Map, which creates a new map with the same key-value mappings as its argument, sorted according to the keys' natural ordering.

  4. A constructor with a single argument of type SortedMap, which creates a new sorted map with the same key-value mappings and the same ordering as the input sorted map.

and on the basis of (3), you can simply initialize a SortedMap implementation wrapping another Map initialization as a constructor argument. There are a lot of options in this Q&A that match with other suggestions here.

Naman
  • 27,789
  • 26
  • 218
  • 353
1

In Java 8:

Stream.of(new SimpleEntry<>(1, "a"), new SimpleEntry<>(2, "b"))
    .collect(
        Collectors.toMap(
            Entry::getKey, Entry::getValue,
            (a, b) -> { throw new IllegalStateException(); },
            TreeMap::new);

(Yuk).

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

The answer by M Anouti holds good for only up to 10 entries. If you want to do it for more than 10 entries, you need to use Map.ofEntries(Map.entry(k, v), Map.entry(k, v) ...) as shown below:

import static java.util.Map.entry;

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class Main {
    public static void main(String[] args) {
        SortedMap<Integer, String> stuff = new TreeMap<>(
                Map.ofEntries(entry(1, "a"), entry(2, "b"), entry(3, "c"), entry(4, "d"), entry(5, "e"), entry(6, "f"),
                        entry(7, "g"), entry(8, "h"), entry(9, "i"), entry(10, "j"), entry(11, "k"), entry(12, "l")));
        System.out.println(stuff);
    }
}

Output:

{1=a, 2=b, 3=c, 4=d, 5=e, 6=f, 7=g, 8=h, 9=i, 10=j, 11=k, 12=l}
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
-1

There's double brace initializers:

Map stuff = new TreeMap<Integer, String>() {{
    put(1, "a");
    put(2, "b");
}};
System.out.println(stuff);

You can write this in one line if you want.

Although, I do not recommend this. Read here.

Harshal Parekh
  • 5,918
  • 4
  • 21
  • 43
  • 5
    Nobody should be initializing a map like this :) Not worth the readability benefit. – M A May 14 '20 at 21:21
  • @MAnouti, yes. I did mention that. But it provides a way to call put twice. The linked answer is more than enough to explain why this should not be used. – Harshal Parekh May 14 '20 at 21:23
  • 2
    @MAnouti actually, it doesn’t even have a readability benefit. There’s no significant difference to `Map stuff = new TreeMap<>(); stuff.put(1, "a"); stuff.put(2, "b");` and since the double brace construct is creating a subclass, you have to repeat the type parameters in Java 8, which makes the double brace construct even longer… – Holger May 15 '20 at 12:05