如何避免在 Set 中插入重复元素?如果我有:
Set<User> user=new HashSet<>();
User user1=new User("11","Mark",null,"1");
User user2=new User("11","Mark",null,"1");
User user3=new User("12","Helen",null,"2");
user.add(user1);
user.add(user2);
Log.d("main_activity_user", "la dimensione è" +String.valueOf(user.size()));
Adn 用户类别是:
public class User {
public String uid;
public String name;
public String pversion;
public String upicture;
public User(String uid,
String name,
String upicture, String pversion ){
this.uid=uid;
this.name=name;
this.upicture=upicture;
this.pversion=pversion;
}
public String get_uid(){
return uid;
}
public String get_name(){
return name;
}
public String get_pversion(){
return pversion;
}
public String get_upicture(){
return upicture;
}
@Override
public boolean equals(Object obj) {
User newObj = (User)obj;
if (this.get_uid().equals( newObj.get_uid()))
return true;
else
return false;
}
}
现在
Set
还存储重复项并打印 3 个元素而不是两个。为什么?
我以前从未使用过
Set
类,我不明白它。那么,每次我使用 Set
类时,我是否必须重写 Equals 方法?为什么?类不会自动删除重复项吗?
正如评论中已经说过的,您的
User
类需要通过重写 equals()
和 hashCode()
方法来遵守哈希码和 equals 契约。
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()
在您的代码中,您使用的是
HashSet
,它在底层实现为 HashMap
。相反,HashMap
被实现为存储桶数组,其中每个条目都存储在基于键的 hashCode()
的存储桶中。但是,不同的键可能会产生相同的哈希码,因此同一存储桶中可能会列出多个条目。为了引用存储桶中的正确条目,HashMap
必须求助于键的equals()
方法来查找键与给定值匹配的确切条目。例如,当检索或替换元素时,执行该操作序列。最后,桶是一种通用的数据结构。在 Java 中,HashMap
的存储桶在 Java 7 之前被实现为 LinkedList
,而从 Java 8 开始,它采用混合解决方案,在一定数量的冲突后,LinkedList
实现切换为平衡树。有关更多详细信息,请阅读JEP-180。
这个简短的解释向您展示了为什么提供
hashCode()
和 equals()
方法的正确定义如此重要,因为,如您所见,HashMap
严重依赖于这些方法。
https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html
这是
User
类的正确实现,如果两个用户具有相同的内容,则称他们相同:uid
、name
、pversion
和 upicture
。相反,如果两个用户仅在某些提到的字段上相同,那么您应该相应地更新 equals()
和 hashCode()
实现(它们都必须基于相同的字段)。
public class User {
public String uid;
public String name;
public String pversion;
public String upicture;
public User(String uid, String name, String upicture, String pversion) {
this.uid = uid;
this.name = name;
this.upicture = upicture;
this.pversion = pversion;
}
public String getUid() {
return uid;
}
public String getName() {
return name;
}
public String getPversion() {
return pversion;
}
public String getUpicture() {
return upicture;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(uid, user.uid) && Objects.equals(name, user.name) && Objects.equals(pversion, user.pversion) && Objects.equals(upicture, user.upicture);
}
@Override
public int hashCode() {
return Objects.hash(uid, name, pversion, upicture);
}
}
public class Main {
public static void main(String[] args) {
Set<User> user = new HashSet<>();
User user1 = new User("11", "Mark", null, "1");
User user2 = new User("11", "Mark", null, "1");
User user3 = new User("12", "Helen", null, "2");
user.add(user1);
user.add(user2);
System.out.println("Size is: " + user.size());
}
}
Size is: 1