Reputation: 1
So brief overview of my assignment: I'm supposed to write an ATM class that uses an accounts class I created. (The accounts class contains methods, open - to create a new account , quit - to exit the current account , login - for a user to login to their account , deposit, withdraw, get balance, and terminate - which breaks out of the infinite loop). My ATM class must keep track of all the opened accounts, so I figure use an array list of type account. For some reason though, the .contains() method is not recognizing duplicates, so it keeps adding accounts that are already there, and I'm not quite sure how to fix this issue. Here's my code: THANKS =)
My account class:
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
my main method:
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());
}
}
}
The code is still work in progress, I haven't posted it all - which is why the brackets aren't all closed off.
Upvotes: 0
Views: 882
Reputation: 347184
ArrayList#contains
uses the Object#equals
method to determine equality between objects. By default this simple does a comparison of the memory location of the object (o1 == o2
)
You will need to override the equals
method of the Account
class and compare (something like) the 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
Now, having said this, each time you create a temporary Account
you are automatically incrementing the account number, which isn't really desirable.
A better solution would be to use a Map
of some kind, keyed to the account number, so that you could simply do something like...
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...
This does mean, that each time you create an Account
, you will need to add it to the Map
, so a factory method of some kind is probably called for...
ps...
There is a contractual link between the equals and the hashCode
method, which generally means, when you override one, you should override the other
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
For example...
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
Upvotes: 2
Reputation: 833
May have just gone over my head but if you are looking for duplicates of your Account class, why not just add a unique identifier (primary key) whenever one is created ?
Is the data from a database or are you just statically typing entering it? If its from a DB then the primary key is fine. Otherwise just add a Primary Key property to your model and just check to see if any accounts have the same primary key.
Upvotes: 0