1. import java.util.HashSet;
  2. class Dog{
  3. String color;
  4. public Dog(String s){
  5. color = s;
  6. }
  7. }
  8. public class SetAndHashCode {
  9. public static void main(String[] args) {
  10. HashSet<Dog> dogSet = new HashSet<Dog>();
  11. dogSet.add( new Dog( "white" ));
  12. dogSet.add( new Dog( "white" ));
  13. System.out.println( "We have " + dogSet.size() + " white dogs!" );
  14. if (dogSet.contains( new Dog( "white" ))){
  15. System.out.println( "We have a white dog!" );
  16. } else {
  17. System.out.println( "No white dog!" );
  18. }
  19. }
  20. }
上述代码的输出为: Set的contains(Object o) 方法详解 Java的API文档指出: 当且仅当 本set包含一个元素 e,并且满足(o==null ? e==null : o.equals(e))条件时,contains()方法才返回true. 因此 contains()方法 必定使用equals方法来检查是否相等. 需要注意的是: set 中是可以包含 null值的(常见的集合类都可以包含null值). 所以如果添加了null,然后判断是否包含null,将会返回true,代码如下所示:
  1. HashSet<Dog> a = new HashSet<Dog>();
  2. a.add( null );
  3. if (a.contains( null )){
  4. System.out.println( "true" );
  5. }
Java的根类Object定义了  public boolean equals(Object obj) 方法.因此所有的对象,包括数组(array,[]),都实现了此方法。 在自定义类里,如果没有明确地重写(override)此方法,那么就会使用Object类的默认实现.即只有两个对象(引用)指向同一块内存地址(即同一个实际对象, x==y为true)时,才会返回true。 如果把Dog类修改为如下代码,能实现我们的目标吗?
  1. class Dog{
  2. String color;
  3. public Dog(String s){
  4. color = s;
  5. }
  6. //重写equals方法, 最佳实践就是如下这种判断顺序:
  7. public boolean equals(Object obj) {
  8. if (!(obj instanceof Dog))
  9. return false ;
  10. if (obj == this )
  11. return true ;
  12. return this .color == ((Dog) obj).color;
  13. }
  14. }
英文答案是: no. 问题的关键在于 Java中hashCode与equals方法的紧密联系 . hashCode() 是Object类定义的另一个基础方法. equals()与hashCode()方法之间的设计实现原则为: 如果两个对象相等(使用equals()方法),那么必须拥有相同的哈希码(使用hashCode()方法). 即使两个对象有相同的哈希值(hash code),他们不一定相等.意思就是: 多个不同的对象,可以返回同一个hash值. hashCode()的默认实现是为不同的对象返回不同的整数.有一个设计原则是,hashCode对于同一个对象,不管内部怎么改变,应该都返回相同的整数值. 在上面的例子中,因为未定义自己的hashCode()实现,因此默认实现对两个对象返回两个不同的整数,这种情况破坏了约定原则。
  1. class Dog{
  2. String color;
  3. public Dog(String s){
  4. color = s;
  5. }
  6. //重写equals方法, 最佳实践就是如下这种判断顺序:
  7. public boolean equals(Object obj) {
  8. if (!(obj instanceof Dog))
  9. return false ;
  10. if (obj == this )
  11. return true ;
  12. return this .color == ((Dog) obj).color;
  13. }
  14. public int hashCode(){
  15. return color.length(); //简单原则
  16. }
  17. }
但是上面的hashCode实现,要求Dog的color是不变的.否则会出现如下的这种困惑:
  1. import java.util.HashSet;
  2. import java.util.Set;
  3. public class TestContains {
  4. public static final class Person{
  5. private String name = "" ;
  6. public Person(String n) {
  7. setName(n);
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this .name = (name== null )? "" : name;
  14. }
  15. @Override
  16. public int hashCode() {
  17. // 请考虑是否值得这么做,因为此时name是会变的.
  18. return name.length();
  19. // 推荐让name不可改变
  20. }
  21. @Override
  22. public boolean equals(Object obj) {
  23. if (!(obj instanceof Person)){
  24. return false ;
  25. }
  26. if (obj == this ){
  27. return true ;
  28. }
  29. return this .name.equals(((Person)obj).name);
  30. }
  31. };
  32. public static void main(String[] args) {
  33. Set<Person> persons = new HashSet<Person>();
  34. //
  35. Person person = new Person( "tiemao" );
  36. persons.add(person);
  37. // 修改name, 则依赖hash的集合可能失去作用
  38. person.setName( "ren" );
  39. // 同一个对象,居然是false,原因是我们重写了hashCode,打破了hashCode不变的基本约定
  40. boolean has = persons.contains(person);
  41. int size = persons.size();
  42. System.out.println( "has=" +has); // has=false.
  43. System.out.println( "size=" +size); // size=1
  44. }
  45. }
新手对Set中contains()方法的疑惑[java] view plain copyimport java.util.HashSet;     class Dog{      String color;         public Dog(String s){          color = s;      }   test_ set .add('b'); console.log(test_ set );// Set (2){"a", "b"} console.log(test_ set .has('a'));//true console.log(test_ set .has('c'));//fal.
list. contains (o) :遍历集合所有元素,用每个元素和传入的元素进行 equals 比较,如果集合元素有 n 个,则会比较 n 次,所以时间复杂度为 O(n) 。 方法 源码如下: // ArrayList 方法 public boolean contains (Object o) { return indexOf(o) >= 0; public int indexOf(Object o) { if (o == null) { for .
关了再重新开一下。 您好,我修改模板的时候提示 contains aninvalidpa? 打开360安全卫士-软件管家,搜索“c ”和“.net”然后点击一键安装,可以尝试多版本安装,如果遇到不能安装的话,系统会有对应的提示。 java conta...
s=“pwwkew” public static void lengthOfLongestSubstring(String s) { char[] ss=s.toCharArray(); Set <String> set =new Hash Set <>(); for(char c:ss){ if( set . contains (c)){ System...
本文主要对两者共有的 方法 contains ()做一个简单的讨论,主要是性能上的对比,并用JMH(ava Microbenchmark Harness)进行测试比较。 2 先看JMH测试结果 我们使用一个由O... 然后,创建一个Node的 Set 集合,并add一个Node对象nd1,同时new一个xy值与nd1相同的nd2: Node nd1 = new Node(1,2); Node nd2 = new Node(1,2); Set <Node> st=new Hash Set <>