繁体   English   中英

如何通过某个比较器对 Java TreeMap 进行排序?

[英]How to make a Java TreeMap be sorted by some comparator?

我有一个 java TreeMap<String, Integer> (我们暂时称它为多重集,因为我正在使用它),我希望它按字符串的长度排序。 我的意思是对于这样的一些代码:

// Imports
import java.util.Comparator;
import java.util.TreeMap;

class CompareLength implements Comparator<String> {
    public int compare(String string, String string_2) {
        return Integer.compare(string.length(), string_2.length());
    }
}

// More lines of code ...
TreeMap<String, Integer> multiset = new TreeMap<>(new CompareLength());
multiset.put("abc", 1);
multiset.put("x", 1);
multiset.put("yz", 1);

for (String string: multiset.keySet()) {
    System.out.print(string + " ");
}

System.out.println(multiset.containsKey("xyz") + " ");

output 是:x yz abc true

我希望它按长度排序,而不是完全改变 TreeMap 的比较器? 我该怎么做,无论比较器是什么,键类型,键,值,值类型,我也希望它能够工作。 等等

正如您所意识到的,传递给TreeMapComparator不仅指定条目的顺序,还指定哪些条目被认为是等效的(即Comparator.compare()返回 0 的条目)。

结论是您根本不应该为任何两个字符串值返回 0,除非它们确实相同。 一个简单的方法是使用这样的比较器:

class CompareLength implements Comparator<String> {
    public int compare(String str1, String str2) {
        int result = Integer.compare(str1.legnth(), str2.length());
        if (result == 0) {
          result = str1.compareTo(str2);
        }
        return result;
    }
}

绍尔的回答是正确的。

这是该代码的一个更简洁的版本。

Comparator器 class 具有使用 lambda 或方法参考创建Comparator器实现的便捷方法。 这里我们两者都用。

我们使用String#length方法。 该方法基于char类型。 自 Java 2 以来, char类型已基本被破坏,自 Java 5 以来遗留下来。作为 16 位值, char在物理上无法表示大多数字符。 因此,如果字符串包含 Unicode 中的BMP之外的任何字符,则String#length将失败,也就是说,大多数字符都会失败。 相反,在处理 Java 中的单个字符时,请使用代码点integer 数字。

我们将 map 声明为更通用的接口NavigableMap而不是具体的 class TreeMap

    NavigableMap < String, Integer > map = 
        new TreeMap<>(
            Comparator
                .comparing( ( String s ) -> s.codePoints().count() )  
                .thenComparing( String :: compareTo ) 
        );

定义一些样本数据。 我们添加了几个条目,而不是您必须显示具有相同字符串长度的多个键。

Map.of方法是一种以文字方式定义不可修改的 map 的简短甜蜜方法。 我们将 map 作为参数传递。

    map.putAll( 
        Map.of (
            "abc", 1 ,
            "x", 2 ,
            "b" , 3 ,
            "a" , 4 ,
            "yz", 5
        )
    ) ;

转储到控制台。

    System.out.println( map ) ;

请参阅在 Ideone.com 上实时运行的代码

{a=4, b=3, x=2, yz=5, abc=1}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM