如何不将重复项添加到arrayList

时间:2014-09-10 04:18:07

标签: java oop arraylist duplicates contains

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

我的帐户类:

import 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());
                    }
                }




            }

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

2 个答案:

答案 0 :(得分:2)

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

您需要覆盖equals类的Account方法,并比较(例如)帐号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

答案 1 :(得分:0)

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

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