2013-11-26 29 views
5

neden olduğu TreeSet için add() yöntem ve HashSet devlet için Oracle Java API belgeleri: sette hiçbir e2 varsaKuralları

bir element e sadece eklenir nerede (e==null ? e2==null : e.equals(e2))

HashSet eşitliği belirlemek için hashCode() kullanırken

Ancak TreeSet, compareTo() kullanır. Her ikisi de equals() değerini göz ardı eder. Belgelerin yanlış olduğu konusunda endişelerim var mı, yoksa kongre anlayışım mı yoksa hatalı olan algoritma mı?

cevap

2

TreeSet belgelerinin yanlış olduğu konusunda haklısınız.

equals() kullanımında olduğu gibi HashSet hakkında yanlışsınız. hashCode(), yalnızca hızlı arama için eşitlik testi için değil değildir.

+0

hashCode() her zaman aynı kodu döndürecek şekilde ayarlanırsa, add() davranışı eşittir() değerine bağlı olarak görünür. Fakat eğer equals() öğesinin her zaman 'true' değerini döndürdüğü ve hashCode() öğesini geçersiz kılmadığı bir nesne oluşturursam, farklı nesneler için farklı olur - sonra add() öğesi birden çok nesne ekler. Bu nedenle, add() 'in davranışı, dokümanlar içinde belirtilenden daha karmaşık görünüyor. Louis'in dediği gibi, bu durumlar sözleşmenin dışında, ancak uygulama ile ilgileniyordum (söylediği şeyi yapmadığı gibi) - herkes kanonik bir şartname olup olmadığını biliyor mu? – user3038094

+0

@ user3038094 - HashMap'in nasıl çalıştığını okumayı öneriyorum. o zaman "equals()" yönteminin neden her zaman çağrılmadığını anlayacaksınız. ne olursa olsun, genel anlamda, HashSet _does_ eşitlik testi için 'equals() işlevini kullanır. – jtahlborn

+0

Teşekkürler jtahlborn - Tavsiyeni takip ettim ve ne demek istediğini görüyorum. Eğer hashCode() farklıysa, algoritma eşittir() ile uğraşmaktan rahatsız olmaz, eğer hashCode() aynı ise sadece eşittir() kullanır. Muhtemelen bunun nedeni, hashCode() 'nin, eşittir()' den daha hızlı değerlendirileceği varsayılıyor ya da hashCode() 'ın değerlendirilmesinin gerekeceği gerçeği mi? Yani dokümanlarda söylemek daha iyi olurdu: e == null? e2 == null: e.hashCode() == e2.hashCode()? e.hashCode() == e2.hashCode(): e.equals (e2) == 0 – user3038094

1

TreeSet onun doc bu anlatıyor: doğru ayarlayın arabirimini uygulamak ise (açık karşılaştırıcı sağlanır olsun veya olmasın) kümesi tarafından tutulan sipariş eşittir ile tutarlı olmalıdır

Not söyledi. (Eşitlerle tutarlı bir kesin tanım için Karşılaştırılabilir veya Karşılaştırıcı'ya bakın.) Bunun nedeni, Set arabiriminin eşitleme işlemi açısından tanımlanmasıdır, ancak TreeSet örneği, compareTo (veya karşılaştırması) yöntemini kullanarak tüm öğe karşılaştırmaları gerçekleştirir; Bu yöntemle eşit kabul edilen öğeler, kümenin bakış açısından eşittir. Bir kümenin davranışı, siparişi eşitlikle uyuşmasa bile iyi tanımlanmıştır; Set arayüzünün genel sözleşmesine uymuyor.

HashSet için, Set nesnelerin doğru uygulanan dokümanın örtülü bir beklenti; hashCode() doğru uygulanmadıysa, HashSet spesifikasyonlarını ihlal etmiyor ancak nesneye geçiriliyor.

+0

"Bir kümenin davranışı, siparişi eşittir ile tutarlı olsa bile iyi tanımlanmış." Ancak davranış, belgelerde tanımlandığı gibi değil, merak ettiğim şey bu. Neden bu belgelere özel (kesin) değil? Söylemek daha iyi olurdu: e == null? e2 == null: e.compareTo (e2) == 0) – user3038094