如何在 Java 中为 TreeMap 编写自定义比较器?

ZIN*_*TET 0 java treemap comparator

我想在 TreeMap 中存储键值对,并根据以下逻辑根据 Key 的值对条目进行排序:

按键的长度排序。如果两个键的长度相同,则按字母顺序对它们进行排序。例如,对于以下键值对。

IBARAKI MitoCity
TOCHIGI UtunomiyaCity
GUNMA MaehashiCity
SAITAMA SaitamaCity
CHIBA ChibaCity
TOKYO Sinjyuku
KANAGAWA YokohamaCity
Run Code Online (Sandbox Code Playgroud)

预期的输出是这样的。

CHIBA : ChibaCity
GUNMA : MaehashiCity
TOKYO : Sinjyuku
IBARAKI : MitoCity
SAITAMA : SaitamaCity
TOCHIGI : UtunomiyaCity
KANAGAWA : YokohamaCity
Run Code Online (Sandbox Code Playgroud)

Dar*_*hta 5

您需要为此编写自己comparator的代码并在 中使用它TreeMap,例如:

public class StringComparator implements Comparator<String> {

    @Override
    public int compare(String s1, String s2) {
        return s1.length() == s2.length() ? s1.compareTo(s2) : s1.length() - s2.length();
    }

    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
        Map<String, String> map = new TreeMap<>(new StringComparator());
        map.put("IBARAKI", "MitoCity");
        map.put("TOCHIGI", "UtunomiyaCity");
        map.put("GUNMA", "MaehashiCity");
        map.put("SAITAMA", "SaitamaCity");
        map.put("CHIBA", "ChibaCity");
        map.put("TOKYO", "Sinjyuku");
        map.put("KANAGAWA", "YokohamaCity");

        System.out.println(map);
    }

}
Run Code Online (Sandbox Code Playgroud)

这不处理null值,但如果您null在用例中期望值,则可以添加处理。


Nay*_*aya 5

您可以将 Comparator 作为参数传递给 Map 的构造函数。根据文档,它仅用于密钥:

/**
 * Constructs a new, empty tree map, ordered according to the given
 * comparator.  All keys inserted into the map must be <em>mutually
 * comparable</em> by the given comparator: {@code comparator.compare(k1,
 * k2)} must not throw a {@code ClassCastException} for any keys
 * {@code k1} and {@code k2} in the map.  If the user attempts to put
 * a key into the map that violates this constraint, the {@code put(Object
 * key, Object value)} call will throw a
 * {@code ClassCastException}.
 *
 * @param comparator the comparator that will be used to order this map.
 *        If {@code null}, the {@linkplain Comparable natural
 *        ordering} of the keys will be used.
 */
public TreeMap(Comparator<? super K> comparator) {
    this.comparator = comparator;
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以像这样按密钥的长度传递比较器:

new TreeMap<>(Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()))
Run Code Online (Sandbox Code Playgroud)