我有 Java 地图:
Map<Pair<String, String>, MyClass> myMap;
我需要配对不区分大小写。常规字符串键的解决方案很简单:
TreeMap<String, MyClass> myMap= new TreeMap(String.CASE_INSENSITIVE_ORDER);
但是,字符串对键的情况怎么样?
我需要比较
first
(左)值区分大小写,然后比较second
(右)不区分大小写。
Comparator.comparing()
接受一个从类型 T 中提取 Comparable 排序键的函数,并返回一个按该排序键进行比较的 Comparator。
Comparator.thenComparing()
返回字典顺序比较器,其函数提取要与给定比较器进行比较的键。
轻松构建比较器,优先比较
first
,然后如果 second
相等则 first
。
Comparator<Pair> comparator = Comparator.comparing(Pair::first)//compare first case-sensitive
.thenComparing(Pair::second, String.CASE_INSENSITIVE_ORDER);//case-insensitive comparison of second if first are equal
不幸的是,我对你的
Pair
对象一无所知。但是,我确实知道 TreeMap 有一个带有 Comparator
参数的构造函数,因此您可以实现自己的:
class CaseInsensitiveComparator implements Comparator<Pair<String, String>> {
@Override
public int compare(Pair<String, String> o1, Pair<String, String> o2) {
return o1.getKey().compareToIgnoreCase(o2.getKey());
}
}
然后你可以简单地做:
Map<Pair<String, String>, MyClass> myMap = new TreeMap(new CaseInsensitiveComparator())
如果您想使用
TreeMap
,您可以编写自定义 Comparator
,如 Federico klez Culloca 的评论中提到的那样。另请参阅有关如何执行此操作的其他答案。
但是,仅当您确实希望按键对条目进行排序时才应使用 TreeMap
。如果不需要排序,还可以使用
hashCode
和
equals
方法创建自定义键类,并使用
HashMap
:
record CaseInsensitiveStringPair(String first, String second){
@Override
public boolean equals(Object other){
return other instanceof CaseInsensitiveStringPair o &&
first().toLowerCase().equals(o.first().toLowerCase()) &&
second().toLowerCase().equals(o.second().toLowerCase())
}
@Override
public int hashCode(){
return Objects.hash(first().toLowerCase(), second().toLowerCase());
}
}
如果String
可以以小写形式存储,你也可以这样做:
record CaseInsensitiveStringPair(String first, String second){
public CaseInsensitiveStringPair(String first, String second){
this.first=first.toLowerCase();
this.second=second.toLowerCase();
}
}
然后使用
Map<CaseInsensitiveStringPair, MyClass> map = new HashMap<>();