重量はハッシュコードに影響を与え、HashSetの要素が繰り返し要素を追加する可能性である添加書き換える等しくありません
実験1:等号のハッシュコードをオーバーライドしません
輸入はjava.util.HashSet。 パブリック クラスDemoHashSet { 公共の 静的な 無効メイン(文字列[] args)を{ のHashSet <学生>学生= 新しい HashSetの<> (); 学生S1 = 新しい学生( "张明"、12 ); 学生S2 = 新しい学生( "张杰"、14 ); 学生S3 = 新しい学生( "张杰"、14 ); students.add(S1)。 students.add(S2)。 students.add(S3)。 以下のための{:(学生学生学生) System.out.println(student.getName() + student.getAge()+ "岁" ); } } } インポートjava.util.Objects。 パブリック クラス学生{ プライベート文字列名; プライベート int型の年齢; 公共学生(文字列名、int型の年齢){ この .nameの= 名前; この .age = 年齢; } パブリック文字列のgetName(){ 戻り名。 } 公共 ボイドのsetName(文字列名){ この .nameの=名; } 公共 INT getAge(){ 戻り年齢; } 公共 ボイド setAge(int型の年齢){ この .age = 年齢。 } / * @Override パブリックブール等しい(オブジェクトo){ (これは== O)trueを返す場合。 (!()学生のinstanceof o)の場合はfalseを返します。 学生学生=(学生)O; 戻りgetAge()== student.getAge()&& Objects.equals(のgetName()、student.getName())。 } @Override 公共int型のハッシュコード(){ 戻りObjects.hash(のgetName()、getAge())。 } * / }
結果:
14歳の張傑
チャン12歳の
張傑14年の
終了コードで仕上げプロセス 0
実験2:オーバーライドに等しいとhashCode
輸入はjava.util.HashSet。 パブリック クラスDemoHashSet { 公共の 静的な 無効メイン(文字列[] args)を{ のHashSet <学生>学生= 新しい HashSetの<> (); 学生S1 = 新しい学生( "张明"、12 ); 学生S2 = 新しい学生( "张杰"、14 ); 学生S3 = 新しい学生( "张杰"、14 ); students.add(S1)。 students.add(S2)。 students.add(S3)。 以下のための{:(学生学生学生) System.out.println(student.getName() + student.getAge()+ "岁" ); } } } インポートjava.util.Objects。 パブリック クラス学生{ プライベート文字列名; プライベート int型の年齢; 公共学生(文字列名、int型の年齢){ この .nameの= 名前; この .age = 年齢; } パブリック文字列のgetName(){ 戻り名。 } 公共 ボイドのsetName(文字列名){ この .nameの=名; } 公共 INT getAge(){ 戻り年齢; } 公共 ボイド setAge(int型の年齢){ この .age = 年齢。 } @Override パブリック ブール等しい(オブジェクトo){ 場合(これは == O)戻り 真。 もし(!(O instanceofは)学生)を返す 偽。 学生学生 = (学生)O; 戻る getAge()== student.getAgeを()&& Objects.equals(のgetName()、student.getName())。 } @Override 公共 int型のハッシュコード(){ 戻りObjects.hash(のgetName()、getAge())。 } }
結果:
12歳の張
傑14歳
繰り返し要素は表示されません。
III。分析:
根底にあるのHashMap
アドオン「put-」ハッシュマップ
最終 V putVal(int型のハッシュ、Kキー、V値、ブールonlyIfAbsent、 ブール追い出し){ ノード <K、V> []タブ。ノード<K、V> P。int型nは、I。 もし((タブ=表)== NULL ||(N = tab.length)== 0 ) N =(タブ= リサイズ())の長さ。 もし((P =タブ[I =(N - 1)・ハッシュ])== NULL ) タブ[I] = newNode(ハッシュ、キー、値、NULL ); 他{ ノード <K、V> E。KのK。 もし(p.hash ==ハッシュ&& ((K!= p.key)==キー||(キー= nullの && key.equals(K)))) E = P; 他の 場合(P instanceofのツリーノード) E =((ツリーノード<K、V>)P).putTreeVal(本、タブ、ハッシュ、キー、値)。 他{ ため(INT binCount = 0; ++ binCount){ 場合((E = p.next)== NULL ){ p.next = newNode(ハッシュ、キー、値、ヌル); もし(binCount> = TREEIFY_THRESHOLD - 1)// -1第一のため treeifyBin(タブ、ハッシュ)。 破ります; } 場合(e.hash ==ハッシュ&& ((K = e.key)==キー||(キー=!ヌル && key.equals(K)))) 休憩。 P = E; } } もし、(E!= NULL){ // キーの既存のマッピング V OLDVALUE =e.value; もし(!onlyIfAbsent || OLDVALUE == nullの) e.value = 値; afterNodeAccess(E); 返すOLDVALUEを。 } } ++ modCount。 もし(++サイズ> しきい値) (サイズを変更)。 afterNodeInsertion(追い出し)。 リターン ヌル。 }
要約する前
書き換え前:2を比較値に等しい3番偽のアドレスを書き換えることなく、その結果偽、実行要素を追加することができ、偽==アドレス値の比較は異なります。
ハッシュコードを書き換え、ハッシュ値を比較し、値が確かに異なるアドレス番号2偽で、同じ比較が第3情報のメンバーであり、その結果、真の、実行括弧、添加していない事実です。
ハッシュマップは同じ理由であります
1つの インポートたjava.util.HashMap。 2 インポートはjava.util.HashSet。 3 4 パブリック クラスDemoHashMap { 5 パブリック 静的 ボイドメイン(文字列[]引数){ 6 のHashMap <文字列、整数>学生= 新規 HashMapの<> (); 7 学生S1 = 新しい学生( "张明"、12 ); 8 学生S2 = 新しい学生( "张杰"、14 ); 9 学生S3 = 新しい学生( "张杰"、14 ); 10 students.put( "张明"、12); 11 students.put( "王明"、12 ); 12 students.put( "张明"、12 ); 13 文字列S = students.toString()。 14 15 のSystem.out.println(S);} 16 }
結果:
張= {12、12} =王