学java学到 hashset 有不懂 的地方,求助!

u010444750 2014-05-13 10:39:46
不明白的地方是到底是谁调用了 hashCode() 和 equals(Object obj)

下面是代码

-------------------------------------------------------------------------------------------------------------------------------------------

package com.kk.Collection;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetTest {
public static void main(String[] args) {
Set hashSet=new HashSet();
hashSet.add(new Student(0,"kk"));
hashSet.add(new Student(1,"mm"));
hashSet.add(new Student(1,"mm"));//内存地址和值一样,Set将不会添加同样的对象
Iterator it=hashSet.iterator();
while(it.hasNext()){
Student stu=(Student) it.next();
System.out.println(stu.name);
}
}

static class Student {
int num;

String name;

public Student(int num, String name) {
this.num = num;
this.name = name;
}

@Override
/**
* 判断对象的内存地址是否一样
*/
public int hashCode() {
return num*name.hashCode();
}

@Override
/**
* 判断对象的值是否一样
*/
public boolean equals(Object obj) {
Student stu=(Student) obj;
return this.num==stu.num && this.name.equals(stu.name);
}
}
}
...全文
270 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuebichongkafei 2014-05-15
  • 打赏
  • 举报
回复
不知道API介绍的方法底层大致什么逻辑,就看源码吧!
haorengoodman 2014-05-14
  • 打赏
  • 举报
回复

    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

    public boolean add(E e) {
	return map.put(e, PRESENT)==null;
    }
这是 hashset 代码中的一部分,hashset 底层是用hashmap来存储的,hashset 存储的值 存放到map中的key,value值 就是PRESENT(一个模拟值而已)。这你就该明白了吧,hashMap的 key 是不能,也不会重复的,hashmap的源码是怎么实现 key不能重复的机制,就是 set集合不能重复的实现。
landlord 2014-05-14
  • 打赏
  • 举报
回复
下面是我自己的代码练习和理解,不知道是不是你需要的 =================================================================================== package com.test.example; import java.util.HashSet; class Student /*extends Object*/{ //Object是所有自定义类的父类 //hashCode和equals方法是Object中已定义的方法,所有类都有这两个方法 int Sno; String Sname = null; public Student(int Sno, String Sname){ this.Sno = Sno; this.Sname = Sname; } //hashCode先被调用,如果在集合中有与当前元素一致的hashCode,调用equals进一步比对 //1.需要重写一个方法hashCode(哈希码) public int hashCode(){ System.out.println("生成hashCode"); //添加元素时自动调用hashCode return Sno; } //2.重写equals方法 public boolean equals(Object obj){ Student s = (Student)obj; System.out.println("equals被调用 [" + Sname + "] -- [" + s.Sname + "] "); boolean b = Sno == s.Sno; //boolean b = Sname.equals(s.Sname); return b; //返回true表示一致 } } public class StudentSet { public static void main(String[] args){ /**当使用HashSet存储自定义类时,需要在自定义类中重写equals和hashCode方法, * 主要原因是集合内不允许有重复的数据元素,在集合校验元素的有效性时(数据元素不可重复), * 需要调用equals和hashCode验证。 * */ HashSet<Student> stuSet = new HashSet<Student>(); Student s1 = new Student(1, "Lily"); Student s2 = new Student(2, "Tom"); Student s3 = new Student(3, "Jay"); Student s4 = new Student(3, "Jay"); /*stuSet.add(s1); stuSet.add(s2); stuSet.add(s3); stuSet.add(s4); //System.out.println(stuSet); //因为没有重写toString方法,所以返回Object默认toString,显示的是元素的位置 System.out.println("stuSet的大小是:" + stuSet.size());//重写之前,stuSet的大小是:4 //s3和s4一样,但是stuSet将其视作两个元素 //因为Student是自定义类,Set不能判断自定义类什么时候重复,所以需要重写hashCode方法和equals方法 */ System.out.println("-------------------0-------------------"); stuSet.add(s1); System.out.println("-------------------1-------------------"); stuSet.add(s2); System.out.println("-------------------2-------------------"); stuSet.add(s3); System.out.println("-------------------3-------------------"); stuSet.add(s4); System.out.println("-------------------4-------------------"); System.out.println("stuSet的大小是:" + stuSet.size()); /*结果显示: -------------------0------------------- 生成hashCode -------------------1------------------- 生成hashCode -------------------2------------------- 生成hashCode -------------------3------------------- 生成hashCode equals被调用 [Jay] -- [Jay] -------------------4------------------- stuSet的大小是:3 * */ //当将自定义类的对象存储到set中时,会先自动调用hashCode,如果不一致,直接添加元素(不调用equals方法) //当hashCode一致时,再调用equals进行比较,如果不一致添加元素,如果一致则舍弃 } }
rumlee 2014-05-14
  • 打赏
  • 举报
回复
看看源码就什么都知道了。
鸿洋_ 2014-05-14
  • 打赏
  • 举报
回复
简单点给你说,add的时候调用equals,在你查找的时候调用hashcode,所以hashcode写得好坏会影响查找效率。
S117 2014-05-13
  • 打赏
  • 举报
回复
你去看JDK的源码就知道了!
vnvlyp 2014-05-13
  • 打赏
  • 举报
回复
HashSet在你调用add的时候,就会调用添加的对象的hashCode方法,而equals方法是在你某些操作的时候,比如remove,HashSet来判断到底是哪一个对象所调用的方法

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧