【问题标题】:HashSet adding duplicatesHashSet添加重复项
【发布时间】:2016-06-04 16:31:15
【问题描述】:

我正在研究 hashmaps 。它不允许重复,但在这个程序中它添加了三个项目,据我说它应该只添加一个 bcz 其余部分相同。

 import java.util.*;
public class WrappedString {
private String s;
public WrappedString(String s) { this.s = s; }
public static void main(String[] args) {
    HashSet<Object> hs = new HashSet<Object>();
    WrappedString ws1 = new WrappedString("aardvark");
    WrappedString ws2 = new WrappedString("aardvark");
    String s1 = new String("aardvark");
    String s2 = new String("aardvark");
    System.out.println(hs.add(ws1));    //true
    System.out.println(hs.add(ws2));    ////true
    System.out.println(hs.add(s1)); //true
    System.out.println(hs.add(s2)); //false
    System.out.println(hs.size());//3 } }

【问题讨论】:

  • 这个类WrappedString是什么? HashSet 依赖于equals() 方法来避免重复。如果您的课程没有覆盖它,那么您可能会得到不可预知的结果
  • @zencv 没有必要覆盖 equals() 方法,因为它已经可用于所有类,因为该方法是在 Object() 类中定义的
  • @DishaJain Exactly Object 实现 equals 并且它确定这两个对象不相等。
  • @DishaJain:Object 中 equals 的默认实现不比较逻辑相等,而只比较对象标识。如果这是您想要的,那很好 - 任何依赖于 equals 的 Set 实现都会将它们视为不同的对象。如果您希望将两个不同的对象视为相同,则提供您自己的equals和hashCode实现

标签: collections hashset


【解决方案1】:

在你的问题中:

System.out.println(hs.add(ws1)); //真

System.out.println(hs.add(ws2));////真

System.out.println(hs.add(s1)); //真

原因是当您在HashSet 上调用add 方法时,您要添加的element 使用equals() 方法与Set 的现有elements 进行检查。这里ws1 不等于ws2,也没有一个不等于s1。所以你看到true 三次。

【讨论】:

  • 那么在 TreeSet 为什么它不起作用的情况下 public class Drink 实现 Comparable { public String name; public int compareTo(Object o) { return 0; } @SuppressWarnings("rawtypes") public static void main(String arg[]) { Drink one = new Drink();喝两杯 = new Drink(); one.name="咖啡"; two.name="茶";树集集 = 新树集(); System.out.println(set.add(one)); //true System.out.println(set.add(two));//false }这里也应该插入两者,因为它们是唯一的对象
【解决方案2】:

发生这种情况是因为 WrappedString 不像“正常”String 那样工作。那我推荐你使用String。

它将返回 false

new WrappedString("test").equals(new WrappedString("test"))

它将返回真

new String("aardvark").equals(new String("aardvark"))

如果结果返回 false,HashSet 将像一个新项目一样添加。

或者,如果您不希望更改为 String,则可以覆盖 WrappedString 的 equals 和 hashSet 确定何时比较差异,执行以下操作:

public class WrappedString {
    private String s;

    public WrappedString(String s) {
    this.s = s;
    }
    @Override
    public boolean equals(Object obj) {
        WrappedString ws = (WrappedString)obj;
        return this.s.equals(ws.s);
    }
    @Override
    public int hashCode() {
        return this.s.hashCode();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多