Searching object - java

I want to search object inside arraylist get value from user input and print it to text area. here is the code.
//the arrayList I declared
Book[]myBook = new Book [30];
int index = 0;
private void searchBtnActionPerformed(java.awt.event.ActionEvent evt) {
String title = titleTF.getText();
boolean found = false;
for (int i = 0; i < index; i++) {
if (myBook[i].getTitle().equals(title));
{
outputTA.append("Book Title : " + myBook[i].getTitle() + "\n");
outputTA.append("Book Author : " + myBook[i].getAuthor() + "\n");
outputTA.append("Year of Publication : " + myBook[i].getYear() + "\n");
outputTA.append("Book Status : " + myBook[i].getStatus() + "\n");
outputTA.append("======================================\n");
found = true;
break;
}
}
if (found == false) {
JOptionPane.showMessageDialog(this, "Book is not Found! Please Try again!");
}
}
The problem is, when I click the search button, it will display the first object in the arraylist. Which line of code is wrong?

First off, your index is 0 so your for doesn't loop. Replace index with myBook.size()

Related

Trying to run Else statement inside For Loop

I have a small issue with my application that I spotted when testing it. I have a println statement that should run to inform the user they have entered an invalid product code.
I have a for-loop that will run through an Array List of objects where an if statement will match each item in said Array List to a local variable named searchTerm.
The issue is that if the searchTerm does not match the item[0] with in the ArrayList then, the else statement will run more than once, thus executing the println statement multiple times.
static void searchProduct() {
System.out.print("Please enter product code to search: ");
String searchTerm = in.nextLine().toUpperCase();
for (int i = 0; i < report.size(); i++) {
if (report.get(i).code.equals(searchTerm)) {
System.out.println("****************************************************************************"
+ "\nPRODUCT SEARCH RESULTS"
+ "\n****************************************************************************");
System.out.println("PRODUCT CODE >> " + report.get(i).code);
System.out.println("PRODUCT NAME >> " + report.get(i).name);
System.out.println("PRODUCT CATERGORY >> " + report.get(i).category);
System.out.println("PRODUCT WARRANTY >> " + report.get(i).warranty);
System.out.println("PRODUCT PRICE >> " + report.get(i).price);
System.out.println("PRODUCT LEVEL >> " + report.get(i).stock);
System.out.println("PRODUCT SUPPLIER >> " + report.get(i).supplier);
System.out.println("****************************************************************************");
}
else {
// System.out.println("The product cannot be located. Invalid Product");
}
}
System.out.println("Enter (1) to launch menu or any other key to exit");
String opt2 = in.nextLine();
if (opt2.equals("1")) {
mainMenu.Menu();
}
else { System.exit(0); }
}
Separate out the printing from the looping:
Loop through the list until you find the item:
Report r = null;
for (int i = 0; i < report.size(); ++i) {
if (report.get(i).code.equals(searchTerm)) {
r = report.get(i);
break;
}
}
// or
for (Report rep : report) {
if (rep.code.equals(searchTerm)) {
r = rep;
break;
}
}
// or
Report r = report.stream().filter(rep -> rep.code.equals(searchTerm)).findFirst().orElse(null);
Now, r is only non-null if you found something, so, after the loop:
if (r != null) {
// Print stuff.
} else {
// Print message saying you didn't find it.
}
Use a boolean flag to detect if the product is found:
boolean found = false;
for (int i = 0; i < report.size(); i++) {
if (report.get(i).code.equals(searchTerm)) {
System.out.println("****************************************************************************"
+ "\nPRODUCT SEARCH RESULTS"
+ "\n****************************************************************************");
System.out.println("PRODUCT CODE >> " + report.get(i).code);
System.out.println("PRODUCT NAME >> " + report.get(i).name);
System.out.println("PRODUCT CATERGORY >> " + report.get(i).category);
System.out.println("PRODUCT WARRANTY >> " + report.get(i).warranty);
System.out.println("PRODUCT PRICE >> " + report.get(i).price);
System.out.println("PRODUCT LEVEL >> " + report.get(i).stock);
System.out.println("PRODUCT SUPPLIER >> " + report.get(i).supplier);
System.out.println("****************************************************************************");
found= true;
}
}
//end of the loop
if(!found) System.out.println("The product cannot be located. Invalid Product");
Switch the data structure used for searching the items in 'report' from a List to HashMap to avoid having to loop through all of them:
HashMap<String, Integer> quickSearchMapping;
quickSearchMapping = new HashMap<>();
for(int i=0 ; i<report.size ; i++ ){
quickSearchMapping.put(report.get(i).code, i);
}
while(TRUE){
System.out.print("Please enter product code to search: ");
String searchTerm = in.nextLine().toUpperCase();
if quickSearchMapping.containsKey(searchTerm){
Report the_report = report.get(quickSearchMapping.get(searchTerm));
//print to user stuff in the_report
break; //break if you wish to
} else {
System.out.println("Code entered didn't match any product.");
}
}

How to break out of a loop after an input has been checked against every item in an enum Java?

I'm trying to make a program that will allow the user to input either a name or symbol of an element from the periodic table, and will then output some data about that element. So far I've managed to get the user to be able to input either a name or a symbol and have it output correctly, but if the user inputs something wrong then the code doesn't output anything, and will stop accepting an input of a symbol and only accept an input of a name. I would like to know how I would be able to break out of the loop and tell a user that their input is invalid only after the input has been checked against every item in the enum, since my current solution doesn't work. I'm new to Java, so a simple explanation as to how and why would be greatly appreciated.
import java.util.Scanner;
public class PeriodicTable {
public enum Element {
Hydrogen("H", "Nonmetal", "1.008"),
Helium("He", "Noble Gas", "4.003"),
Lithium("Li", "Alkali Metal", "6.941"),
Beryllium("Be", "Alkaline Earth", "9.012"),
Boron("B", "Semimetal", "10.811"),
Carbon("C", "Nonmetal", "12.011"),
//The rest of the periodic table is here, I just removed it for the sake of this post.
private String symbol;
private String group;
private String weight;
private Element(String symbol, String group, String weight) {
this.symbol = symbol;
this.group = group;
this.weight = weight;
}
}
static Element cName = null;
public static void main(String[] args) {
int counter = 0;
System.out.println("Enter the name or symbol of an element in the periodic table. ");
outer:
do {
Scanner reader = new Scanner(System.in);
String input = reader.nextLine().trim();
for (Element sy : Element.values()) {
if (sy.symbol.equalsIgnoreCase(input)) {
System.out.println("Element: " + sy + " (" + sy.symbol + ")" + "\nGroup: " + sy.group + "\nAtomic Mass: " + sy.weight);
reader.close();
break outer;
} else {
try {
cName = Element.valueOf(input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase());
System.out.println("Element: " + cName + " (" + cName.symbol + ")" + "\nGroup: " + cName.group + "\nAtomic Mass: " + cName.weight);
reader.close();
break outer;
} catch(IllegalArgumentException e) {
if(counter > Element.values().length) {
System.out.println("That name or symbol is not valid. Please try again. ");
continue outer;
} else {
counter++;
continue;
}
}
}
}
} while (true);
}
}
I would avoid using the valueOf method in a loop. Instead, you can iterate over the elements and for each element check both its name (use the name method) and its symbol.
Scanner reader = new Scanner(System.in);
outer: while (true) {
System.out.println("Enter the name or symbol of an element in the periodic table. ");
String input = reader.nextLine().trim();
for (Element sy : Element.values()) {
if (sy.symbol.equalsIgnoreCase(input) || sy.name().equalsIgnoreCase(input)) {
System.out.println("Element: " + sy + " (" + sy.symbol + ")" + "\nGroup: " + sy.group + "\nAtomic Mass: " + sy.weight);
break outer;
}
}
System.out.println("No such element found. ");
}
reader.close(); // this might be a bad idea
I would also avoid closing the reader, as this will also close System.in and you will be unable to read any more input.
Assuming I understand your question, I would add the logic for parsing Element(s) to Element. You can create Map(s), one to symbol and one of name to corresponding Element instances and then invoke them in whichever order you choose. Like,
private static Map<String, Element> symbolMap = new HashMap<>();
private static Map<String, Element> nameMap = new HashMap<>();
static {
for (Element e : Element.values()) {
symbolMap.put(e.symbol.toUpperCase(), e);
nameMap.put(e.name().toUpperCase(), e);
}
}
public static Element fromString(String token) {
if (symbolMap.containsKey(token.toUpperCase())) {
return symbolMap.get(token.toUpperCase());
}
return nameMap.get(token.toUpperCase());
}
Then in main
Element e = Element.fromString("H");
Element e2 = Element.fromString("Hydrogen");
System.out.println(e == e2); // <-- true
And if e were null then it isn't a valid symbol (or name).
If I have understood correctly, you want to go through the enums and see if any of the symbols match the user input. If not, print a message and try again. You had the right approach, but in the catch block you don't need to make a counter. Instead if we think through the design, you have break outer; if the input ever matches. So the end of the do-while loop will only be reached if there is no matching element. So if we just print a message at the end, this will accomplish our goal:
outer:
do {
Scanner reader = new Scanner(System.in);
String input = reader.nextLine().trim();
for (Element sy : Element.values()) {
if (sy.symbol.equalsIgnoreCase(input)) {
System.out.println("Element: " + sy + " (" + sy.symbol + ")" + "\nGroup: " + sy.group + "\nAtomic Mass: " + sy.weight);
reader.close();
break outer;
} else {
try {
cName = Element.valueOf(input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase());
System.out.println("Element: " + cName + " (" + cName.symbol + ")" + "\nGroup: " + cName.group + "\nAtomic Mass: " + cName.weight);
reader.close();
break outer;
} catch(IllegalArgumentException e) {
continue;
}
}
}
System.out.println("Error. No matching elements. Please try again.");
} while (true);
Sample Output:
Enter the name or symbol of an element in the periodic table.
No
Error. No matching elements. Please try again.
l
Error. No matching elements. Please try again.
He
Element: Helium (He)
Group: Noble Gas
Atomic Mass: 4.003
You complicate the code by mixing the search for the name and the search for the symbol. The search for the name does not need to be inside the for loop:
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("Enter the name or symbol of an element in the periodic table. ");
boolean found = false;
do {
String input = reader.nextLine().trim();
try {
cName = Element.valueOf(input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase());
System.out.println("Element: " + cName + " (" + cName.symbol + ")" + "\nGroup: " + cName.group + "\nAtomic Mass: " + cName.weight);
found = true;
} catch (IllegalArgumentException e) {
}
for (Element sy : Element.values()) {
if (sy.symbol.equalsIgnoreCase(input)) {
found = true;
System.out.println("Element: " + sy + " (" + sy.symbol + ")" + "\nGroup: " + sy.group + "\nAtomic Mass: " + sy.weight);
}
}
if (!found)
System.out.println("That name or symbol is not valid. Please try again. ");
} while (!found);
reader.close();
}

Updated output is concatenating with old output

Can anyone figure out why after removing a found value, the output includes all the information from before the remove?
// Prints current items in both arrays
String titles = "";
String lengths = "";
for (int i = 0; i < numOfSongs; i++) {
titles += songTitles[i] + " ";
lengths += songLengths[i] + " ";
}
JOptionPane.showMessageDialog(null, "**Current Playlist**" + "\nSong titles: " + titles + "\nSong lengths: " + lengths);
// Determines if the user wants to remove a song from the current list
boolean found = false;
// If search matches a song in array, set title to null and length to 0
for (int i = 0; i < songTitles.length; i++) {
if (search.equalsIgnoreCase(songTitles[i])) {
found = true;
songTitles[i] = null;
songLengths[i] = 0;
}
}
// Update arrays, song count, and duration across all songs
if (found) {
titles += songTitles[numOfSongs] + " ";
lengths += songLengths[numOfSongs] + " ";
totalDuration -= songLengths[numOfSongs];
numOfSongs--;
}
// Print updated playlist
JOptionPane.showMessageDialog(null, "**Current Playlist**" + "\nSong titles: " + titles + "\nSong lengths: " + lengths);
titles and totalDuration strings are initialized with all the elements in songTitles and songLengths.
If you find search in songTitles you remove it from songTitles but you don't update songTitles. Instead you append on more song title from songTitles.
You probably want to clear songTitles and songLengths and recreate them skipping null values in songTitles. E.g.
titles = "";
lengths = "";
for (int i = 0; i < numOfSongs; i++) {
if (songTitles[i] != null) {
titles += songTitles[i] + " ";
lengths += songLengths[i] + " ";
}
}
Also consider creating your strings like this (Java 8)
String titles = String.join(" ", songTitles);
String lengths = String.join(" ", songLengths);
Below statements are causing to concatenate with old values.
titles += songTitles[numOfSongs] + " ";
lengths += songLengths[numOfSongs] + " ";
You should first clear the existing values by setting strings empty before adding a new value.
titles = "";
lengths = "";

For each loop in Java with word count

I have a long text which is stored in a String (i.e. tstr1 im code). Now I want to store the user input from console in a String[] (i.e. itemsFromArray im code).
I want for each word stored in the user input String[] array, the system to show how many times that word is present in the long Text String[] array. I tried in this way, but the problem is that the system shows the count just for first entry from an array but for the next it is showing zero.
btnNewButton.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
keyW = txtKeyword.getText();
search = textField.getText();
System.out.println("String for car = " + search);
System.out.println("String keyword = " + keyW);
WebDriver driver = new FirefoxDriver();
driver.get("https://en.wikipedia.org/wiki/" + search);
tstr1 = driver.findElement(By.xpath("//*[#id='content']")).getText();
String [] itemsFromArray = keyW.split(",");
Map<String, Integer> map = new HashMap<String, Integer>();
for (String word : itemsFromArray){
map.put(word, 0);
}
Scanner s = new Scanner(tstr1);
while (s.hasNext()){
String word = s.next();
if (map.containsKey(word)){
map.put(word, map.get(word) + 1);
System.out.println("Word1 '" + word + "' count:" + map.get(word));
} else {
System.out.println("Word2 '" + word + "' not in map");
}
}
driver.close();
}
});
It's probably better to use a Map<String, Integer>:
// initialize a mapping that is used to map words to their count
Map<String, Integer> counter = new HashMap<String, Integer>();
// initialize all counts to 0
for (String word : itemsFromArray){
counter.put(word, 0);
}
// ...
// count words that are in map (give up those that aren't)
while (s.hasNext()){
String word = s.next();
if (counter.containsKey(word)){
counter.put(word, counter.get(word) + 1);
System.output.println("Word '" + word + "' count:" + counter.get(word));
} else {
System.output.println("Word '" + word + "' not in map");
}
}
After I spent one day, the problem was that when I tried to separate the string (without comma) and insert into array, the first string was good but the next started with white spaces and the system does not recognize the word.
btnNewButton.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//If the button UPLOAD was not pressed we should to clear the ArrayList
listKeys.clear();
//////////////////////////////////////////////
if(textField.getText().equals("")) {
JOptionPane.showMessageDialog(null,"Make sure you enter at least one search key");
}
else if (txtKeyword.getText().equals("")) {
System.out.println("String is NULL ");
JOptionPane.showMessageDialog(null,"Add at least one keyword");
} else {
keyW = txtKeyword.getText();
search = textField.getText();
System.out.println("String for car = " + search);
System.out.println("String keyword = " + keyW);
WebDriver driver = new FirefoxDriver();
driver.get("https://en.wikipedia.org/wiki/" + search);
tstr1 = driver.findElement(By.xpath("//*[#id='content']")).getText();
String [] items = keyW.split(",");
String [] itemsFromArray = new String[items.length];
for ( int i = 0; i < items.length; i++)
{
itemsFromArray[i] = items[i].trim();
}
for(String string : itemsFromArray)
{
//if (args[i].toLowerCase().startsWith(­ "from:" ))
System.out.println("FOREACH " + string);
int i = countWords(tstr1, string);
System.out.println("Word count "+ string + ": " + i);
Keyword1 = ("Count for word " + string + " are " + i);
listKeys.add(Keyword1);
}
driver.close();
}
}
private static int countWords(String tstr1, String string)
{
int i = 0;
Scanner s = new Scanner(tstr1);
while (s.hasNext())
{
if (s.next().equals(string))
i++;
}
return i;
}
}

Deleting a String of data from Array List

I have been creating a program that is to add search delete bookings etc...
After hours I finally thought I was making progress but when I delete a booking my program finds the correct booking returns the correct information for that booking but deletes a different booking.
I have attached the files in a zip as if I displayed them they would take up lots of screen space. The program has been made in BlueJay.
Code for decleration and adding of objects into my array list
public Hostel(String hostelName)
{
this.hostelName = "Newcastle Hostel";
bookings = new ArrayList<Booking>();
}
public String getHostelName()
{
return hostelName;
}
public String addBooking(String roomID, String roomType, String guest)
{
if (roomID.equals(""))
return "Error Please Entre Room ID";
else if (roomType.equals(""))
return "Error Please Entre Room Type";
else if (guest.equals(""))
return "Error Please Entre Guest Name";
bookings.add(new Booking(roomID,roomType,guest));
return "Room " + roomID + " " + roomType + " Has Been Booked For " + guest;
}
This is taken from my hostel class
public String deleteBooking(String roomID)
{
int index = 0;
for ( Booking s : bookings )
{
if ( s.getRoomID().equals(roomID))
{
//return "Room ID: " + roomID + " Room Type: " + s.getRoomType() + " Guest: " + s.getGuest();
String deleteMessage = "Room ID: " + roomID + " Room Type: " + s.getRoomType() + " Guest: " + s.getGuest();
int response = JOptionPane.showConfirmDialog(null, deleteMessage, "Confirm Delete",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (response == JOptionPane.NO_OPTION)
{
} else if (response == JOptionPane.YES_OPTION)
{
bookings.remove(index);
}
index++;
}
}
return " Cannot find room";
}
this is taken from my GUI class
else if (item.equals("Cancel Booking"))
{
newBookingButton.setEnabled(false);
cancelBookingButton.setEnabled(false);
String roomID = JOptionPane.showInputDialog(this, "Enter a room ID", "Delete a Booking", JOptionPane.QUESTION_MESSAGE);
output.setText(hostel.deleteBooking(roomID));
newBookingButton.setEnabled(true);
cancelBookingButton.setEnabled(true);
}
Any additonal code needed either ask or there is a full copy in the link above thanks
Your loop only increments the index if the room ID of the current room is equal to the ID of the room to delete. The line
index++;
should be out of the if block.
EDIT:
The other problem is that you're trying to remove elements a collection while iterating on it. This is only possible if you use an Iterator to iterate over the collection, and use the iterator's remove method to remove the current element. Note that even if it was possible, since you remove the element at the given index, the index should not be incremented since you have just removed the element at this index.
Example of using an iterator:
for (Iterator<Booking> it = bookings.iterator(); it.hasNext(); ) {
Booking b = it.next();
if (...) {
it.remove();
}
}
Basically when s.getRoomID().equals(roomID) is true your if block is executed so no matter what is the response of the user your index is incremented. So, do this:
if ( s.getRoomID().equals(roomID))
{
//your code
}
index++
I just looked into your code, and seems like you are trying to iterate over a collection and also modifying the values at the same time. With enhanced for loop, such things do give errors, so instead of using the enhanced for loop, you must use a normal for loop. So I had modified your deleteBookings Method for the respective change.
public String deleteBooking(String roomID)
{
//for ( Booking s : bookings )
for (int i = 0; i < bookings.size(); i++)
{
Booking s = bookings.get(i);
if ( s.getRoomID().equals(roomID))
{
//return "Room ID: " + roomID + " Room Type: " + s.getRoomType() + " Guest: " + s.getGuest();
String deleteMessage = "Room ID: " + roomID + " Room Type: " + s.getRoomType() + " Guest: " + s.getGuest();
//int r = JOptionPane.showOptionDialog,null("Are you sure you would like to delete the following \n"
//+ "deleteMessage",
//"Delete a booking",
//JOptionPane.YES_NO_OPTION,
//JOptionPane.QUESTION_MESSAGE,null,null,null);
//if (r == JOptionPane.YES_OPTION) {
// bookings.remove(index);
//}
//if (r == JOptionPane.NO_OPTION){
// return "Booking Was Not Canceled";
// }
int response = JOptionPane.showConfirmDialog(null, deleteMessage, "Confirm Delete",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (response == JOptionPane.NO_OPTION)
{
} else if (response == JOptionPane.YES_OPTION)
{
//bookings.remove(index);
bookings.remove(i);
return deleteMessage + " has been DELETED."; /*I did this.*/
}
}
}
return " Cannot find room";
}
Moreover, after this
bookings.remove(i);
You forgot to return something like
return deleteMessage + " has been DELETED."; /*I did this.*/
Since you failed to return a String on successful completion, that's the reason why it returns "Cannot find room.", even after successful deletion.
Rest of the code is perfect.
Hope that might solve your query.
Regards

Categories

Resources