java.util.Set.remove(Object o) - 问题 [英] java.util.Set.remove(Object o) - problem

查看:112
本文介绍了java.util.Set.remove(Object o) - 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在这里遗漏一些东西......我有以下代码和输出。你能看出为什么类别categoryToBeDeleted 没有从结果中每本书的类别集中删除?

I must be missing something here... I have the following code and output. Can you see why Category categoryToBeDeleted is not being deleted from the category set of each book in result?

谢谢!!

代码:

List<Book> result = ... //get list from database

final Category categoryToBeDeleted = ... //get category from database

System.out.println("categoryToBeDeleted id: " + categoryToBeDeleted.getId() + " name: " + categoryToBeDeleted.getName());

for (Book book : result) {
    System.out.println("before remove :");
    for (Category category : book.getCategories()) {
        System.out.println("category id: " + category.getId() + " name: " + category.getName() + " equals: " + category.equals(categoryToBeDeleted));
    }
    System.out.println("-----------------------");

    book.getCategories().remove(categoryToBeDeleted);

    System.out.println("after remove :");
    for (Category category : book.getCategories()) {
        System.out.println("category id: " + category.getId() + " name: " + category.getName() + " equals: " + category.equals(categoryToBeDeleted));
    }
    System.out.println("-----------------------");

}

输出:

categoryToBeDeleted id: 10 name: cosmetics
before remove :
category id: 10 name: cosmetics equals: true
category id: 1 name: cleaning equals: false
-----------------------
after remove :
category id: 10 name: cosmetics equals: true
category id: 1 name: cleaning equals: false
-----------------------
before remove :
category id: 9 name: junk-2 equals: false
category id: 10 name: cosmetics equals: true
-----------------------
after remove :
category id: 9 name: junk-2 equals: false
category id: 10 name: cosmetics equals: true
-----------------------
before remove :
category id: 6 name: knick-knacks equals: false
category id: 4 name: baby equals: false
category id: 9 name: junk-2 equals: false
category id: 10 name: cosmetics equals: true
-----------------------
after remove :
category id: 6 name: knick-knacks equals: false
category id: 4 name: baby equals: false
category id: 9 name: junk-2 equals: false
category id: 10 name: cosmetics equals: true
-----------------------

PS类别包含:

@Override
public boolean equals(Object obj) {
    if (obj instanceof Category) {
        Category thatCategory = (Category) obj;
        return this.id.equals(thatCategory.id);
    }
    return false;
}

Javadoc

删除

布尔删除(对象o)

从中删除指定的元素如果存在则设置此选项(可选操作)。更正式地,如果此集合包含这样的元素,则删除元素e(o == null?e == null:o.equals(e))。如果此set包含该元素,则返回true(或等效地,如果此set由于调用而更改)。 (一旦调用返回,该集合将不包含该元素。)

Removes the specified element from this set if it is present (optional operation). More formally, removes an element e such that (o==null ? e==null : o.equals(e)), if this set contains such an element. Returns true if this set contained the element (or equivalently, if this set changed as a result of the call). (This set will not contain the element once the call returns.)

推荐答案

您的集合实际上是 HashSet的。类别未实现 hashCode 。因此,当您去除对象时,对象标识符将用作哈希代码,并且对于每个不同的对象,即使它在语义上等效,它最终也会使用不同的哈希代码,查找错误的位置。哈希集,但没有找到合适的匹配对象。

Your set is actually a HashSet. Category isn't implementing hashCode. As a result, when you go to remove the object, the object identifier is used as the hash code, and for each different object, even if it's semantically equivalent, it ends up using a different hash code, looking in the wrong place in the hash set and not finding the appropriate matching object.

添加

@Override
public int hashCode() {
    return id.hashCode();
}

类别和一切都应该好。

可以在 hashCode 的要求//download.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29\"> java.lang.Object的#avaDoc#equals

The requirement to override hashCode can be read in the JavaDoc for java.lang.Object#equals:


注意,一旦覆盖此方法,通常需要覆盖hashCode方法
,以便维护一般$ b hashCode方法的$ b合约,它声明等于
的对象必须具有相同的哈希码。

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

正如本文所暗示的那样,用于hashCode的JavaDoc 涵盖了更多细节。

As this text implies, the JavaDoc for hashCode covers this in more detail.

虽然删除的JavaDoc可能在这个主题上更清晰,但它只引用等于作为规范的一部分它将删除的对象 - 它不会说等于是它将使用的唯一东西。

Whilst the JavaDoc for remove could perhaps be clearer on the subject, it only references equals as part of the specification for which object it will remove - it doesn't say that equals is the only thing it will use.

最后,如果您正在使用Eclipse,那么您可以打开一个警告,如果您覆盖等于而不覆盖 hashCode 反之亦然。

Finally, if you're using Eclipse, there's a warning you can turn on which will warn you if you override equals without overriding hashCode or vice-versa.

这篇关于java.util.Set.remove(Object o) - 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆