How to create a search method inside an array - java

Good morning, I have the following specification:
"The searchAccount () method must verify the existence of the current account passed as a parameter in the set of current currents existing in the bank and stored in the vector."
I have implemented the following solution.
public boolean searchAccount(BankAccount ba) {
boolean found=false;
int count=0;
while(count<=accounts.length-1) {
if(accounts[count]!=null &&(accounts[count].getCode().equals(ba.getCode())))
found=true;
else
found=false;
count++;
}
return found;
}
Note that accounts is an array defined inside the class where the searchAccount () method is present. However, this solution gives me problems at runtime. Everything is fine when compiling.
In particular given the following main () method:
public static void main(String[] args) {
// print a large HTML header
System.out.println("<h4>-- Bank account exercise --</h4>");
// create 5 objects of type BankAccount
BankAccount c1 = new BankAccount("001",5);
BankAccount c2 = new BankAccount("002",10);
BankAccount c3 = new BankAccount("003",15);
BankAccount c4 = new BankAccount("004",20);
BankAccount c5 = new BankAccount("005",25);
Bank b = new Bank("B001");
b.addAccount(c1);
b.addAccount(c2);
b.addAccount(c3);
b.addAccount(c4);
b.addAccount(c5);
System.out.println("Search bank account having code " +
c4.getCode() + ": ");
System.out.println((b.searchAccount(c4))?"Found":"Not found");
System.out.println("c1.equals(c2)?" + (c1.equals(c2)));
BankAccount c6 = new BankAccount("001",29);
System.out.println("c1.equals(c6)?" + (c1.equals(c6)));
//System.out.println(b);
}
By running I get:
<h4>-- Bank account exercise --</h4>
Search bank account having code 004:
Not found
c1.equals(c2)?false
c1.equals(c6)?true
I don't know why the searchAccount () method doesn't find the C4 object.

What happens when you find a match? You set found to true. Then, you continue searching. When there are more elements, you'll again set (reset) found to false.
You must break and return the result when you find a match (short-circuiting the search).
while(count <= accounts.length-1) {
if(accounts[count] != null &&(accounts[count].getCode().equals(ba.getCode()))) {
found = true;
break;
}
}
return found;
Or, you can remove the found variable and just return.
while(count <= accounts.length-1) {
if(accounts[count] != null &&(accounts[count].getCode().equals(ba.getCode()))) {
return true;
}
}
return false;

Try returning the true value instead of saving it using found variable. So write return true;
Your searchAccount method actually finds the target account, but just continues with the loop, so the next iteration will cause found to be false.

As the other answers mention, you need to break the search when the account is found.
Here are two other alternatives to the search.
Using for-loop:
public boolean searchAccount2(BankAccount ba) {
for(BankAccount account : accounts) {
if(account != null && account.getCode().equals(ba.getCode())) {
return true;
}
}
return false;
}
Using streams:
public boolean searchAccount3(BankAccount ba) {
return Arrays.asList(accounts).stream().filter(Objects::nonNull).anyMatch(b -> b.getCode().equals(ba.getCode()));
}
Update
To test the above code I implemented rudimentary Bank and BankAccount classes and ran your code above, but adding searchAccount2 and searchAccount3:
//...
System.out.println((b.searchAccount(c4))?"Found":"Not found");
System.out.println((b.searchAccount2(c4))?"Found":"Not found");
System.out.println((b.searchAccount3(c4))?"Found":"Not found");
//...
Accounts are assumed to be an array in the Bank class:
private BankAccount[] accounts
This is the output:
<h4>-- Bank account exercise --</h4>
Search bank account having code 004:
Not found
Found
Found
c1.equals(c2)?false
c1.equals(c6)?false
EDIT - addAccount()
Here is your addAccount (as posted in the comment) formatted:
public void addAccount2(BankAccount ba) {
//Il metodo addAccount() deve aggiungere il conto corrente passato
// come parametro al vettore dei conti correnti presente nella banca,
// se non e' giĆ  presente.
if (!searchAccount(ba)) {
for (int i = 0; i < accounts.length; ++i) {
if (accounts[i] == null) {
accounts[i] = ba;
// PROBLEM HERE!!!
}
}
}
}
This method will add the given account (ba) to every position in the array because you do not stop the loop at any time.
You need a return statement where I indicated the "PROBLEM HERE!!!":
public void addAccount2(BankAccount ba) {
if (!searchAccount(ba)) {
for (int i = 0; i < accounts.length; ++i) {
if (accounts[i] == null) {
accounts[i] = ba;
return;
}
}
}
}
Otherwise, after you add the first account (to every position) there is no more room to add further accounts.

The better option for this task will be usage of Map for store your accounts objects.
Something like this:
public class Bank {
private Map<String,Account> accounts = new HashMap<>();
public void addAccount(Account account){
accounts.put(account.getCode(),account);
}
public boolean searchAccount(Account account){
return accounts.containsKey(account.getCode());
}
}

Ok, so maybe it's my addAccount () method that's wrong. I'll bring it back here:
public void addAccount(BankAccount ba) {
if(!searchAccount(ba))
for(int i=0;i<=accounts.length-1;i++)
if(accounts[i]==null)
accounts[i]=ba;
}

Related

javafx user-interface app can't access all the values from an ArrayList

So im developing a javafx gui that it should return all the valid values found in an ArrayList input range, but instead it's functionality its only valid for the latest value added,
so it's only returning the latest entry on the button click, i leave an example picture of the gui
as i hope this would help to clarify:
so if i add 2 different registration, 2 makes and 2 model and try and get the button search by regNo it only works with the latest entry not the previous one;
I leave the code for the setOnAction Method for the button
public void searchByReg(javafx.event.ActionEvent e) {
// clear the text field from the previous message
txtOutput.clear();
// get the car from the user through the car reg
String carReg = txtReg.getText();
// method to check if the field its empty
for (int i = 0; i < cars.size(); i++) {
if (carReg.equalsIgnoreCase(cars.get(i).getRegNo())) {
txtOutput.setText("You have selected \n" + cars.get(i));
carFound = true;
} else {
txtOutput.setText("That car is not in our Database");
}
}
}
Thank you for your help in Advance!!!
Try this, looks like you override text every time until last valid number.
txtOutput.setText("You have selected");
for (int i = 0; i < cars.size(); i++) {
if (carReg.equalsIgnoreCase(cars.get(i).getRegNo())) {
txtOutput.append("\n" + cars.get(i));
carFound = true;
}
}
if(!carFound) {
txtOutput.setText("That car is not in our Database");
}
This is not a JavaFX issue, but just a muddled-up search loop.
There's better ways to do this since Java 8. The following is much simpler and easier to read and debug:
public class LookupSample {
record Car(String name, String regNo) {
}
public static void main(String[] args) {
List<Car> cars = List.of(new Car("Mazda", "123"), new Car("Ford", "123"), new Car("Dodge", "789"));
String carReg = "123";
String result = cars.stream().filter(car -> car.regNo().equals(carReg)).map(Car::name).collect(Collectors.joining("\n\t ", "You have selected:\n\t", ""));
System.out.println(result);
boolean carFound = cars.stream().anyMatch(car -> car.regNo().equals(carReg));
System.out.println("Car Found? " + carFound);
}
}

Search for an object in arrayList Java

package generics;
import java.util.ArrayList;
import java.util.List;
public class Generics {
private static List <Box> newlist = new ArrayList<>();
public static void main(String[] args) {
newlist.add(new Box("charlie",30));
newlist.add(new Box("max",29));
newlist.add(new Box("john",22));
// Testing method find -- Start
find ("max",29);
//Testing method find2 -- Start
Box <String,Integer> search = new Box("max",29);
find2(search);
}
public static void find (String parameter, Integer parameter1){
for (Box e : newlist){
if(e.getName() != null && e.getMoney() !=null
&& e.getName().equals(parameter)
&& e.getMoney().equals(parameter1)){
System.out.println("found on position " + newlist.indexOf(e));
break;
}
}
}
public static void find2 (Box e){
for (Box a : newlist){
if (a.equals(e)){
System.out.println("Found");
}else {
System.out.println("Not found");
}
}
}
}
public class Box<T , D>{
private T name;
private D money;
public Box(T name, D money) {
this.name = name;
this.money = money;
}
public T getName() {
return name;
}
public D getMoney() {
return money;
}
#Override
public String toString() {
return name + " " + money;
}
}
Can someone show me how to search for an object in ArrayList.
Method find() it works perfect but in my opinion is wrong and
the reason why I am thinking like that, because I am passing as parameter a string and an integer but should be an box object or maybe I wrong?
In my second method find2() I am trying to pass as parameter an object of Box and when I am trying to search for it I got a false result =(
I am noobie I am trying to understand and to learn.
Stop using raw types!
Box is generic, so if you are not targeting older Java versions, always add generic parameters!.
The declaration of find2 should be like this:
public static void find2 (Box<String, Integer> e)
And you should check whether two boxes are equal in exactly the way you did in find. equals will not work because you did not define an equals method in Box. So:
for (Box<String, Integer> a : newlist){
if (a.getName().equals(e.getName()) &&
a.getMoney().equals(e.getMoney())){
System.out.println("Found");
}else {
System.out.println("Not found");
}
}
You should override Object.equals() on the Box class.
Try to handle null correctly too. Because 2 Box with null names and/or null money are in fact equal.
(you DON'T need to override Object.hashCode() for this, but it's a good practice to do so, just in case it is used in a hashmap or hashset or such).
The easiest way to search and find something in an arraylist is to use the .equals method combined with a for loop to iterate through your lists.
for(int i = 0; i < newList; ++i)
{
if(newlist.equals(Stringname))
{
//it matches so do something in here
}
}
what it is doing here is moving through the list 1 by 1 until it finds something that matches what you entered -> stringName

How can I turn my four perfect hash basic pseudocode methods into workable code?

I am trying to figure out how I can turn my 4 basic pseudocode methods inside of my perfect hash class into workable methods that will eventually be used inside of a main method of my PerfectHash class. I know I haven't created the instance of the class yet, but I will.
You know like when you call the 4 methods using a stack, for example, you input parameters inside the methods, but my application will be able to take the key that's entered by the user and insert, fetch, delete, or update on it inside of the structure.
Do I need to put more thought into these methods or is the pseudocode enough to work for now? Here's what I have done so far. I know the first class compiles fine, but I am having trouble with the second class as I have already indicated above.
public class PerfectHash
{
private StadiumTickets[] data;
public boolean insert(StadiumTickets newStadiumTicket)
{
// the direct insert hashed algorithm
pseudoKey = preProcessing(targetKey);
ip = pseudoKey; // direct hashing function
// insert the new ticket
data[ip] = newStadiumTicket.deepCopy();
}
public StadiumTickets fetch(String targetKey)
{
// the fetch algorithm
// access the primary storage area
pseudoKey = preprocessing(targetKey);
ip = pseudoKey; // direct hashing function
if(data[ip]== null)
{
return null;
}
else
{
return data[ip].deepCopy();
}
}
public boolean delete(String targetKey)
{
// the delete direct hashed algorithm
// access the primary storage area
pseudoKey = preprocessing(targetKey);
ip = pseudoKey; // direct hashing function
if(data[ip]== null)
{
return false;
}
else
{
data[ip]= null;
return true;
}
}
public boolean update(String targetKey, StadiumTickets newStadiumTicket)
{
// the update direct hashed algorithm
if(delete(targetKey) == false)
return false;
else
{
insert(newStadiumTicket)
return true;
}
}
}
import java.util.Scanner;
public class StadiumTickets
{
int ticketNumber; // keyfield
String purchaserName;
public void input()
{
Scanner input= new Scanner(System.in);
// key values ranges between 2000 to 100,000
System.out.print("Please enter a ticket number between 2000 to 100,000: ");
// a variable to hold the answer
ticketNumber= input.nextInt();
// error checking to make sure the user doesn't enter a key outside of the lower or upper ranges
if(ticketNumber < 2000 && ticketNumber > 100000)
System.out.println("This number is not a valid entry to input into the structure.");
}
public StadiumTickets(int ticketNumber, String purchaserName)
{
this.ticketNumber= ticketNumber;
this.purchaserName= purchaserName;
}
public StadiumTickets deepCopy()
{
StadiumTickets clone= new StadiumTickets(ticketNumber, purchaserName);
return clone;
}
}

I'm trying to search an ArrayList of objects for duplicates and if it doesnt exist add the new object

I have a Class called Subject which will store some information like a subject name and a subject code, I'm struggling because what I'm trying to do is make it loop through the list of records in the arraylist and add the new record if it doesn't already exist. Please help, Ive tried searching for an answer on here but haven't seem to be able to find it.
If looping is not the right thing to do please point me in the right direction.
Thanks
//The Class
public class Subject {
private String name;
private String subjectCode;
public Subject(){
}
public Subject(String name, String subjectCode){
this.name = name;
this.subjectCode = subjectCode;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public String getSubjectCode(){
return this.subjectCode;
}
public void setSubjectCode(String subjectCode){
this.subjectCode = subjectCode;
}
//The Main method
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ArrayList<Subject> subjectList = new ArrayList<>();
//Test records
subjectList.add(new Subject("Java 1", "ITC101"));
subjectList.add(new Subject("Java 2", "ITC201"));
subjectList.add(new Subject("Java 3", "ITC301"));
String newGetName;
String newSubjectCode;
do {
System.out.print("Enter Subject Name: ");
newGetName = input.nextLine();
System.out.print("Enter Subject Code: ");
newSubjectCode = input.nextLine();
for(int i = 0; i < subjectList.size(); i++){
if(!subjectList.get(i).getName().contains(newGetName) && !subjectList.get(i).getSubjectCode().contains(newSubjectCode)){
subjectList.add(new Subject(newGetName, newSubjectCode));
} else {
System.out.println("We have a match ");
}
}
} while(!"0".equals(newGetName));
}
You are declaring a "no match" too soon: you need to walk the whole list before adding a new subject.
Your program tries the first subject, and if ut does not match, it adds a subject, and moves on. Unfortunately, it does not break, so it keeps adding the same subject for each existing one that does not match.
In order to fix this problem make a boolean variable called "found", set it to false before the loop, and search for matches. Once a match is found, set the variable to true, and break.
After the loop check your variable. If it's true, do not add, and say that you found a duplicate. Otherwise, add the new subject.
in your case, you can not check for 'contains' you have to manually check every entry if its the same.
override the equal() function of your Subject:
public boolean equal(Object o){
Subject b = (Subject) o;
return (this.name.equal(b.name) && this.code.equal(b.code));
}
then in your loop:
boolean found = false;
for(Subject s : subjectList){
if(s.equal(newSubject)){
found = true;
break;
}
}
if(!found) //add new entry
If Subject implements equals(), then create the object and call subjectList.contains(subject). Better yet, implement hashCode() too and change the ArrayList to a HashSet (or LinkedHashSet if order is important) for better performance.
Otherwise, search like this (using equals(), not contains(), for string comparison):
boolean found = false;
for (Subject subject : subjectList)
if (subject.getName().equals(newGetName) && subject.getSubjectCode().equals(newSubjectCode)) {
found = true;
break;
}
if (found)
System.out.println("We have a match ");
else
subjectList.add(new Subject(newGetName, newSubjectCode));

Java Queues and Stacks

I have a small problem that I'm hoping someone could help me with.
This is an assignment, so I am not supposed to use classes imported from the java API nor am I supposed to do this in any other way (arraylist would have made this much easier.)
I created a Queue class and a Stack class.
I am trying to retrieve the head of the Queue, and add it to the Stack.
I am guessing I will need to create a method that somehow gets the value of the head of the list and stores it so I can use it.
For example, if I enqueued " bob", "jack", and "jill" to the Queue in that order, it will look like:
bob
jack
jill
I want to dequeue bob from the queue list, but add him to the head of the Stack list, but I can't figure out how. I'm sorry if my question is not very precise, I'm having problems wording what I really need. If any other information is needed I will update my post. Thanks for any help.
Here is my Queueclass:
(LL is my Link List class)
public class Queue<T extends Comparable<T>> {
LL<T> theQueue;
public Queue() {
theQueue = new LL<T>();
}
public boolean isEmpty() {
return theQueue.isEmpty();
}
public void enqueue(T value) {
theQueue.insertTail(value);
}
public T dequeue() throws QueueException {
T retval = null;
try {
retval=theQueue.deleteHead();
}catch (LLException e) {
throw new QueueException ("Queue is empty");
}
return retval;}
public String toString() {
return theQueue.toString();
}}
And my Stack Class:
public class Stack<T extends Comparable<T>>{
LL<T> theStack;
public Stack()
{
theStack = new LL<T>();
}
public boolean isEmpty()
{
return theStack.isEmpty();
}
public void push(T value)
{
theStack.insertHead(value);
}
public T pop() throws StackException
{
T retval = null;
try
{
retval = theStack.deleteHead();
}
catch (LLException e)
{
throw new StackException("Stack Underflow");
}
return retval;
}
public boolean isFull()
{
return false;
}
public String toStrin()
{
return theStack.toString();
}
Main Class:
public static void main(String[] args) {
Stack <String> hired = new Stack<String>();
Stack <String> fired = new Stack<String>();
Queue <String> apps = new Queue<String>();
String temp;
for (int i = 0; i < 1000; i++) {
System.out.println("Enter the number of the action to perform:");
System.out.println("1. Accept Application");
System.out.println("2. Hire");
System.out.println("3. Fire");
System.out.println("4. Exit");
Scanner kb = new Scanner(System.in);
int key = kb.nextInt();
switch (key) {
case 1:
System.out.println("Enter applicant's name and ID separated by semi-colon:");
String applicant = kb.next() + "\n";
System.out.println("You entered " + applicant);
apps.enqueue(applicant);
break;
case 2:
try{
temp = apps.dequeue();
} catch (QueueException s) {
}
try{ apps.dequeue(); }
catch (QueueException s){
System.out.println("Queue is empty");}
hired.push(temp);
case 3:
System.out.println();
case 4: System.out.println("Bye");
System.exit(0);
}
}
So it won't let me assign apps.dequeue() to temp without the try and catch. but then when I do hired.push(temp); I get an error saying temp may have not been initialized.
I think what you want to do is "To dequeue "bob" from the Queue and add it to the Stack", isn't it?
So I think you have already tell what to do:
Queue<String> q = new Queue<String>();
Stack<String> s = new Stack<String>();
// ... enqueue three strings
String temp = q.dequeue();
s.push(temp);
Yes - this task has nothing to do with the implementation of your Queue and Stack class. It's only about using the interface. As long as you have implemented them correctly, these code work.
EDIT
So maybe this is what you want:
String temp = ""; // explicitly initialize
try {
temp = q.dequeue();
s.push(temp);
} catch {
}
I put both dequeue and push in try block: if dequeue fails, nothing is to be pushed. Is this right for you ?
Use iterator (if you need to push value from a random position of queue into stack). For your assignment, simply dequeue method should work fine as pointed in another answer.
Before calling the dequeue method, call this iterator and check if hasNext(). if true, get the value using iterator.next() and store it.
Now you have the value in 'head' position. Now call dequeue method and delete the head value. Now simply push your stored value into stack

Categories