A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© 葛奎 中级黑马   /  2012-7-8 16:28  /  1880 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 葛奎 于 2012-7-9 20:30 编辑

Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

3 个回复

倒序浏览
首先:
        == :用于比较基本数据类型的值是否相等,还可以用于比较两个对象是否指向同一个对象。

        equals():是Object类中的方法,一般类在新建时都会重写equals()和hashCode ()方法。
两个简单类型的数值是否相等,可用“==”来比较;
两个对象的值是否相等,则要用对象的equals()方法比较;
两个对象是否指向同一对象(地址),则使用“==”来进行比较;
对于自定义的类,应该根据情况覆盖其父类或Object类中的equals()方法,否则默认的equals()方法功能与“==”相同。

Set集合 : hashSet集合在添加元素时,会自动调用元素类中的hashCode()和equals()方法,会对新添加的元素与集合中元素进行比较,                        
                 如果集合中有则不会添加到集合中,如果没有则添加到结合中。

                 TreeSet集合在添加元素时,会调用元素类中的compareTo()方法或者调用比较器的compare( )方法,如果方法返回的值为0,
                 则不能填加到结合。
回复 使用道具 举报
Set:元素不可以重复,是无序。
Set接口中的方法和Collection一致。
HashSet: 内部数据结构是哈希表 ,是不同步的。
  如何保证该集合的元素唯一性呢?
  是通过对象的hashCode和equals方法来完成对象唯一性的。
  如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
  如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
  如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。
  
  记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
  一般情况下,如果定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。
  建立对象判断是否相同的依据。

TreeSet:可以对Set集合中的元素进行排序。是不同步的。
    判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。
   
    TreeSet对元素进行排序的方式一:
    让元素自身具备比较功能,元就需要实现Comparable接口。覆盖compareTo方法。
   
    如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
    可以使用TreeSet集合第二种排序方式二:
    让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。
    将该类对象作为参数传递给TreeSet集合的构造函数。
   
哈希表确定元素是否相同
1,判断的是两个元素的哈希值是否相同。
   如果相同,在判断两个对象的内容是否相同。
2,判断哈希值相同,其实判断的是对象的hashCode的方法。判断内容相同,用的是equals方法。
  注意:如果哈希值不同,是不需要判断equals。


评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
前面两位总结的挺多了,哥们这就用代码实现以下,

public class Person {
        private String name;
        private int age;
        Person(){}
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
        public int getAge() {
                return age;
        }
        public void setAge(int age) {
                this.age = age;
        }
        public boolean equals(Object obj){//复写equals()方法,来判断对象的名字和年龄是否相同,如果相同,返回true,如果不同,返回false,或者这里如果你的内容不同你就多加几个
                //传入来的对象和他本身相比,如果等于直接返回true
                if(this == obj){
                        return true;
                }
                //传入进来的对象求证是否是这个类的
                if(!(obj instanceof Person)){
                        return false;
                }
                //传入的对象要对其向下转型,因为是obj接受的
                Person p = (Person)obj;
                //判断对象的名字和年龄是否相同,如果相同,返回true,如果不同,返回false
                return (this.name.equals(p.name)&&this.age==p.age);
        }
        public int hashCode(){//复写hashCode()方法来实现对两个实例对象的的判断,判断其是否是同一个,这里我用了加法在让后边的age乘以56,当然,你可以乘以任意数字都可以
                return this.name.hashCode()+(56*this.age);
        }
        public String toString(){//这里是对toString()方法的复写,让其在打印对象的时候自动调用toString而返回名字和年龄
                return name+"******"+age;
        }
}

public class HashSetTest {//这个是我的实现类

        /*
         * HashSet的特点:元素无序,并且没有重复元素.
         * 去除相同的对象,通过复写hashcode,equals,toString来完成
         */
        public static void main(String[] args) {
                HashSet<Person> hs = new HashSet<Person>();
                Person p1 = new Person();
                p1.setName("段哲");
                p1.setAge(20);
                Person p2 = new Person();
                p2.setName("小梦");
                p2.setAge(20);
                Person p3 = new Person();
                p3.setName("小龙龙");
                p3.setAge(22);
                Person p4 = new Person();
                p4.setName("小梦");
                p4.setAge(20);
                Person p5 = new Person();
                p5.setName("冰冰冰");
                p5.setAge(23);
                hs.add(p1);
                hs.add(p2);
                hs.add(p3);
                hs.add(p4);
                hs.add(p5);
                Iterator<Person> it = hs.iterator();
                while(it.hasNext()){
                        Person p = it.next();
                        System.out.println(p);        
                }
        }
}
在这个程序下的运行结果是
冰冰冰******23
小龙龙******22
小梦******20
段哲******20


在这里可以看到,小哲和小梦是年龄相同的,而但是名字不同,在程序里的比较

可能是HashCode()这里的数字相同了,但是后面的名字和年龄的比较却是不同,或者是直接就 HashCode() 这里就没有通过
而里面有两个小梦,同时他们的年龄也相同,那么HashCode()这个方法就会通过,然后调用equals()方法,结果返回值是ture,那么就不进行存储
在这里也有可能HashCode() 值相同就是这种情况了


20+50=70;
50+20=70;
所以就在后边乘以了56,让其数值有更大的变化











评分

参与人数 1技术分 +1 收起 理由
黑马张扬 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马