Ale HashMap tento kontrakt splňuje. Do Setu vložíte nejprve prázdnou mapu, a
následně jí porovnáváte s mapou s jedním prvkem. V kontraktu není nikde
uvedeno, zda se bude hodnota porovnávat s aktuální hodnotou, nebo s vloženou
hodnotou. Pokud tedy prvky kolekce měníte "za běhu" (což obecně není dobrý
nápad), musíte se podívat, jak se chová konkrétní implementace. A každá
implementace založená na hash bude prvky srovnávat podle hodnoty hashe v
okamžiku vložení (jinak by ten hash neměl žádný význam).
Filip Jirsák
23.5.07, Stöhr Miroslav RNDr. Ph.D. <[EMAIL PROTECTED]>:
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.
>
--
Filip Jirsák
[EMAIL PROTECTED]