【问题标题】:How to not add duplicates to an arrayList如何不向arrayList添加重复项
【发布时间】:2014-11-03 14:49:34
【问题描述】:

我的任务的简要概述: 我应该编写一个使用我创建的帐户类的 ATM 类。 (accounts类包含方法,open——创建新账户,quit——退出当前账户,login——用户登录账户,存款,取款,获取余额,终止——突破无限环形)。我的 ATM 类必须跟踪所有打开的帐户,所以我想使用一个 account 类型的数组列表。但由于某种原因, .contains() 方法无法识别重复项,因此它不断添加已经存在的帐户,我不太确定如何解决此问题。这是我的代码: 谢谢 =)

我的账号类:

导入 java.util.ArrayList;

public class Account 
{
    public ArrayList<Account> accounts;
    public static int NextAcctNo = 999;
    private int accountNo;
    private double balance;
public Account() 
{ // constructor

    balance = 0.0; 
    accountNo = ++NextAcctNo;
}

public void Open()
{
    System.out.println("New account number: " + accountNo);
}

public void Quit()
{
    System.out.println("Goodbye");
}

public void Login(int accountNo)
{
    System.out.println("Hello");
    this.accountNo = accountNo;
}

public void Deposit(double amount) 
{ // method
    balance += amount; 
    System.out.println("Deposited: " + amount);
}

public void Withdraw(double amount) 
{ // method
    balance -= amount; 
    System.out.println("Withdrew: " + amount);
}

public double Balance() 
{ // method
    System.out.println("Balance: " + balance);
    return balance; 
}

public void Terminate()
{
    System.out.println("Terminated");
}

public int getAccountNo() 
{ // method
    return accountNo; 
}

}//class Account

我的主要方法:

import java.util.Scanner;
import java.util.ArrayList;

public class ATM 
{

    // search for accounts for D, W, B

    public static void main(String [] args)
    {

        ArrayList<Account> accounts = new ArrayList<Account>();
        int counter = 0;

        while (true)
        {

            Scanner commandScanner = new Scanner(System.in);
            System.out.print("Enter a command - O, Q, L, D, W, B, T: ");
            String command = commandScanner.nextLine();

            if (command.equals("O") == true)
            {   
                Account newAccount = new Account();
                accounts.add(newAccount);
                counter++;
                newAccount.Open();  
            }

            else if (command.equals("Q") == true)
            {
                if (accounts.size() == 0)
                {
                    System.out.println("Error");
                }
                else
                {
                    accounts.get(counter-1).Quit();
                }
            }

            else if (command.equals("L") == true)
            {
                Scanner numberScanner = new Scanner(System.in);
                System.out.println("Enter your account number: ");
                int accountNo = numberScanner.nextInt();
                Account temp = new Account();
                temp.accountNo = accountNo;

                if (counter == 0)
                {
                    accounts.add(temp);
                    counter++;
                }
                else if (counter > 0)
                {
                    if (accounts.contains(temp.accountNo) == true)
                    {
                        counter+=0;
                    }
                    else
                    {
                        Account newAccount = temp;
                        newAccount.Login(accountNo);
                        accounts.add(newAccount);
                        counter++;
                        System.out.println(accounts.size());
                    }
                }




            }

代码仍在进行中,我还没有全部发布 - 这就是为什么括号没有全部关闭的原因。

【问题讨论】:

  • 您需要覆盖Account 类的hashcodeequals 方法,以便ArrayList 检测对象的重复实例
  • 你可以使用'HashSet'概念来存储值。
  • 在覆盖 hashcode 和 equals 之后,您可以使用 set,因为不会有数据重复。

标签: java oop arraylist duplicates contains


【解决方案1】:

ArrayList#contains 使用Object#equals 方法来确定对象之间的相等性。默认情况下,这个简单的比较对象的内存位置(o1 == o2

您需要覆盖Account 类的equals 方法并比较(类似)帐户ID

public class Account {

    //...

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

}//class Account

现在,话虽如此,每次您创建一个临时的Account 时,您都会自动增加帐号,这并不理想。

更好的解决方案是使用某种Map,键入帐号,这样您就可以简单地执行类似...

Scanner numberScanner = new Scanner(System.in);
System.out.println("Enter your account number: ");
int accountNo = numberScanner.nextInt();
Account account = accountsMap.get(accountNo);
// Check for a null return result...

这确实意味着,每次创建Account 时,都需要将其添加到Map,因此可能需要某种工厂方法...

ps...

equals 和hashCode 方法之间存在契约联系,这通常意味着,当您覆盖一个时,您应该覆盖另一个

注意,一般需要在任何时候重写 hashCode 方法,以维护 hashCode 方法的通用约定,即相等的对象必须具有相等的哈希码

例如...

public class Account {

    //...

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

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

}//class Account

【讨论】:

  • @nem 是的,进入“但你可以......”状态......:P
【解决方案2】:

可能刚刚超出了我的想象,但是如果您正在寻找您的 Account 类的重复项,为什么不在创建一个唯一标识符(主键)时添加一个唯一标识符(主键)?

数据是来自数据库还是只是静态输入?如果它来自数据库,那么主键就可以了。否则,只需将主键属性添加到您的模型,然后检查是否有任何帐户具有相同的主键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    相关资源
    最近更新 更多