问题描述
我的目标是使用TreeMap制作按Box.volume属性排序的Box键对象,同时能够按Box.code区分键。在TreeMap中不可能吗?
根据下面的测试1,HashMap放置正常,HashMap保留A,B键对象,但是在测试2中, TreeMap放置不将D视为唯一键,它将替换C的值,请注意,我将TreeMap比较器用作Box.volume,因为我希望键在TreeMap中按卷排序。
import java.util.*;
public class MapExample {
public static void main(String[] args) {
//test 1
Box b1 = new Box("A");
Box b2 = new Box("B");
Map<Box,String> hashMap = new HashMap<>();
hashMap.put(b1,"test1");
hashMap.put(b2,"test2");
hashMap.entrySet().stream().forEach(o-> System.out.println(o.getKey().code+":"+o.getValue()));
//output
A:test1
B:test2
//test 2
Box b3 = new Box("C");
Box b4 = new Box("D");
Map<Box,String> treeMap = new TreeMap<>((a,b)-> Integer.compare(a.volume,b.volume));
treeMap.put(b3,"test3");
treeMap.put(b4,"test4");
treeMap.entrySet().stream().forEach(o-> System.out.println(o.getKey().code+":"+o.getValue()));
//output
C:test4
}
}
class Box {
String code;
int volume;
public Box(String code) {
this.code = code;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Box Box = (Box) o;
return code.equals(Box.code);
}
@Override
public int hashCode() {
return Objects.hash(code);
}
}
谢谢
解决方法
TreeMap
认为比较方法返回0的2个键是相同的,即使它们彼此不相等,因此您当前的TreeMap
不能包含两个具有相同音量的键。 / p>
如果您要保持按音量排序,而在Map
中仍然有多个音量相同的键,请更改Comparator
的比较方法以比较Box
的相等时编码。这样,如果键相等,它将仅返回0。
Map<Box,String> treeMap = new TreeMap<>((a,b)-> a.volume != b.volume ? Integer.compare(a.volume,b.volume) : a.code.compareTo(b.code));
现在的输出是:
C:test3
D:test4
,
b3和b4具有相同的音量,即0(默认值)。
要使其正常工作,请在比较之前为Box的体积变量分配一个值。