Zdrojak hovori jasnou reci:
contains u HashSet:
public boolean contains(Object o) {
return map.containsKey(o);
}
a containsKey u HashMap:
public boolean containsKey(Object key) {
Object k = maskNull(key);
int hash = hash(k.hashCode());
int i = indexFor(hash, table.length);
Entry e = table[i];
while (e != null) {
if (e.hash == hash && eq(k, e.key))
return true;
e = e.next;
}
return false;
}
K objektu se pristupuje pres hashCode (jinak to ani nejde, protoze jsou
organizovany pomoci hashe a pak se porovnava,
takze ho to po zmene hashe nenajde).
Jirka
Stöhr Miroslav RNDr. Ph.D. napsal(a):
> Děkuji za objasnění zajímavé vlastnosti těchto objektů, které jsem si
> prozatím nebyl vědom. Jenom mi není jasné následující:
>
> 1/ Set.contains(Object o)
> Returns true if this set contains the specified element. More formally,
> returns true if and only if this set contains an element e such that (o==null
> ? e==null : o.equals(e)).
>
> Tento obecný kontrakt musí splňovat i HashSet, který používáme v příkladě.
>
> 2/ Z toho plyne, že metoda contains() v uvedeném příkladě volá metodu
> Map.equals. U té je uvedeno:
> Compares the specified object with this map for equality. Returns true if the
> given object is also a map and the two Maps represent the same mappings. More
> formally, two maps t1 and t2 represent the same mappings if
> t1.entrySet().equals(t2.entrySet()). This ensures that the equals method
> works properly across different implementations of the Map interface.
>
> Tento obecný kontrakt musí splňovat HashMap, který používáme v příkladě.
>
> Ať čtu jak čtu, to co jste uvedl (že měnit hashcode objektu v mapě nelze) tam
> nevidím. Je pravda, že HashMap.hashCode() se zmení, ale pokud je i nadále
> splněn obecný kontrakt hashCode() (tj. že musí být v souladu s equals(), a to
> je), obecné kontrakty by měly platit jak před změnou, tak po změně.
>
> Mohl bych poprosit o objasnění?
>
> Mirek
>
>
> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Podlesak Kamil
> Sent: Wednesday, May 23, 2007 11:39 AM
> To: Java
> Subject: RE: hashset contains wtf
>
> Zdravim,
>
> To je proste: Map#hashCode() presne definuje ze vysledek musi byt vypocitan
> jako soucet hashcode vsech zaznamu. Pridanim noveho prvku se tedy zmeni
> hodnota hashCode.
>
> Jenomze HashSet (resp. HashMap, kterou interne pouziva) zarazuje i hleda
> zaznamy podle hashCode(). Jakmile se hashCode zmeni, tak hleda jinde a
> nenajde.
>
> Plati obecne pravidlo:
> Objekty vkladane do hash mapy NESMI MENIT svuj hashCode()! Tedy alespon po
> dobu, co jsou v mape.
> Konkretne pak plati:
> Kolekce (Map, Collection) vlozene do hash mapy se NESMI MODIFIKOVAT.
>
> Pokud potrebujete mit v mnozine kolekce ktere bezne modifikujete, pouzijte
> IdentityHashMap.
>
>
>> -----Original Message-----
>> From: [EMAIL PROTECTED]
>> [mailto:[EMAIL PROTECTED] Behalf Of Tomas Zverina
>> Sent: Wednesday, May 23, 2007 11:24 AM
>> To: Java
>> Subject: hashset contains wtf
>>
>>
>> Zdravim,
>>
>> nekdo do me prosim vase kopnete, a vysvetlete mi, proc je vystup
>> nasledujiciho programu:
>>
>> import java.util.*;
>>
>> public class HashSetPokus {
>>
>> public static void main(String[] args) {
>>
>> {
>> // Experiment s HashSet
>> Map element1 = new HashMap();
>> Set<Map> container1 = new HashSet<Map>();
>> container1.add(element1);
>> System.out.println("1a: "+container1.contains(element1));
>> container1.iterator().next().put("a", 123);
>> System.out.println("1b: "+container1.contains(element1));
>> }
>> {
>> // Experiment s ArrayList
>> Map element2 = new HashMap();
>> List<Map> container2 = new ArrayList<Map>();
>> container2.add(element2);
>> System.out.println("2a: "+container2.contains(element2));
>> container2.iterator().next().put("a", 123);
>> System.out.println("2b: "+container2.contains(element2));
>> }
>>
>> }
>>
>> }
>>
>> takovyhle:
>>
>> 1a: true
>> 1b: false
>> 2a: true
>> 2b: true
>>
>> misto ocekavaneho:
>>
>> 1a: true
>> 1b: true
>> 2a: true
>> 2b: true
>>
>> Ja jsem z toho zverina.
>>
>> --
>> S pozdravem,
>>
>> Tomas Zverina
>>
>> Multimedia atelier s.r.o.
>> Na Dolinách 4
>> 147 00 Praha 4
>> IČO: 25127071
>> tel.: 241 433 120
>> e-mail: [EMAIL PROTECTED]
>> http://www.m-atelier.cz/
>>
>> Společnost Multimedia atelier s.r.o. je zapsána u rejstříkového soudu
>> v Praze, oddíl C, vložka 51961.
>>
--
Jiří Mareš (mailto:[EMAIL PROTECTED])
ČSAD SVT Praha, s.r.o. (http://www.svt.cz)
Czech Republic