[英]Tree Set behaves differently but hash set doesn't in case of custom object
In below created code have Employee class with attributes Id and Name,Created 3 objects of Employee class e1,e2,e3 with respective name attribute a,b,a. 在下面创建的代码中,创建了具有ID和Name属性的Employee类,创建了3个Employee类e1,e2,e3对象,它们分别具有名称属性a,b,a。 when I add these object in hash set the size shows 3 but on same while in Tree Set it show size 2 even i am not overriding the hash code and equals method.
当我将这些对象添加到哈希集中时,大小显示为3,但在树集中同时显示为2,即使我没有覆盖哈希码和equals方法。
Emplyoee class.............................
package collection.core.concept;
public class Employee implements Comparable<Employee>{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Employee o) {
if(this.name.equal(o.getName()){
return 0;
}else{
return 1;
}
}
@Override
public String toString(){
return name;
}
}
main class...............................................
public class CustomTreeSetSorting {
public static void main(String[] args) {
Employee e1 = new Employee();
e1.setId(1);
e1.setName("alok");
Employee e2 = new Employee();
e2.setId(2);
e2.setName("vaibhav");
Employee e3 = new Employee();
e3.setId(3);
e3.setName("alok");
Set<Employee> Employee1 = new TreeSet<Employee>();
Employee1.add(e1);
Employee1.add(e2);
Employee1.add(e3);
System.out.println(Employee1.size());
}
}
In general sets you cannot have repetitions. 一般而言,您不能重复。 Hence the size is two.
因此,大小为两个。
Since 以来
@Override
public boolean equals(Object obj) {
Employee emp = (Employee) obj;
if (name.equals(emp. getName())) {
return true;
}
return false;
}
It checks only name even though the id is different it treats them as same objects. 即使id不同,它也只检查名称,它将它们视为相同的对象。
Change it to 更改为
@Override
public boolean equals(Object obj) {
if(obj instanceof this) {
Employee emp = (Employee) obj;
if (name.equals(emp. getName()) && id == emp.getId()) {
return true;
}
return false;
}
return false;
}
Also the code is wrong for 另外代码是错误的
@Override
public int compareTo(Employee o) {
if(this.name==o.name){
return 0;
}else{
return 1;
}
}
Change it to 更改为
@Override
public int compareTo(Employee o) {
return name.compareTo(o.getName());
}
You cannot compare strings with == use .equals method. 您不能使用==使用.equals方法比较字符串。
Whenever you are add something to TreeSet then compareTo method of class Employee is getting invoked and in compareTo
method you are stating that if 2 names are equal then both objects are the same. 每当您向TreeSet添加一些内容时,便会调用Employee类的compareTo方法,并在
compareTo
方法中声明如果2个名称相等,则两个对象都相同。 Thats why TreeSet is adding only 2 objects alok
and vaibhav
. 这就是为什么TreeSet仅添加2个对象
alok
和vaibhav
。 Moreover, currently you are comparing string wrongly , in order to compare Strings use compareTo on String objects that compare objects based on natural ordering ie lexicographically 此外,当前您错误地比较了字符串,为了比较字符串,请对基于自然顺序(即按字典顺序比较对象)的String对象使用compareTo
How could we get different results according to the set that is used? 我们如何根据所使用的设置获得不同的结果? It's quite simple : the HashSet uses both equals and hashCode to check object equality.
这很简单:HashSet同时使用equals和hashCode来检查对象是否相等。 You've got 3 different ids, that's why you get 3 objects in your hashset.
您有3个不同的ID,这就是为什么在哈希集中获得3个对象的原因。
On the other hand, the TreeSet will use your compareTo method (or a provided Comparator) to compare items and check equality. 另一方面,TreeSet将使用您的compareTo方法(或提供的Comparator)比较项目并检查相等性。 If you compareTo method uses names only to give its result, and knowing you have only 2 unique names, then the TreeSet will only have 2 elements (probably the last one will be discarded)
如果compareTo方法仅使用名称来给出其结果,并且知道您只有2个唯一的名称,则TreeSet将仅具有2个元素(可能最后一个元素将被丢弃)
Personally if I was going to base my comparison on a single string for insertion into the tree I would use what is already given to us: 就个人而言,如果我将比较基于插入到树中的单个字符串,我将使用已经提供给我们的内容:
public int compareTo(Employee o) {
return this.name.compareTo(o.getName());
}
Not sure why this isn't the first choice? 不确定为什么这不是首选? Am I missing something?
我想念什么吗?
Given that, you probably need more than just the String, otherwise why have id's? 鉴于此,您可能不仅仅需要String,否则为什么要使用id? I can't fathom two employee objects being the same if they have different id's (ie if they have more than one ID, I would create an array of id's as names are not unique.)
如果两个员工对象具有不同的ID,则我无法理解它们是否相同(即,如果它们具有多个ID,由于名称不是唯一的,我将创建一个ID数组)。
Both HashSet
and Treeset
doesn't allow duplicates. HashSet
和Treeset
都不允许重复。
The behavior is explained by understanding How do you define a Duplicate!
通过了解
How do you define a Duplicate!
来解释该行为How do you define a Duplicate!
In case of HashSet
, the hashcodes for two objects are different even for same names, hence they are not considered duplicates.Unless you override hashCode
and equals
all the objects are considered distinct/unique 在的情况下,
HashSet
,两个对象的哈希码是即使是同一名称的不同,因此它们没有考虑duplicates.Unless你重写hashCode
和equals
所有的对象都认为是不同的/独特
You are providing the definition of "Duplicate" by overriding compareTo
. 您将通过覆盖
compareTo
提供“ Duplicate”的定义。 ie If the names are same then the Objects are same 即,如果名称相同,则对象相同
To allow duplicates in your TreeSet
, Change your compareTo
to 要允许
TreeSet
有重复项,请将compareTo
更改为
@Override
public int compareTo(Employee o) {
if (this.name.equals(o.getName())) {
return -1; //return 0 says that two objects are same
} else {
return 1;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.