只存储一个HashSet值亲人,当equals方法说,它们是相同的。 那正是我所想。
但现在我将元素添加到HashSet的地方equals方法返回true并且集的大小还是增长? 抱歉,我很困惑。 一些提示在那里我错了就好了。
Element t1 = new Element(false, false, false, false);
Element t2 = new Element(true, true, true, true);
Element t3 = new Element(false, false, false, false);
if (t1.equals(t3))
System.out.println("they're equal");
Set<Element> set = new HashSet<>();
set.add(t1);
set.add(t2);
set.add(t3);
System.out.println("set size: " + set.size());
所以在这个例子我的控制台输出:
他们是平等的
集大小:3
这是没有意义的我..不该大小为2?
问题是,你的Element
类有没有覆盖的equals
和hashCode
方法或这些实现都断了。
从Object#equals
方法的javadoc:
equals方法实现对非空对象引用的一个等价关系:
- 自反性:对于任何非空的参考值x,x.equals(x)应返回true。
- 对称性:对于任何非空的参考值x和y,x.equals(y)的应返回true,当且仅当y.equals(x)返回真。
- 传递性:对于任何非空引用值x,y和z,如果x.equals(Y)返回true并且y.equals(z)返回true,那么x.equals(z)应返回true。 它是一致的:对于任何非空引用值x和y,的-x.equals(y)的多个调用始终返回true或始终返回假,没有设置中使用的信息等于在对象上比较被修改。
- 对于任何非空引用值x,x.equals(空)应该返回false。
从Object#hashCode
方法的javadoc:
hashCode的一般合同是:
- 每当它是一个Java应用程序的执行期间,在同一对象上调用一次以上,hashCode方法必须一致地返回相同的整数,没有设置中使用的信息等于在对象上比较被修改。 该整数不必从一个应用的执行保持一致,以同一应用程序的另一执行。
- 如果两个对象根据equals(Object)方法是相等的,则调用在每个两个对象的hashCode方法必须产生相同的整数结果。
- 这不是必需的:如果两个对象根据equals(java.lang.Object)方法是不相等的,然后调用hashCode方法在各两个对象的必须产生不同的整数结果。 但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
确保这些方法的实现满足这些规则和您的Set
(由支持HashSet
)会正常运行。
你的对象有不同的散列所以HashSet的“放”,然后在不同的“桶”。
如果你有自己的模型类,你需要改变一些基本功能的工作就像在下面的例子来完成。
执行代码:
HashSet<MyModel> models = new HashSet<MyModel>();
for (int i = 1; i < 5; i++)
models.add(new MyModel(i + "", "Name :" + i + ""));
for (int i = 3; i < 5; i++)
models.add(new MyModel(i + "", "Name :" + i + ""));
for (Object object : models)
System.out.println(object);
模型类:
/**
* Created by Arun
*/
public static class MyModel {
private String id = "";
private String name = "";
public MyModel(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return getId();
}
@Override
public boolean equals(Object obj) {
return !super.equals(obj);
}
public int hashCode() {
return getId().hashCode();
}
}
希望这可以帮助。
是的,我们可以用这不是最终的类的对象实现它。
HashSet的支票两种方法hashCode()
和equals()
添加任何对象之前。 首先它检查方法hashCode()
,如果它返回的哈希码是相同的任何组中的对象,然后它检查该对象,其在内部的参考文献中两个对象即比较equals方法this.obj1==obj
。如果这些是在这种情况下,相同的附图标记,则返回true意味着它是一个重复的值。 我们可以通过重写的hashCode添加重复的非最终目标和equals方法。 在hashCode()方法,你可以在同样的参数的情况下返回相同的哈希码。
见例如:
public class Product {
int i;
Product(int a)
{
this.i=a;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + i;
return result;
}
@Override
public boolean equals(Object obj) {
/*if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Product other = (Product) obj;
if (i != other.i)
return false;
return true;*/
return true;
}
}
`
`
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Product p1=new Product(1);
Product p2=new Product(1);
Product p3=new Product(1);
Set s=new HashSet();
s.add(p1);
s.add(p2);
s.add(p3);
System.out.println(s.size());
}
}
输出将是1。
PS:如果不重写这些方法,输出将是3,因为它会使用它们的默认行为。