簡體   English   中英

TreeMap 在小數點后放置帶尾隨零的 BigDecimal 鍵無效

[英]TreeMap putting BigDecimal key with trailing zero after decimal has no effect

將值放入 Map 的鍵中而不是將值添加到鍵中

public static void putKey() {
    TreeMap<BigDecimal,String> trmap = new TreeMap<BigDecimal,String>();
    MathContext mc = new MathContext(2);
    BigDecimal b1 = new BigDecimal(3.1,mc);
    BigDecimal b2 = new BigDecimal(3.10,mc);
    BigDecimal b3 = new BigDecimal(3.2,mc);
    BigDecimal b4 = new BigDecimal(3.3,mc);
    BigDecimal b5 = new BigDecimal(3.4,mc);
    
    trmap.put(b1, "3.1");
    trmap.put(b2, "3.10");
    trmap.put(b3, "3.2");
    trmap.put(b4, "3.3");
    trmap.put(b5, "3.4");
    
    System.out.println(trmap);
}

在上面的地圖中,3.10 中沒有添加密鑰。

所以我嘗試計算這兩個值的哈希碼

public static void putKey() {
    TreeMap<BigDecimal, String> trmap = new TreeMap<BigDecimal, String>();
    MathContext mc = new MathContext(2);
    BigDecimal b1 = new BigDecimal(3.1, mc);
    BigDecimal b2 = new BigDecimal(3.10, mc);
    BigDecimal b3 = new BigDecimal(3.2, mc);
    BigDecimal b4 = new BigDecimal(3.3, mc);
    BigDecimal b5 = new BigDecimal(3.4, mc);

    trmap.put(b1, "3.1");
    trmap.put(b2, "3.10");
    trmap.put(b3, "3.2");
    trmap.put(b4, "3.3");
    trmap.put(b5, "3.4");

    System.out.println(trmap);
    int hashcodeb1 = b1.hashCode();
    int hashcodeb2 = b2.hashCode();

    System.out.println("3.1-->" + hashcodeb1);
    System.out.println("3.10-->" + hashcodeb2);
}

兩個哈希碼都在計算相同的值我的要求是我想將兩個值都放在我的地圖中,因此在其他論壇帖子的幫助下看起來我必須重寫hashCode()方法但它返回 int 作為值並且我我不確定這對我的情況是否有幫助。

我在課堂上寫了hashCode()

public class BigDecimalMap {
    public BigDecimalMap() {
        super();
    }

    public static void main(String[] args) {
        BigDecimalMap bigDecimalMap = new BigDecimalMap();
        putKey();
        }
    
        public static void putKey() {
            TreeMap<BigDecimal, String> trmap = new TreeMap<BigDecimal, String>();
            MathContext mc = new MathContext(2);
            BigDecimal b1 = new BigDecimal(3.1, mc);
            BigDecimal b2 = new BigDecimal(3.10, mc);
            BigDecimal b3 = new BigDecimal(3.2, mc);
            BigDecimal b4 = new BigDecimal(3.3, mc);
            BigDecimal b5 = new BigDecimal(3.4, mc);
    
            trmap.put(b1, "3.1");
            trmap.put(b2, "3.10");
            trmap.put(b3, "3.2");
            trmap.put(b4, "3.3");
            trmap.put(b5, "3.4");
    
            System.out.println(trmap);
            int hashcodeb1 = b1.hashCode();
            int hashcodeb2 = b2.hashCode();
    
            System.out.println("3.1-->" + hashcodeb1);
            System.out.println("3.10-->" + hashcodeb2);
        }
        
        public int hashCode() {
            return 1;
        }
    }

請幫助確定如何添加這兩個值。

參考TreeMap的Javadoc

請注意,如果此排序映射要正確實現 Map 接口,則樹映射維護的順序與任何排序映射一樣,無論是否提供顯式比較器,都必須與 equals 一致。

由於BigDecimalcompareToequals不一致(compareTo 可能返回 0 但 equals 返回 false)。 使用HashMap而不是考慮hashCodeequals作為鍵。

參考BigDecimal#equals方法的 Javadoc

比較此 BigDecimal 與指定的 Object 是否相等。 與 compareTo 不同,此方法僅在兩個 BigDecimal 對象的值和比例相等時才認為它們相等(因此,通過此方法進行比較時,2.0 不等於 2.00)。

當我們執行下面的代碼

MathContext mc = new MathContext(2);
BigDecimal b1 = new BigDecimal(3.1, mc);
BigDecimal b2 = new BigDecimal(3.10, mc);
System.out.println(b1.doubleValue());
System.out.println(b2.doubleValue());
System.out.println(b1.scale());
System.out.println(b2.scale());
System.out.println(b1.compareTo(b2));
System.out.println(b1.equals(b2));
System.out.println(b1.hashCode());
System.out.println(b2.hashCode());

由於 b1 和 b2 具有相同的值和比例,因此它們被認為是相同的對象。

然后我們用下面的代碼比較不同比例的 b1 和 b2。 為了創建具有不同比例的 BigDeciaml,請使用帶有 String 而不是 double 的構造函數(請參閱注釋https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#BigDecimal(double ) )。

BigDecimal b1 = new BigDecimal("3.1");
BigDecimal b2 = new BigDecimal("3.10");
System.out.println(b1.doubleValue());
System.out.println(b2.doubleValue());
System.out.println(b1.scale());
System.out.println(b2.scale());
System.out.println(b1.compareTo(b2));
System.out.println(b1.equals(b2));
System.out.println(b1.hashCode());
System.out.println(b2.hashCode());

Treemap被實現為紅黑樹; 一個關心compareTo是如何實現的,因為它必須將您的條目移動到leftright

所以TreeMap只關心你的鍵如何實現compareTo方法。 現在,如果您查看這段代碼:

    BigDecimal b1 = new BigDecimal("3.1");
    BigDecimal b2 = new BigDecimal("3.10");

    System.out.println(b1.compareTo(b2)); // this prints zero since
                        // they are the same according to compareTo

    TreeMap<BigDecimal, String> map = new TreeMap<>();
    map.put(b1, "aaa");
    map.put(b2, "bbb");

    System.out.println(map); // {3.1=bbb}

請注意,最后,在兩次插入之后,TreeMap 中只有一個條目。 發生這種情況是因為b1b2相同(根據compareTo ),因此在第二次插入后該值在地圖中被替換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM