解决方案 »
- try-finally问题 求高手解答
- 静态成员变量初始化的疑惑
- 关于解析网络xml的中文问题
- class的文件不小心改了 请问怎么改回来了!怎么改回来
- 请教高人一个图片问题!
- 对Jswing有兴趣,却碰到了难题,请大虾么帮忙解决,多谢!
- 如何用jbuilder发布应用程序!!!!!!!!!!!
- 用Field类怎样才能取得一个final静态属性的值。
- IOException类里面的 fillInStackTrace,getStackTrace,printStackTrace(光这个就三种),setStackTrace分别都能实现什么功能?(我真的查
- 山里野人冥思苦想一个礼拜不得其解,请各位高手指点。
- 单引号不用转义符也可以输出,为什么还要加呢?
- java UUID 怎么构造
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集合不能重复的实现。
===================================================================================
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进行比较,如果不一致添加元素,如果一致则舍弃
}
}