JAVA中,当使用HashSet类的HashSet.add方法的一些疑问

我想问下HashSet类中的Set.add方法,如果add相同的两个对象,是不是通过equals方法对比后,只在堆内存中生成一个对象?到底是覆盖第一个还是忽略后面的那个呢?我做了个实验,第一步:设定一个Student类,并且重写了该类中的equals方法,返回值的boolean类型为true(因为我要查明是覆盖还是忽略,所以让他不管相同还是不相同都返回true)。第二部:生成HashSet类并向上转型为Set,之后生成两个不同对象并且使用Set.add()添加。具体代码如下import java.util.Set;import java.util.HashSet;import java.util.Iterator;class Student{ String name ; int age; public Student() { } public Student(String name, int age) { this.name = name ; this.age = age ; } public boolean equals(Object o) { System.out.println("equals"); return true; } public static void main(String args []) { Set set = new HashSet(); Student s1 = new Student("zhangsan",20); Student s2 = new Student("lisi",21); System.out.println(s1.equals(s2)); set.add(s1); set.add(s2); Iterator it = set.iterator(); while(it.hasNext()) { Student s = (Student)it.next(); System.out.println(s.name); } }} 结果为:equalstruelisizhangsan 如果按照我预计的后果应该是lisi覆盖zhangsan,或者输出zhangsan忽略lisi。难道他调用的不是equals函数来比较的?

嘿嘿,这个就要说一下所谓的散列的概念了。像Set,Map这种东东在判断你的两个对象是否是一样的时候先回去判断你的hashCode方法返回的值是否一致,如果一致再去判断equals方法返回的值。所以,这个地方,你想玩的话,hashCode方法是需要重写的啦,像这种hashCode和equals方法在重写的时候有许多java规约性的东西,如果你想写好的话最好上网查查。这里顺便就说一下散列桶这个东西吧,在Set,Map这种容器里面存放对象数据的时候,这些数据以存在以hashCode为单位的散列桶里面的,hashCode相同的对象就会被放在同一个散列桶里面,在查找的时候会先定位到散列桶,然后再用equals方法去匹配散列桶里面的具体对象。所以,如果你定义的对象需要被存放在这类容器里面的话,hashCode和equals方法的重写就需要好好考虑一下了,不然会非常影响效率的。
温馨提示:内容为网友见解,仅供参考
第1个回答  推荐于2016-09-29
import java.text.DateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class test {
static class Student {
String name;
int age;

public Student() {
}

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

public int hashCode(){
return 1000;
}
public boolean equals(Object o) {
return true;
}

public static void main(String args[]) {
Set set = new HashSet();
Student s1 = new Student("zhangsan", 20);
Student s2 = new Student("lisi", 21);
System.out.println(s1.equals(s2));
set.add(s1);
set.add(s2);
Iterator it = set.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
System.out.println(s.name);
}
}
}

}

把代码改了一下 这下运行一下你该明白了
运行结果是
true
zhangsan本回答被提问者采纳

Java培训:HashSet的原理及常用方法
1. add(Object obj):向HashSet中插入元素,若元素已存在则返回false,否则返回true。2. remove(Object obj):从集合中移除指定元素,返回true表示移除成功,否则返回false。3. contains(Object obj):检查集合中是否包含指定元素,存在则返回true,否则返回false。4. clear():清空HashSet内的所有元素。

java hashset 有方法add(E o)这里的E是什麼类型?
这里用的是泛型,如定义 E 为String 类型,就只能添加String类型的 Set<String> set = new HashSet<String>();set.add("ssss");hashset 源码中 方法定义其实就是这样的 public HashSet(Collection<? extends E> c)百度下 java 泛型 这个不是那么好理解 多看资料 我本军团为你解答 ...

java代码中Hashset报错问题
将你的类名换一个就可以了。因为Java默认会先去找本包下面匹配的类名,如果有匹配的就不会去找java.util下面的类了。而你自己建的HashSet类并没有实现Set接口,所以会报错。

java程序设计问题,查找两个list属性值相同的元素,并对差异
方法一:使用HashSet HashSet在Java中是一个不包含重复元素的集合。通过合并两个列表并计算差集,可以找出重复元素。以下代码示例展示了使用HashSet方法:此代码由全栈式全自动开发工具-飞算SoFlu软件机器人生成的AI-FuncGPT(慧函数)自动创建,通过输入“找出两个List中的重复元素”这一指令,瞬间生成了上...

javaset的hashset什么输出数字是有序的?
HashSet运用了Hashmap的实现方式,内部存储数据依据哈希值排序。所有hashCode%size=0的key排在最前,hashCode%size=1的其次,以此类推。你观察到输出有序,这纯属偶然。你定义的Student类,hashCode是将id转为字符串后获取哈希值。Java默认字符串哈希值计算规则为:s[0]*31^(n-1) + s[1]*31^(n-...

java中的hashSet为什么会自动排序的呢
hashset是set的子集,Set的底层是Map实现的,Map的实现是散列码,就是根据key的hashcode计算出来的,通过这个hashcode计算出一个元素放在数组中的index,这样是为了快速查找元素,减少相等的判断。Set set = new LinkedHashSet();这样的话,就是按照元素的加入顺序保存元素的顺序。

面试官:HashSet如何保证元素不重复?
HashSet 基本操作方法有:add(添加)、remove(删除)、contains(判断某个元素是否存在)和 size(集合数量)。这些方法的性能都是固定操作时间,如果哈希函数是将元素分散在桶中的正确位置。HashSet 的基本使用方式如下:HashSet 不能保证插入元素的顺序和循环输出元素的顺序一致,实际上,HashSet 是无序...

java中HashSet的哈希表和ASCII码还有2进制之间是什么关系
首先电脑只有0,1就是所谓的二进制;HashSet的哈希表是通过哈希算法来的(后面一个数是前面两个数之和),HashSet里面是通过哈希算法计算出值然后形成的一条哈希单向链;而ASCII码是字节数,就像你传输IO流底层都是通过byte实现的,所以无论什么都可以变成byte字节,比如某个东西变成byte字节这个字节数就是...

java 关于集合Set接口的实现类中 元素相等的问题
HashSet确实是靠hashcode来运算出这个元素应该存放在什么地方。但是不同的对象,hashcode也可能会相同。这时就发生了冲突,需要再次比较发生冲突的两个或多个元素是否相同(通过equals方法)。如果相同添加失败,如果不同添加成功。为什么不直接用equals比较是否相同?因为不知道该跟哪个元素比较啊,难不成遍历...

java HashSet 中addall()函数有重复怎么办?
equals方法改为:public boolean equals(Object o) { Name name=(Name)o;boolean a = Firstname.equals (name.Firstname);boolean b =Lastname.equals(name.Lastname);return a&&b;}

相似回答