簡體   English   中英

HashMap對象鍵

[英]HashMap Object key

在Java中,我有一個類:

public static class Key {

    int[] vector = null;

    private int hashcode = 0;

    Key (int[] key) {
        vector = new int[key.length];
        // here is the problem
        System.arraycopy(key, 0, vector, 0, key.length);
    }

    public int hashCode() { ... }

    public boolean equals(Object o) { ... }

}

HashMap<Key, int[]> map用作鍵。 在代碼中,我這樣做:

// value int[] array is filled before
map.put(new Key(new int[] {5, 7}), value);

但這會兩次創建一個參數數組{5, 7} -第一次調用Key構造函數時,然后在該構造函數中。

我不能使用HashMap<int[], int[]> map因為那hashCode不清楚將哪種hashCode用於int[] 因此,我在Key類中包裝了int[]鍵。

如何僅創建一次參數數組(大小可以不同)?

我不喜歡這種解決方案:

map.put(new Key(5, 7), value);

// and rewrite the constructor
Key (int a1, int a2) {
    vector = new int[2];
    vector[0] = a1;
    vector[1] = a2;
}

因為參數數組通常可以具有各種大小。

如何僅創建一次參數數組(大小可以不同)?

不幸的是,您無法做到這一點,因為無法使內置Java數組不可變。 如果可以制作不可變的數組,則可以進行以下操作:

Key (int[] key) {
    // Do not do this!!!
    vector = key;
}

盡管以上內容可以在完全協作的環境中工作,但是敵對的用戶可以傳遞一個數組,讓鍵計算哈希值,然后更改數組元素以將錯誤引入代碼中。 這就是為什么您決定復制傳入的數組時絕對正確的原因。

您可以更改函數以接受可變數量的參數,如下所示:

Key (int ... key) {
    vector = new int[key.length];
    System.arraycopy(key, 0, vector, 0, key.length);
}

這將使您隱式而不是顯式創建數組:

map.put(new Key(5, 7), value);

使用varargs作為參數,並使用Arrays.copyOf()

Key (int... key) {
    vector = Arrays.copyOf(key, key.length);
}

現在,如果int參數(包括無參數)可以調用任意數量的構造函數,並且不會導致錯誤。

由於使用arraycopy進行從一個對象到另一個對象的深層復制,因此有時需要創建兩個對象,其中第二個對象的大小與參數數組的大小相同。 所以vector = new int[key.length]; 看起來很正確。

順便說一句,當我編譯您的代碼時,我得到一個錯誤,指出static不是類的有效修飾符,只有publicabstractfinal是。

暫無
暫無

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

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