【问题标题】:Removing object element from HashSet从 HashSet 中删除对象元素
【发布时间】:2020-12-08 11:26:19
【问题描述】:

我正在开发电子钱包,并从基础开始。我将 Penny 对象添加到存储钱的 HashSet 中。我将容量初始化为 5,然后从一个完整的钱包开始。

当尝试花费一分钱时,返回 null(如预期的那样),但是当调用 moneyCheck() 方法时,仍然有 5 个硬币。

我不知道该怎么做,因为我正在尝试使用 .remove() 方法删除 Penny,并且对象没有从 HashSet 中删除。

import java.util.HashSet;

public class Wallet{
    private HashSet<Penny> walletPenny;

    public Wallet(){
        int walletCapacity = 5;
        walletPenny = new HashSet<>();

        int counter = 0;
        while (counter < pocketCapacity){
            pocketPenny.add(new Penny());
            counter++;
        }
    }

    public Penny removePenny(){
        Penny spentPenny = null;

        if (walletPenny.isEmpty()){
            System.out.print("No more pennies!\n");
            return spentPenny;
        }
        else {
            pocketPenny.remove(spentPenny);
            System.out.println(("Spent penny!"));
        }
        return spentPenny;
    }

    public int moneyCheck(){
        System.out.print("Money remaining: " + walletPenny.size() + "\n");
        return walletPenny.size();
    }
}

【问题讨论】:

  • 在你的removePenny()方法中,spendPenny 永远不会被初始化,它总是为空的。事实上你的代码不会编译。
  • 请注意,您的模型不是很健全。一方面,您使用 SET 来收集便士物品,另一方面,您知道钱对应于该集合中的条目数。这样做真的没有什么意义。在您的情况下,您的“钱包”可能只包含一个 int 计数器值!便士都是一样的,还是你真钱包里的便士分不清?不,您只关心它们的总数。

标签: java object hashset


【解决方案1】:

找到了一个答案,我想我会更新这个,以防其他人有同样的问题。

为了移除便士,我使用迭代器初始化了一个便士对象,以在 HashSet 中查找下一个可用对象。 然后我返回该值以在程序的其他地方使用。

    public Penny removePenny(){
        Penny spentPenny;

        if (walletPenny.isEmpty()){
            System.out.print("No more pennies!\n");
            spentPenny = null;
            return spentPenny;
        }
        else {
            spentPenny = walletPenny.iterator().next();
            walletPenny.remove(spentPenny);
            System.out.println(("Spent penny!"));
            return spentPenny;
        }
    }

【讨论】:

  • 这错过了你的问题的真正要点:你的 Penny 类上缺少 equals/hashCode 方法。
【解决方案2】:

当您尝试使用pocketPenny.remove(spentPenny) 删除便士时,Java 会尝试查找要删除的 便士。为了做到这一点,它使用equals 并迭代HashSet 直到找到与spentPenny 相等(身份明智)的一分钱。 More on how remove() works。由于您将 null 提供为 spentPenny,因此它将不匹配任何内容(您的 5 便士已初始化,因此它们不为 null)。如果您检查 .remove() 方法的返回值,您可以验证这一点 - 它将是 false

为了解决这个问题,您需要:

  1. 调用remove()方法时提供非空值
  2. 在您的 Penny 类中实现 equals()
  3. 跟踪您创建了哪些便士,以便日后删除它们

完整示例:

public class Penny {

    private final int serialNum;

    public Penny(int serialNum) {
        this.serialNum = serialNum;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 79 * hash + this.serialNum;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Penny other = (Penny) obj;
        return this.serialNum == other.serialNum;
    }

}

然后创建你的便士:

int counter = 0;
        while (counter < pocketCapacity){
            pocketPenny.add(new Penny(counter));
            counter++;
        }

现在您有 5 个便士,编号为 0 到 4。您可以删除一个,例如 #3:

Penny spentPenny = new Penny(3);
pocketPenny.remove(spentPenny);

【讨论】:

    猜你喜欢
    • 2015-06-30
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2014-05-05
    • 2020-05-11
    • 1970-01-01
    • 2010-11-09
    • 2015-11-16
    相关资源
    最近更新 更多