javatreemapsortedmap

How to sort TreeMap alphabetically if first char is "+" or "-"


I have map looks like this

key: + something value: something

So it have a big amount of strings starting with + or -, and I need to sort it alphabetically.

For example:

{
  host: hexlet.io,
+ timeout: 20,
+ verbose: true,
- follow: false,
- proxy: 123.234.53.22,
- timeout: 50
}

And it must be sorted to this:

{
- follow: false,
  host: hexlet.io,
- proxy: 123.234.53.22,
- timeout: 50,
+ timeout: 20,
+ verbose: true
}

How can I sort it skipping "+" or "-"?

UPD:

Thx so much! But i missed out that my boileplate must be kinda of this: (it contains 2 whitespace before minus and 1 whitespace after it)

{
  - follow: false
    host: hexlet.io
  - proxy: 123.234.53.22
  - timeout: 50
  + timeout: 20
  + verbose: true
}

So if i make s -> s.substring(2) it doesn`t sort it alphabetically, or if i use 3-4, my "timeout" string crashes, i have "+ timeout: 50" instead of "-timeout: 50" and "+ timeout: 20". How can i fix it?


Solution

  • We can create a TreeMap with a custom Comparator and then use putAll to add all elements from an existing map to the sorted implementation.

    According to the example, custom comparator needs to include two parts:

    1. check if the key starts with " + " and put it to the end, assuming that strings starting with " - " or with empty prefix " " should be treated the same
    2. compare "substring" version of the key when needed without the prefix.

    For example:

    Map<String, Object> data = Map.of(
        "    host", "hexlet.io",
        "  + timeout", 20,
        "  + verbose", true,
        "  - follow", false,
        "  - proxy", "123.234.53.22",
        "  - timeout", 50
    );
    String plusPrefix = "  + ";
    
    Map<String, Object> sorted = new TreeMap<>(
      Comparator.comparing((String str) -> str.startsWith(plusPrefix) ? 1 : -1)
                .thenComparing(str -> str.substring(plusPrefix.length()))
    );
    sorted.putAll(data);
    System.out.println("{");
    sorted.forEach((k, v) -> System.out.println(k + ": " + v));
    System.out.println("}");
    

    Output (sorted in the requested order):

    {
      - follow: false
        host: hexlet.io
      - proxy: 123.234.53.22
      - timeout: 50
      + timeout: 20
      + verbose: true
    }