Set<String> set2 = new HashSet<>();
String s2 = new String("rajkumar");
String s3 = new String("rajkumar");
set2.add(s3);
set2.add(s2);
System.out.println(set2.size()); //this will output 1
Person p1= new Person("rajkumar", 25);
Person p2= new Person("rajkumar", 25);
Set<Person>set= new HashSet<>();
set.add(p1);
set.add(p2);
System.out.println(set.size());//This will output 2
为什么会这样。字符串对象的has哈希码不是应该不同吗?
这里的人班就像
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
答案 0 :(得分:2)
Set
允许唯一的条目。唯一性通过equals
方法检查。
s2和s3都具有相同的文本,因此两者相等。字符串类实现equals
方法进行文本比较。在将s3添加到现有集合时,不会添加s3对象,相反,该方法返回false,表示具有相同值的对象已经存在。
另一方面,Person类未实现equals和hashcode,因此将对引用进行比较。在这种情况下,两个对象都添加到集合中
浏览javadoc以获得更多信息。
答案 1 :(得分:1)
在Java中有字符串池,该池将相等的字符串保存在同一内存中。查看此链接:https://www.journaldev.com/797/what-is-java-string-pool。 如果要一次在集合中使用同一个人,则必须重写equals方法。
答案 2 :(得分:1)
Java Set接口java.util.Set表示对象的集合,其中Set中的每个对象都是唯一的。换句话说,在Java集中,同一对象不能出现多次。 source
哈希集由哈希图支持
set2的类型为String。 s2和s3都被视为相同的字符串,因此set2中仅存在一个条目
set接受类型为Person的对象,而p1和p2是不同的对象,尽管它们具有相同的字段。
要对此进行测试,请进一步更改s2或s3的字符串值,并尝试在Person类中创建equals和hashcode方法:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
答案 3 :(得分:0)
查看HashSet的add方法实现
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
它在内部使用Hashmap添加元素 现在看一下HashMap的内部实现
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
您可以看到它调用了键的equals方法,即要在HashSet中添加的元素 字符串类具有等于任何自定义/用户定义类的默认实现,如果添加到集合中则必须覆盖等于和哈希码
答案 4 :(得分:0)
您可以看一下这篇文章:Can a set have duplicate elements?。这里很好地说明了set
的工作方式。
但是,如果我们看您的问题,您的两个Strings
都是相同的(equals
比较)。另一方面,Person
object
不相同。如果您希望Person
objects
像String
一样工作,则应该在class
中使用overide equals method。