Java TreeMap put vs HashMap put,自定义对象作为键
Java TreeMap put vs HashMap put, custom Object as key
我的 objective 是使用 TreeMap 使 Box 键对象按 Box.volume 属性排序,同时能够将键按 Box.code 区分。在 TreeMap 中不可以吗?
根据下面的测试 1,HashMap put 按预期工作,HashMap 保留 A、B 键对象,但在测试 2 中,TreeMap put 不将 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
认为比较方法 returns 0 的 2 个键是相同的,即使它们彼此不相等,所以你当前的 TreeMap
不能包含两个具有相同音量的键。
如果您想保持按数量排序,并且在您的 Map
中仍然有多个具有相同数量的密钥,请更改您的 Comparator
的比较方法以比较 Box
体积相等时的代码。这样,如果键相等,它只会 return 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(int默认值)。
为使其有效,请在比较之前为 Box 体积变量赋值。
我的 objective 是使用 TreeMap 使 Box 键对象按 Box.volume 属性排序,同时能够将键按 Box.code 区分。在 TreeMap 中不可以吗?
根据下面的测试 1,HashMap put 按预期工作,HashMap 保留 A、B 键对象,但在测试 2 中,TreeMap put 不将 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
认为比较方法 returns 0 的 2 个键是相同的,即使它们彼此不相等,所以你当前的 TreeMap
不能包含两个具有相同音量的键。
如果您想保持按数量排序,并且在您的 Map
中仍然有多个具有相同数量的密钥,请更改您的 Comparator
的比较方法以比较 Box
体积相等时的代码。这样,如果键相等,它只会 return 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(int默认值)。
为使其有效,请在比较之前为 Box 体积变量赋值。