当前位置: 首页 > 面试题库 >

更改集合中的元素会更改“等于”语义

慕嘉运
2023-03-14
问题内容

想象一下,我们有这段代码。

public class HashAddAfter {
    private class A {
        public int value;
        public A(int value) {
            this.value = value;
        }
        public void setValue(int value) {
            this.value = value;
        }
        // Code for hashCode()...
        // Code for equals()...
    }

    Set<A> list1 = new HashSet<A>();
    Set<A> list2 = new HashSet<A>();

    public static void main(String[] args) {
        HashAddAfter x = new HashAddAfter();

        A e1 = x.new A(1);
        A e2 = x.new A(1);

        x.list1.add(e1);
        x.list2.add(e2);

        System.out.println(x.list1.equals(x.list2));   // true

        e1.setValue(4);
        e2.setValue(4);

        System.out.println(x.list1.equals(x.list2));   // false
    }
}

由于空间限制,我没有将hashCode()和equals()的代码放入其中,但这是从Eclipse生成的代码。

问题在于,在更改两个集合中的元素之前,这两个集合是相等的。更改它们的值(每个值都相同)后,尽管e1.hashCode()==
e2.hashCode()和e1.equals(e2),但这些集合不再相等。

我猜想在比较两个HashSet时,Java使用元素的原始hashCode(在插入时是一个)。因此,在插入后更改元素会更改其原始hashCode,因此contains()将返回false。

我认为这是一种非常不直观的行为。

你怎么看?


问题答案:

这正是预期的行为。有一个没有可能的方式Set实施,要知道,hashCode一个元素的改变了,所以没有什么可以做,以抵御这种可能性。

Set
Javadoc:

注意:如果将可变对象用作集合元素,则必须格外小心。如果对象的值以影响相等比较的方式更改,而对象是集合中的元素,则不指定集合的​​行为。此禁止的一种特殊情况是,不允许集合将自身包含为元素。



 类似资料:
  • 我正试图从网站上获取预订数据。进入现场后,我必须: 将默认日期范围(起初,网站显示默认日期范围的预订数据)更改为我想要搜索的日期范围 点击刷新按钮 等待网站更新页面上显示的结果。 使用Selenium、Python和BeautifulSoup,当我执行Selenium命令更新日期范围的字段并单击“刷新”按钮时,当代码到达我使用BeautifulSoup提取HTML数据的行时,将提取默认网站日期范围

  • 如何使用WebDriverWait等到属性更改? 在我的AUT中,我必须等待一个按钮被启用后才能继续,不幸的是,由于开发人员编码页面的方式,我不能使用WebElement的isEnabled()方法。开发人员正在使用一些CSS来使按钮看起来像是被禁用的,这样用户就不能点击它,并且方法isEnabled对我来说总是返回true。所以我要做的就是获得属性“aria-disabiled”,检查文本是“t

  • 问题内容: 当我转换到元素的顺序发生变化,由字符排序。 考虑以下示例: 我的问题是 为什么会这样呢? 如何进行设置操作(尤其是“设置差异”)而不丢失初始顺序? 问题答案: 是无序的数据结构。 不要使用,而是: 请注意,的顺序b无关紧要,因此它可以是可迭代的,但是应该是支持O(1)成员资格测试的可迭代。 编辑:上面的答案假定你希望能够对所有出现的集合执行(有序)设置操作,尤其是对先前设置操作的结果也

  • 问题内容: 我想动态更新元素的文本: 我是jQuery的新手,因此对我来说,这项任务似乎非常具有挑战性。有人可以指出我要使用的功能/选择器吗? 如果可能的话,我想在不为需要更改的文本添加新容器的情况下执行此操作。 问题答案: 在Javascript中,该属性为您提供元素的所有子节点,包括文本节点。 因此,如果您知道要更改的文本始终是元素中的第一件事,那么请给出以下HTML: 您可以这样做: 当然,

  • 问题内容: 我想使用CSS 更改标签的颜色。我在下面尝试过的代码似乎不起作用: 问题答案: 我想如果您打算更改tag 产生的线条的颜色,则应该使用而不是。 虽然,在注释中已指出,如果您更改线条的大小,边框仍将与样式中指定的宽度一样,并且线条将被填充为默认颜色(大多数情况下这不是理想的效果)时间)。因此,在这种情况下,您似乎还需要指定(如@Ibu在其答案中建议的那样)。 HTML 5 Boilerp

  • 问题内容: 如何使用WebDriverWait等待属性更改? 在我的AUT中,我必须等待按钮被启用后才能继续,但是不幸的是,由于开发人员对页面进行编码的方式,我无法使用WebElement的isEnabled()方法。开发人员正在使用一些CSS来使按钮看起来像已禁用,因此用户无法单击它,并且isEnabled方法始终为我返回true。因此,我要做的就是获取属性“ aria-disabled”,并检