黑马程序员技术交流社区

标题: 关于HashSet中是否重复的理解 [打印本页]

作者: 张 涛    时间: 2012-9-8 14:11
标题: 关于HashSet中是否重复的理解
本帖最后由 张 涛 于 2012-9-9 17:20 编辑
  1. import java.util.HashSet;
  2. import java.util.Iterator;


  3. public class CollectionDemo {

  4.         public static void main(String[] args) {

  5.                 Person p1 = new Person(21);
  6.                 Person p2 = new Person(23);
  7.                 Person p3 = new Person(21);
  8.                
  9.                 //set
  10.                 HashSet<Person> hashSet = new HashSet<Person>();//构造方法
  11.                 hashSet.add(p1);
  12.                 hashSet.add(p2);
  13.                 hashSet.add(p3);
  14.                 System.out.println("hashSet:"+hashSet.size());
  15.                 Iterator<Person> i = hashSet.iterator();
  16.                 while(i.hasNext()){
  17.                         System.out.println(i.next());
  18.                         i.remove();
  19.                 }
  20.                 System.out.println("hashSet:"+hashSet.size());
  21.         }
  22. }

  23. class Person {
  24.         int age;
  25.         Person(int age){
  26.                 this.age = age;
  27.         }
  28.         @Override
  29.         public boolean equals(Object obj) {
  30.                 Person s = (Person)obj;
  31.                 return this.age == s.age;
  32.         }
  33.         @Override
  34.         public String toString() {
  35.                 return "Person age = "+ age;
  36.         }
  37.         
  38. }
复制代码
结果:
hashSet:3
Person age = 21
Person age = 23
Person age = 21
hashSet:0

疑问:我重写了Person的equals方法,那么hashSet判断是否可重复不是依据equals吗?有两个21岁,不是不重复了吗?第二个21岁怎么会添加进去呢?
作者: 王德升    时间: 2012-9-8 14:24
武庆东 发表于 2012-9-8 14:19
稍等一下哈!

你这战术不错!
作者: AngieFans85    时间: 2012-9-8 14:27
本帖最后由 马镱洵 于 2012-9-8 14:57 编辑

凡是使用HashSet,HashMap,HashTable这三个容器,要放入这三个容器的对象所属的类必须要实现hashCode()方法和equals()方法.因为这三个容器是先判断放进来的对象的Hash码,如果Hash码不相同,那么就不会进行equals比较了,而是直接把对象存放进来了.你要知道,如果不重写hashCode()方法,每个对象的Hash码都不一样,所以你的代码中,虽然p1和p3两个对象的age属性都为21,但是p1和p3两个对象的Hash码却不一样,p1和p3当然可以同时放进你的容器中了.
作者: 彭润生    时间: 2012-9-8 14:32
import java.util.HashSet;

import java.util.Iterator;



public class CollectionDemo {


        public static void main(String[] args) {


                Person p1 = new Person(21);

                Person p2 = new Person(23);

                Person p3 = new Person(21);

               
                //set

                HashSet<Person> hashSet = new HashSet<Person>();//构造方法

                hashSet.add(p1);

                hashSet.add(p2);

                hashSet.add(p3);

                System.out.println("hashSet:"+hashSet.size());

                Iterator<Person> i = hashSet.iterator();

                while(i.hasNext()){

                        System.out.println(i.next());

                        i.remove();

                }

                System.out.println("hashSet:"+hashSet.size());

        }

}


class Person {

        int age;

        Person(int age){

                this.age = age;

        }

        @Override

        public boolean equals(Object obj) {

                Person1 s = (Person1)obj;

                return this.age == s.age;

        }
  public int hashCode(){//覆盖了这个,就年龄不能重复了,如果没有,则以对象的hash值来判断,以对象当然是不同的了
     return age*10;
        }


        @Override

        public String toString() {

                return "Person age = "+ age;

        }

        
}
       / /如果覆盖了hashCode方法,那么年龄就不能重复了,HashSet先通过hash值来判断对象是否相同,如果相同后才equals();
作者: 张 涛    时间: 2012-9-8 15:10
扫噶。
原来是hashCode()没有重写,谢谢。
作者: 舒远    时间: 2012-9-8 15:11
因为没有重写hashCode方法,默认添加对象的时候会调用Object的hashCode方法,因为三个对象的内存地址都不同,那么比较hashCode则不同。所以都被添加进HashSet了。
HashSet在添加内容的时候是根据对象的hashCode和equals方法同时为true的时候才能判定重复。
作者: 广驰    时间: 2012-9-8 15:44
hashset判断元素是否相同的第一依据是hashCode是否相同,相同才执行equlas,equlas后还相同就代表元素重复,不同就放在相同hashCode的地址块中,如果hashCode都不同,那就不用调用equlas;
作者: 方志亮    时间: 2012-9-8 19:28
HashSet
                        底层数据结构是哈希表。线程不安全。
                        如果保证元素的唯一性呢?
                        A:首先根据hashCode值判断。
                        B:如果hashCode值不同,那么,这就是不同的元素。直接存储。
                          如果hashCode值相同,那么,会继续根据equals方法进行判断,
                          根据自己的需求来决定元素是否相同。如果相同,就不存储。否则,存储。

                        一般,用HashSet的时候,要重写hashCode和equals方法。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2