删除集合[重复项]中的重复项

问题描述 投票:0回答:1

如何避免在 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 方法?为什么?类不会自动删除重复项吗?

java collections duplicates set hashset
1个回答
3
投票

正如评论中已经说过的,您的

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
© www.soinside.com 2019 - 2024. All rights reserved.