简体   繁体   English

Java TreeMap put vs HashMap put,自定义 Object 作为键

[英]Java TreeMap put vs HashMap put, custom Object as key

My objective was to use the TreeMap to make Box key objects sorted by Box.volume attribute while able to put keys distinct by the Box.code.我的目标是使用 TreeMap 使 Box 键对象按 Box.volume 属性排序,同时能够将键按 Box.code 区分。 Is it not possible in TreeMap?在 TreeMap 中不可能吗?

As per below test 1, HashMap put works as expected, HashMap keeps both A, B key objects, but in test 2, TreeMap put doesn't treat D as a distinct key , it replaces C's value, note that i used the TreeMap comparator as Box.volume, because i want keys to be sorted by volume in 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);
    }
}

Thank you谢谢

TreeMap considers 2 keys for which the comparison method returns 0 to be identical, even if they are not equal to each other, so your current TreeMap cannot contain two keys with the same volume. TreeMap将比较方法返回 0 的 2 个键视为相同,即使它们彼此不相等,因此您当前的TreeMap不能包含具有相同体积的两个键。

If you want to keep the ordering by volume and still have multiple keys with the same volume in your Map , change your Comparator 's comparison method to compare the Box 's codes when the volumes are equal.如果您想保持按体积排序并且在Map中仍然有多个具有相同体积的键,请更改Comparator的比较方法以在体积相等时比较Box的代码。 This way it will only return 0 if the keys are equal.这样,如果键相等,它只会返回 0。

Map<Box, String> treeMap = new TreeMap<>((a,b)-> a.volume != b.volume ? Integer.compare(a.volume, b.volume) : a.code.compareTo(b.code));

Now the output is:现在 output 是:

C:test3
D:test4

b3 and b4 has the same volume, that is 0 (int default value). b3 和 b4 具有相同的音量,即 0(int 默认值)。

For it work, assign a value to the Box volume variables before comparing.对于它的工作,在比较之前为 Box 体积变量分配一个值。

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

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