将比较器与 Treemap 一起使用会导致重复键
Using a comparator with Treemap causes duplicate keys
我正在使用树状图,但创建了我自己的比较器,以便树状图按值而不是键排序。这工作正常但是每当我覆盖 映射而不是被覆盖时,会添加一个具有相同键的新映射(这不应该发生,因为 Java 中的映射意味着具有唯一性键)。我什至尝试先删除映射,然后再添加另一个映射,但没有从树图中删除任何内容。当我删除比较器时,没有唯一值并且树状图按预期工作。为什么会这样?
这是我的代码:
public Map<String, List<String>> mapQtToNonSampledCase(List<Entry> cases, Map<String, Integer> populationDistribution) {
Map<String. Integer> distribution = new HashMap<>(populationDistribution);
Map<String. List<String>> qtToCases = new HashMap<>();
Comparator<String> valueComparator = new Comparator<String>() {
public int compare(String k1, String k2) {
int compare = distribution.get(k1).compareTo(distribution.get(k2));
if (compare == 0)
return 1;
else
return compare;
}
};
TreeMap<String, Integer> sortedByValues = new TreeMap<>(valueComparator);
sortedByValues.putAll(distribution);
for(Entry entry: cases) {
List<Map.Entry<String, Integer>> listEntries = sortedByValues.entrySet().stream().collect(Collectors.tolist());
Map.Entry<String, Integer> qt = sortedByValues.firstEntry().getKey().equals(entry.get(UtilsClass.ID).toString()) ? (listEntries.get(1) != null ? listEntries.get(1) : null) : sortedByValues.firstEntry();
if(qt != null) {
if(!qtToCases.containsKey(qt.getKey()) {
qtToCases.put(qt.getKey(), new ArrayList<>());
);
}
qtToCases.get(qt.getKey()).add(entry.get(UtilsClass.ID).toString());
sortedByValues.put(qt.getKey(), qt.getValue() - 1);
}
}
// Printing keys
for(Map.Entry<String, Integer> entry : sortedByValues.entrySet()) {
System.out.println(entry.getKey());
}
}
这是控制台输出(为质量道歉,这是来自另一台设备的图片):
您的自定义比较器 与等号不一致:当您尝试使用不同的值更新键时,您的比较器将 return 一个值 != 0,但是键是一样的。
在 TreeMap API doc 中查看此评论:
Note that the ordering maintained by a tree map, like any sorted map,
and whether or not an explicit comparator is provided, must be
consistent with equals if this sorted map is to correctly implement
the Map interface.
术语 'consistent with equals' 定义如下:[Comparable API doc]:2
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C.
我正在使用树状图,但创建了我自己的比较器,以便树状图按值而不是键排序。这工作正常但是每当我覆盖
这是我的代码:
public Map<String, List<String>> mapQtToNonSampledCase(List<Entry> cases, Map<String, Integer> populationDistribution) {
Map<String. Integer> distribution = new HashMap<>(populationDistribution);
Map<String. List<String>> qtToCases = new HashMap<>();
Comparator<String> valueComparator = new Comparator<String>() {
public int compare(String k1, String k2) {
int compare = distribution.get(k1).compareTo(distribution.get(k2));
if (compare == 0)
return 1;
else
return compare;
}
};
TreeMap<String, Integer> sortedByValues = new TreeMap<>(valueComparator);
sortedByValues.putAll(distribution);
for(Entry entry: cases) {
List<Map.Entry<String, Integer>> listEntries = sortedByValues.entrySet().stream().collect(Collectors.tolist());
Map.Entry<String, Integer> qt = sortedByValues.firstEntry().getKey().equals(entry.get(UtilsClass.ID).toString()) ? (listEntries.get(1) != null ? listEntries.get(1) : null) : sortedByValues.firstEntry();
if(qt != null) {
if(!qtToCases.containsKey(qt.getKey()) {
qtToCases.put(qt.getKey(), new ArrayList<>());
);
}
qtToCases.get(qt.getKey()).add(entry.get(UtilsClass.ID).toString());
sortedByValues.put(qt.getKey(), qt.getValue() - 1);
}
}
// Printing keys
for(Map.Entry<String, Integer> entry : sortedByValues.entrySet()) {
System.out.println(entry.getKey());
}
}
这是控制台输出(为质量道歉,这是来自另一台设备的图片):
您的自定义比较器 与等号不一致:当您尝试使用不同的值更新键时,您的比较器将 return 一个值 != 0,但是键是一样的。
在 TreeMap API doc 中查看此评论:
Note that the ordering maintained by a tree map, like any sorted map, and whether or not an explicit comparator is provided, must be consistent with equals if this sorted map is to correctly implement the Map interface.
术语 'consistent with equals' 定义如下:[Comparable API doc]:2
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C.