如何避免在集合中插入重复元素?如果我有:

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

推荐答案

正如 comments 中已经提到的,您的User类需要通过重写equals()hashCode()方法来遵守hashcode和equals约定.

https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

在代码中,您使用的是HashSet,它在引擎盖下实现为HashMap.相反,HashMap被实现为桶的数组,其中每个条目基于密钥的hashCode()存储在桶中.然而,不同的键可能会产生相同的哈希代码,因此可能会在同一个bucket中列出多个条目.此时,HashMap必须求助于equals()方法,以在对应于输入条目的bucket中找到准确的键,以便检索或替换元素.这个简短的解释向您展示了为什么正确定义hashCode()equals()方法如此重要,因为正如您所看到的,HashMap严重依赖于这些方法.

https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html

这里是User类的一个正确实现,其中两个用户如果具有相同的属性,则称为相同:uidnamepversionupicture.相反,如果两个用户仅在某些提到的字段上是相同的,那么您需要相应地更新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);
    }
}

Test Main

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("la dimensione è: " + user.size());
    }
}

Output

la dimensione è: 1

Java相关问答推荐

Java小程序未在MacOS上运行

判断大写字符串的Java方法总是返回假

如何在Android上获取来电信息

无法找到符号错误—Java—封装

Mat. n_Delete()和Mat. n_release的区别

如何在Javascript中设置文本区域圆角的样式

Quarkus keycloat配置不工作.quarkus. keycloak. policy—enforcer. enable = true在. yaml表示中不工作

Java函数式编程中的双值单值映射

为什么不应用类型推断?

Java中实现的归并排序算法给出ArrayIndexOutOfBound异常

使用REST客户端和对象映射器从字符串反序列化Json

带错误BER验证的itext8签名返回pdf

用户填充的数组列表永不结束循环

在添加AdMob时无法为Google Play构建应用程序包:JVM垃圾收集器崩溃和JVM内存耗尽

如何在Cosmos DB(Java SDK)中增加默认响应大小

在macOS上读取文件会导致FileNotFound,即使文件存在(并且具有权限)

与IntArray相比,ArrayList<;Int>;对于大量元素的性能极差

在实例化中指定泛型类型与不指定泛型类型之间的区别

协同 routine 似乎并不比JVM线程占用更少的资源

由于版本不匹配,从Java 8迁移到Java 17和Spring 6 JUnit4失败