2011-11-01 22 views
0

我有一個類屬性其中有2個變量說int a,b;如何使類在Java中的不同HashMap中可用

我想在兩個不同的HashSet中使用class Attribute。

第一個散列集合a的值相同時認爲對象相等。 但是當b的值相同時,第二散列集合認爲對象相等。

我知道,如果我覆蓋等於方法HashSet中會用平等的覆蓋版本來比較兩個對象,但在這種情況下,我需要平等的)兩種不同的實現(

的一種方式創建兩個子類的屬性,併爲他們提供不同的等號方法,但我想知道是否有更好的方法來做到這一點,使我不必創建屬性的子類。

謝謝。

+0

您的問題類型沒有意義。如果'a'是相同的,你的對象是相同的,但不是。那麼如果'b'是相同的物體是相同的,但它們也不是。請製作兩節課,因爲它們是不同目的的不同課程。 – Andre

+0

@Andre我認爲這樣做確實有道理......平等語義可以被認爲是一個類固有的,但是之後也可以進行比較。但是,您可以在某些集合方法中提供自定義比較器。只允許在一個類中定義一個單一的等式定義標準可能是「純粹」的方法,但我認爲給開發者自由和靈活性比堅持非常嚴格的概念更重要。仔細想想...爲什麼Ruby和Scala獲得了牽引力,而Java一直面臨着很多批評? –

+0

自定義比較器的構建和實現與您所描述的完全不同的目的。如果兩個對象的equals()方法返回true,則無論從哪個上下文調用方法,它們都是相同的。 – Andre

回答

1

我做了一些事情不同,,而不是使用HashSet的,我使用的HashMap,我已經使用INT一個作爲第一個HashMap中的關鍵字和對象存儲爲值。 而在另一個HashMap我一直把鑰匙保存爲int b和對象作爲值。

這爲我提供了一種散列兩個變量一個b所以我沒有做任何的子類。

而且,我得到O(1)時間而不是O(log n)。但我知道我通過使用更多內存來付出代價,但是我主要關心的是時間,所以我選擇了TreeSet上的HashMap。

謝謝大家的意見和建議。

1

不幸的是,沒有可以覆蓋equals邏輯的「均衡器」類。有這樣的排序方式,您可以使用基於Comparable實現的自然排序,或者提供自己的Comparator。我真的很想知道爲什麼沒有這種平等檢查的事情。

由於平等的語義是由一個類定義的,可以被認爲是該類的一個特徵,所以這兩個子類方法似乎是最自然的。也許有人知道以更簡單的方式做這件事的有用模式,但我從來沒有遇到過。

編輯:只是想的東西......你可以使用兩個Map情況下,像HashMap,使用a關鍵和第二使用b爲重點的第一位。它會讓你檢測到碰撞。然後您可以簡單地將該屬性鏈接到關聯的實例。

3

一種可能的解決方案是不使用HashSet,而是使用TreeSet代替。它與Set界面相同,但是有一個TreeSet構造函數,可讓您傳入Comparator。這樣,你可以離開Attribute類unchanged-剛剛創建兩個不同的比較,並使用它像

Set<Attribute> setA = new TreeSet<Attribute>(comparatorForA); 
Set<Attribute> setB = new TreeSet<Attribute>(comparatorForB); 

比較採取平等檢查的護理(例如,如果compare返回0,對象相等)

+0

雖然這只是對訂購有影響。它仍然不會允許根據「equals」相等的條目。 –

+0

你失去了使用哈希算法的速度,但它會工作。 –

+0

@G_H - 當兩個字段相等時,比較器返回0,這意味着對象本身應該被視爲相等。例如,如果'a'是一個'int',你有'int比較(Object x,Object y){return x.a - y.a; }' –

0

HashMapHashSet修改爲接受散列和平等測試策略將非常容易。

public interface Hasher { 
    int hashCode(Object o); 
} 

public interface Equalizer { 
    int areEqual(Object o1, Object o2); 
} 
0

一個簡單的解決方案是繞過HashSet並直接使用HashMap。對於第一個,使用其a屬性作爲關鍵字來存儲每個Attribute,並且對於其他使用b

0

我可以提出一點哈克但較小的努力解決方案:) 當存儲在第二個哈希集中時交換a和b的值,以便唯一性由b的值定義,然後在從哈希集讀取類時交換該值a和b再次保持原來的狀態。所以相同的equals/hascode方法將用於此目的。

相關問題