2D String search in Java - java

This is my code:
import java.util.*;
import java.util.Arrays;
public class PhoneNumbers
{
static Scanner scan = new Scanner(System.in);
public static void main(String[] args)
{
String phoneList[][] =
{
{"Harrison, Rose: ", "James, Jean: ", "Smith, William: ", "Smith, Brad: "},
{"415-555-2234", "415-555-9098", "415-555-1785", "415-555-9224"}
};
System.out.println(Arrays.deepToString(phoneList)); //this line is to make sure the 2D arrays work
String input;
System.out.print("Enter the first few letters of a last name to search for: ");
input = scan.nextLine();
int match = -1;
for(int i = 0; i < phoneList.length; i++)
{
if(phoneList[i].indexOf(input))
{
System.out.println(phoneList[i]);
match = i;
break;
}
else
System.out.println("There is no match.");
}
}
}
My goal is:
I have a 2D array, i got name in one and the phone number in another.
I am trying to allow user to enter first few letters of a last name and do a search that and display the matching search along with the phone number(this would be my next challenge).
Thank you,

Here is your Answer :
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
int refNumber=-1;
String phoneList[][] =
{
{"Harrison, Rose: ", "James, Jean: ", "Smith, William: ", "Smith, Brad: "},
{"415-555-2234", "415-555-9098", "415-555-1785", "415-555-9224"}
};
Scanner scanner = new Scanner(System.in);
System.out.print("Enter String to be searched ->");
String input = scanner.nextLine();
//System.out.println(input);
for (int i=0; i<phoneList[0].length; i++) {
if (phoneList[0][i].contains(input)) {
refNumber = i;
}
}
System.out.println("Name ->"+phoneList[0][refNumber]);
System.out.println("Phone No ->"+phoneList[1][refNumber]);
}
}

Create a dictionary (e.g. trie tree) for all the names you have. While creating/updating your search dictionary, at each node, keep an integer array which gives you the list of index of all the matching names. As the user provides input, you can keep on refining the result at runtime, and when he selects any one of the provided suggestions, you'll have the index to it.
Rest is simple, using that index, display the phone number of the selected person.

I did some refactoring:
using a Map: name => phone
public static void main(String[] args)
{
String phoneList[][] =
{
{"Harrison, Rose: ", "James, Jean: ", "Smith, William: ", "Smith, Brad: "},
{"415-555-2234", "415-555-9098", "415-555-1785", "415-555-9224"}
};
// Make a Map
Map<String,String> mss=new HashMap<String,String>();
for(int i = 0; i < phoneList.length; i++)
mss.put(phoneList[0][i], phoneList[1][i]) ;
String input;
System.out.print("Enter the first few letters of a last name to search for: ");
Scanner scan = new Scanner(System.in);
input = scan.nextLine();
String match="";
for (String name: mss.keySet())
if (name.startsWith(input))
{
System.out.println("NAME:"+name+ " PHONE:"+mss.get(name));
match=name;
break;
}
if (match.equals(""))
System.out.println("There is no match.");
}

One simple approach is to match the beginning of the input String:
for(int x=0; x<phoneList[1].length; x++)
if(phoneList[0][x].toLowerCase().startsWith(input.toLowerCase()))
System.out.println("Numbers which matched: " + phoneList[1][x]);
Program output:
//Using "smith" as input:
Numbers which matched: 415-555-1785
Numbers which matched: 415-555-9224

Related

How to check user input is part of the array in Java

I wanna ask if this is possible. So I have this program will enter a for loop to get the user input on number of subjects. Then after he will enter the subjects listed in the array as his guide. My goal is that I want to check his subjects if it is really inside the array that I made. I made a program but I don't know where to put the part that the program will check the contents.
My goal:
Enter the corresponding code for the subjects you have chosen: user will input 8
Enter the number of subjects you wish to enroll: be able to type the whole subject name like (MATH6100) Calculus 1
then the program will check if the subjects entered are part of the elements inside the array
UPDATE:
I have made another but the problem is that I don't know where to put the code fragment wherein it will check the contents of the user input for list of subjects he wish to enroll.
Here is the code:
private static void check(String[] arr, String toCheckValue){
boolean test=Arrays.asList(arr).contains(toCheckValue);
System.out.println("Is/Are " + toCheckValue + " present in the array: " + test);
}
public static void main(String[] args){
String arr[]={"(MATH6100) Calculus 1", "(ITE6101) Computer Fundamentals", "(ITE6102) Computer Programming 1", "(GE6100) Understanding the Self", "(GE6106) Purposive Comunication 1", "(ETHNS6101) Euthenics 1", "(PHYED6101) Physical Fitness", "(NSTP6101) National Service Training Program 1"};
Scanner input1=new Scanner(System.in);
System.out.print("\nEnter the number of subjects you wish to enroll: ");
int number_subjects1=input1.nextInt();
String []subjects1=new String[number_subjects1];
//else statement when user exceeds the number of possible number of subjects
if(number_subjects1<=8){
for(int counter=0; counter<number_subjects1; counter++){
System.out.println("Enter the corresponding code for the subjects you have chosen (EX. MATH6100): " + (counter+1));
subjects1[counter]=input1.next();
}
String toCheckValue=subjects1[0];
System.out.println("Array: " +Arrays.toString(arr));
check(arr, toCheckValue);
System.out.println("\nPlease check if these are your preferred subjects:");
for(int counter=0; counter<number_subjects1; counter++){
System.out.println(subjects1[counter]);
}System.out.println("********************************** \n" + "\tNothing Follows");
System.out.print("\nIf you have enter some errors please press Y and refresh the form (Y/N): ");
Scanner character=new Scanner(System.in);
String answer_1subjectserrors=character.nextLine();
System.out.println(answer_1subjectserrors + "Based on your answer, you need to refresh thae page and try again.");
}
}
}
I believe the issue is that you are checking your class course codes against an array which contains both the class code AND the class description.
You ask the user to enter the class code but then you use that code to check for its existence in an array containing both the code & description. The contains in List (collections) is not the same as the contains in String.
I have slightly modified your code so you may get the desired result.
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SOQuestion {
private static void check(String[] arr, String toCheckValue){
List courses = Arrays.asList(arr);
boolean test=courses.contains(toCheckValue);;
System.out.println("Is/Are " + toCheckValue + " present in the array: " + test);
}
public static void main(String[] args) {
String class_codes_and_descriptions[] = { "(MATH6100) Calculus 1", "(ITE6101) Computer Fundamentals", "(ITE6102) Computer Programming 1",
"(GE6100) Understanding the Self", "(GE6106) Purposive Comunication 1", "(ETHNS6101) Euthenics 1",
"(PHYED6101) Physical Fitness", "(NSTP6101) National Service Training Program 1" };
String class_codes[] = { "MATH6100", "ITE6101", "ITE6102","GE6100", "GE6106", "ETHNS6101","PHYED6101", "NSTP6101" };
Scanner input1 = new Scanner(System.in);
System.out.print("\nEnter the number of subjects you wish to enroll: ");
int number_subjects1 = input1.nextInt();
String[] subjects1 = new String[number_subjects1];
// else statement when user exceeds the number of possible number of subjects
if (number_subjects1 <= 8) {
for (int counter = 0; counter < number_subjects1; counter++) {
System.out.println("Enter the corresponding code for the subjects you have chosen (EX. MATH6100): "
+ (counter + 1));
subjects1[counter] = input1.next();
}
String toCheckValue = subjects1[0];
System.out.println("Array: " + Arrays.toString(class_codes_and_descriptions));
check(class_codes, toCheckValue);
System.out.println("\nPlease check if these are your preferred subjects:");
for (int counter = 0; counter < number_subjects1; counter++) {
System.out.println(subjects1[counter]);
}
System.out.println("********************************** \n" + "\tNothing Follows");
System.out.print("\nIf you have enter some errors please press Y and refresh the form (Y/N): ");
Scanner character = new Scanner(System.in);
String answer_1subjectserrors = character.nextLine();
System.out.println(
answer_1subjectserrors + "Based on your answer, you need to refresh the page and try again.");
}
}
}
When you are debugging always try to break down the statements into steps so you know where the error is. For example instead of boolean test=Arrays.asList(arr).contains(toCheckValue);
break it down to two steps like this :
List courses = Arrays.asList(arr);
boolean test=courses.contains(toCheckValue);
That way you will have an easier time checking for issues.
Second request is to always look at the API. Skim over the API to look at the method that you are using to understand it better.
For example if you are using contains method of List then look up the API here:
https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/List.html#contains(java.lang.Object)
Of course since this is Oracle's Java the explanation is imprecise & not straightforward but it is usually helpful.
I would recommend using a different data structure than plain arrays. Since you are already using List why not use another collections data structure like HashMap?
The original poster may want to look at a slightly refactored and cleaned up version of the code & try to figure out how to check for all courses since that is his next question. I believe that should become obvious with a more refactored code:
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SOQuestion {
public static String class_codes_and_descriptions[] = { "(MATH6100) Calculus 1", "(ITE6101) Computer Fundamentals", "(ITE6102) Computer Programming 1",
"(GE6100) Understanding the Self", "(GE6106) Purposive Comunication 1", "(ETHNS6101) Euthenics 1",
"(PHYED6101) Physical Fitness", "(NSTP6101) National Service Training Program 1" };
public static String class_codes[] = { "MATH6100", "ITE6101", "ITE6102","GE6100", "GE6106", "ETHNS6101","PHYED6101", "NSTP6101" };
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int desired_number_of_subjects = input_desired_number_of_subjects(input);
String[] desired_subjects = enter_subjects(desired_number_of_subjects, input);
String toCheckValue = desired_subjects[0];
System.out.println("Array: " + Arrays.toString(class_codes_and_descriptions));
check(class_codes, toCheckValue);
pls_confirm_desired_subjects(desired_number_of_subjects, desired_subjects);
System.out.println("********************************** \n" + "\tNothing Follows");
System.out.print("\nIf you have enter some errors please press Y and refresh the form (Y/N): ");
Scanner character = new Scanner(System.in);
String answer_1subjectserrors = character.nextLine();
System.out.println(
answer_1subjectserrors + "Based on your answer, you need to refresh the page and try again.");
}
private static int input_desired_number_of_subjects(Scanner input) {
System.out.print("\nEnter the number of subjects you wish to enroll: ");
int take_number_of_subjects = input.nextInt();
// TODO: else statement when user exceeds the number of possible number of subjects
return take_number_of_subjects;
}
private static String[] enter_subjects(int desired_subjects_count , Scanner input_desired_subjects) {
String[] subjects_totake = new String[desired_subjects_count];
if (desired_subjects_count <= 8) {
for (int counter = 0; counter < desired_subjects_count; counter++) {
System.out.println("Enter the corresponding code for the subjects you have chosen (EX. MATH6100): "
+ (counter + 1));
subjects_totake[counter] = input_desired_subjects.next();
}
}
return subjects_totake;
}
private static void check(String[] arr, String toCheckValue){
List courses = Arrays.asList(arr);
boolean test=courses.contains(toCheckValue);
System.out.println("Is/Are " + toCheckValue + " present in the array: " + test);
}
private static void pls_confirm_desired_subjects(int take_number_of_subjects, String[] take_subjects) {
System.out.println("\nPlease check if these are your preferred subjects:");
for (int counter = 0; counter < take_number_of_subjects; counter++) {
System.out.println(take_subjects[counter]);
}
}
}
I will shortly edit the above but a hint is : you can use a for loop to go over the entered desired_subjects array and do a check on each one of the subjects, perhaps?
The following checks for all the courses (though this is not how I would check the courses)
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SOQuestion {
public static String class_codes_and_descriptions[] = { "(MATH6100) Calculus 1", "(ITE6101) Computer Fundamentals", "(ITE6102) Computer Programming 1",
"(GE6100) Understanding the Self", "(GE6106) Purposive Comunication 1", "(ETHNS6101) Euthenics 1",
"(PHYED6101) Physical Fitness", "(NSTP6101) National Service Training Program 1" };
public static String class_codes[] = { "MATH6100", "ITE6101", "ITE6102","GE6100", "GE6106", "ETHNS6101","PHYED6101", "NSTP6101" };
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int desired_number_of_subjects = input_desired_number_of_subjects(input);
String[] desired_subjects = enter_subjects(desired_number_of_subjects, input);
check_all_desired_subjects(desired_subjects);
pls_confirm_desired_subjects(desired_number_of_subjects, desired_subjects);
System.out.println("********************************** \n" + "\tNothing Follows");
System.out.print("\nIf you have enter some errors please press Y and refresh the form (Y/N): ");
Scanner character = new Scanner(System.in);
String answer_1subjectserrors = character.nextLine();
System.out.println(
answer_1subjectserrors + "Based on your answer, you need to refresh the page and try again.");
}
private static int input_desired_number_of_subjects(Scanner input) {
System.out.print("\nEnter the number of subjects you wish to enroll: ");
int take_number_of_subjects = input.nextInt();
// TODO: else statement when user exceeds the number of possible number of subjects
return take_number_of_subjects;
}
private static String[] enter_subjects(int desired_subjects_count , Scanner input_desired_subjects) {
String[] subjects_totake = new String[desired_subjects_count];
if (desired_subjects_count <= 8) {
for (int counter = 0; counter < desired_subjects_count; counter++) {
System.out.println("Enter the corresponding code for the subjects you have chosen (EX. MATH6100): "
+ (counter + 1));
subjects_totake[counter] = input_desired_subjects.next();
}
}
return subjects_totake;
}
private static void check_all_desired_subjects(String[] desired_subjects) {
System.out.println("Array: " + Arrays.toString(class_codes_and_descriptions));
for (String subject_code_to_check:desired_subjects ) {
check(class_codes, subject_code_to_check);
}
}
private static void check(String[] arr, String toCheckValue){
List courses = Arrays.asList(arr);
boolean test=courses.contains(toCheckValue);
System.out.println("Is/Are " + toCheckValue + " present in the array: " + test);
}
private static void pls_confirm_desired_subjects(int take_number_of_subjects, String[] take_subjects) {
System.out.println("\nPlease check if these are your preferred subjects:");
for (int counter = 0; counter < take_number_of_subjects; counter++) {
System.out.println(take_subjects[counter]);
}
}
}

How to stop on duplicate entry (Java)

I have a simple code that asks a user to input items and stores them into an array. I would like to make it so the program stops running when the last entry is the same as the first.
so for example this would stop the program because Cookie it both the first item in the array and the last. But it's also ok to have duplicates with in the array like "Sugar" in this example:
Enter the item: Cookie
Enter the item: Sugar
Enter the item: Milk
Enter the item: Sugar
Enter the item: Salt
Enter the item: Cookie
Main.java
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
//Decide the number of items
int numOfItems = 20;
//Create a string array to store the names of your items
String arrayOfNames[] = new String[numOfItems];
for (int i = 0; i < arrayOfNames.length; i++) {
System.out.print("Enter Item " + (i+1) + " : ");
arrayOfNames[i] = scan.nextLine();
}
//Now show your items's name one by one
for (int i = 0; i < arrayOfNames.length; i++) {
System.out.print("Item # " + (i+1) + " : ");
System.out.print(arrayOfNames[i] + "\n");
}
}
}
Thanks for your help
You can do this by adding a simple if-condition with equals() method. you need do add following if-condition.
if(Temp.equals(arrayOfNames[0])) // readed Temp equals to first element.
Try this code:-
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
//Decide the number of items
int numOfItems = 20,maxItems=0; // total items may vary
//Create a string array to store the names of your items
String arrayOfNames[] = new String[numOfItems];
String Temp=""; // for temporary storage
for (int i = 0; i < arrayOfNames.length; i++) {
System.out.print("Enter Item " + (i+1) + " : ");
Temp= scan.nextLine();
if(Temp.equals(arrayOfNames[0])){
maxItems=i;
break;
}
else{
arrayOfNames[i]=Temp;
}
}
//Now show your items's name one by one
for (int i = 0; i < maxItems; i++) {
System.out.print("Item # " + (i+1) + " : ");
System.out.print(arrayOfNames[i] + "\n");
}
}
}
Output :-
Enter Item 1 : Cookie
Enter Item 2 : Sugar
Enter Item 3 : milk
Enter Item 4 : Sugar
Enter Item 5 : Salt
Enter Item 6 : Cookie
Item # 1 : Cookie
Item # 2 : Sugar
Item # 3 : milk
Item # 4 : Sugar
Item # 5 : Salt
If you don't know the number of items will be entered by the user then this code will be helpful,
import java.util.*;
public class MyClass {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
Scanner sc = new Scanner(System.in);
while(true)
{
System.out.print("Enter name:");
String temp = sc.next();
if(al.isEmpty() != true)
{
if(temp.equals(al.get(0)))
break;
}
al.add(temp);
}
for(int i = 0;i<al.size();i++)
{
System.out.println(al.get(i));
}
}
}
More sophisticated OO Program Example:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Grocery {
List<String> basket; // list of items in the basket
//constructor of Grocery with number of items provided
public Grocery(int numberOfItems) {
basket = new ArrayList<>(numberOfItems); // initialize basket
}
/**
* Add item to basket only if it is not similar to the first item
* return true if succeeded otherwise return false if it's duplicate
* #param item
* #return
*/
public boolean addItem(String item) {
if(basket.size()==0) return basket.add(item);
if(!basket.get(0).equals(item)) {
return basket.add(item);
}
return false;
}
/**
* Remove specific item in the basket
* or all items by name if "all" is true
* #param item
*/
public void removeItem(String item, boolean all) {
if(all) {
for(String i : basket) {
if(i.equals(item)) {
basket.remove(i);
}
}
}else {
basket.remove(item);
}
}
// method to empty the basket
public void emptyBasket() {
basket.clear();
}
/**
* Override toString() to provide your own
* textual representation of the basket
*/
#Override
public String toString() {
String s = "";
for(int i=0; i<basket.size(); i++) {
s += "Item #" + (i+1) + " : " + basket.get(i) + "\n";
}
return s;
}
// TEST
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//Decide the number of items
int numOfItems=0;
System.out.print("Enter How Many Items: ");
try {
numOfItems = Integer.parseInt(scan.nextLine().trim());
}catch(NumberFormatException e) {
System.out.print("Number of items you entered is invalid!");
System.exit(0);
}
Grocery grocery = new Grocery(numOfItems);
for (int i = 0; i < numOfItems; i++) {
System.out.print("Enter Item " + (i+1) + " : ");
if(!grocery.addItem(scan.nextLine())) {
System.out.println("First Item Duplicate Detected!");
//break;
System.exit(0);
};
}
scan.close();
System.out.println(grocery.toString());
}
}
Test
Sounds to me like you should be able to do a if statement in here to find out if array[0] = array[i]
if (i > 0 && (arrayOfNames[0] == arrayOfNames[i])) {
// do something
}
Simply add a condition that if the current element matches first element, then break out of the for loop.
String first=null;
for (int i = 0; i < arrayOfNames.length; i++) {
System.out.print("Enter Item " + (i+1) + " : ");
arrayOfNames[i] = scan.nextLine();
if (i==0){
first=arrayOfNames[i];
}else{
if(first==arrayOfNames[i]){break;}
}
}
Just change your for loop condition to:
for (int i = 0; i == 0 || arrayOfNames[i] != arrayOfNames[0]; i++)

Need some help retrieving data from a parallel array / output statement

package statescapitalquizz;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
*
* #author Steve
*/
public class Statescapitalquizz {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String fileName = "Capitals.txt";
boolean found = false;
Scanner kb = new Scanner(System.in);
String target;
int n = 50;
String[] states = new String[n];
String[] capitals = new String[n];
try (Scanner inputStream = new Scanner(new FileInputStream(fileName))) {
for (int i = 0; i < n; i++) {
states[i] = inputStream.nextLine();
capitals[i] = inputStream.nextLine();
}
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
System.out.println("Please enter the name of a state: ");
target = kb.nextLine();
// the loop coninues to the end of the array if the city is not found
for (n=0; (!found) && (n < states.length) ; n++) {
if (states[n].matches(target)) {
//print found message and set found to true
System.out.println("The capital of " + target + " is"); //Where I need help
found = true;
} // end if
} // for loop
// after the loop – if not(found) print not found message
if (!found)
System.out.println(target + "is not a state in the United States");
}
}
Okay so the part I need help is how to retrieve the matching 'capital' to the 'state' that was entered by the user. My output statement is basically
//print found message and set found to true
System.out.println("The capital of " + target + " is" + ); //Where I need help
found = true;
} // end if
} // for loop
And I don't know what code to put in the output statement so it cross references my second array and puts the matching Capital from the State the user entered.
System.out.println("The capital of " + target + " is " + capitals[n]);
As mentioned in the comments to my question, is the answer.

How do I use same variable inside two different methods without making those variables global?

My simple program will ask user to enter few cities. The user should be able to print them out by choosing another option.
Now I have declared an array inside a method (city();) to store those values. And I have two different methods each for asking user and printing them out (which is gonna be called in main class). If I want to print out the array (in printCity() method ), it must use the varibale which is used in another method ( city();). Thus, the printCity() method shows error that it can't find the variables. Besides, declaring those variable as Global (outside the methods)doesn't work in my case (I don't know why).
So, how can I fix this issue so that same variables works in two different methods?
My code:
Main class:
package city;
import java.util.*;
public class City {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
UserInput ui = new UserInput();
System.out.println(" THIS PROGRAM WILL TELL YOU THE CITY YOU HAVE EVER TRAVELLED\n"
+ " Choose one of the following option\n\n"
+ " You must enter city name before printing them out!");
System.out.println("1. Enter the cities you have travelled\n"
+ "2. Print out the cities\n"
+ "3. Exit\n"
+ "....................\n"
+ "....................");
while (true) {
int userChoose = input.nextInt();
switch (userChoose) {
case 1:
//call method where the program asks to enter city name
ui.city();
break;
case 2:
//call method where the program prints out the city name
ui.printCity();
break;
case 3:
System.exit(0);
default:
System.out.println("Invalid input! Plz try again: ");
}
}
}
}
UserInput class:
package city;
import java.util.*;
public class UserInput {
Scanner inScanner = new Scanner(System.in);
public void city() {
System.out.println("How many favourite city you have in your list?");
int numOfCity = inScanner.nextInt();
String[] cityInArr = new String[numOfCity];
for (int i = 0; i < numOfCity; i++) {
System.out.println("City " + (i + 1) + ": ");
cityInArr[i] = inScanner.next();
}
System.out.println("YOU ARE DONE! NOW PRINT THEM OUT");
}
public void printCity() {
System.out.println("");
System.out.println("These are your favorite cities: ");
for (int j = 0; j < numOfCity; j++) {//has an error
System.out.printf("%s ", cityInArr);//has an error
}
}
}
It sounds like your city() method should return the array of cities, which you can then pass to the printCity() method:
public String[] city() {
...
return cityInArr;
}
public void printCity(String[] cities) {
...
}
And in your calling code:
String[] cities = {}; // Empty until fetched
...
cities = ui.city();
...
ui.printCity(cities);
I would also strongly recommend that you revisit your naming. For example, getFavoriteCities() and displayCities() would be more appropriate, IMO.
Assuming that by 'global', you mean declaring them as a field of the UserInput class (correct me if you mean something else), I fail to understand why you wouldn't want to do that.
Considering you are sharing data between two methods of the same instance of the same class, a field is exactly what you need..
I took the liberty of rewriting your UserInput class to have the array as a field (the main class works unchanged). Also note that you don't need to pass around the number of cities, as it is determined by the length of the array.
public class UserInput {
private String[] cityInArr;
public void city() {
System.out.println("How many favourite city you have in your list?");
Scanner inScanner = new Scanner(System.in);
int numOfCity = inScanner.nextInt();
cityInArr = new String[numOfCity];
for (int i = 0; i < numOfCity; i++) {
System.out.println("City " + (i + 1) + ": ");
cityInArr[i] = inScanner.next();
}
System.out.println("YOU ARE DONE! NOW PRINT THEM OUT");
}
public void printCity() {
System.out.println("\nThese are your favorite cities: ");
for (int j = 0; j < cityInArr.length; j++) {//has an error
System.out.printf("%s ", cityInArr[j]);//has an error
}
}
}
You need to pass the it as method argument.
public void printCity(String[] cityInArr, int numOfCity) {
System.out.println("");
System.out.println("These are your favorite cities: ");
for (int j = 0; j < numOfCity; j++) {//has an error
System.out.printf("%s ", cityInArr);//has an error
}
Then call it like this
public static void main(String[] args) {
.......
printCity(cityArray, numOfCity);
........
}

Counting the occurrence of objects in an ArrayList, using either Collections or my functions

I have an ArrayList of FlowerClass objects. Each of these FlowerClass objects has a name. I want to go through the ArrayList and count them. I want to display the amount of each. So if I have three FlowerClass objects named Rose, two named Daffodil, and one named Tulip...I want to display the following:
Found 3 Rose
Found 3 Daffodil
Found 3 Tulip
So far, I've gotten it to count correctly using two functions I made. The problem is that I iterate through the entire ArrayList...so it'll show me the results more than once. For example, if the user adds 3 Roses and 2 Daffodils...The output is like this:
Found 3 Roses
Found 3 Roses
Found 3 Roses
Found 2 Daffodils
Found 2 Daffodils
I know why the code does this but I don't know how to erase repeats of output. I also don't know how to implement Collections correctly. I've used Collections on an ArrayList of strings before...and it works. But this time I'd be using Collections on an ArrayList of Objects, and I want to check for the frequency of each specific name. Here is the main class:
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
public class MainClass {
static ArrayList<FlowerClass> flowerPack = new ArrayList<FlowerClass>();
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while(true){
System.out.println("1. Add flower to flowerpack.");
System.out.println("2. Remove flower from the flowerpack.");
System.out.println("3. Search for a flower in the flowerpack.");
System.out.println("4. Display the flowers in the flowerpack.");
System.out.println("5. Exit the program.");
int userChoice = input.nextInt();
switch(userChoice){
case 1:
addFlower();
break;
case 2:
searchFlower();
break;
case 3:
displayFlowers();
break;
case 4:
System.out.println("Goodbye!");
System.exit(0);
}
}
}
public static void addFlower(){
if (FlowerClass.numberFlowers() == 25){
System.out.println("There are 25 flowers in the flowerpack. Remove at least one in order to add more.");
return;
}
Scanner input = new Scanner(System.in);
System.out.println("What is the flower's name?");
String desiredName = input.nextLine();
System.out.println("What is the flower's color?");
String desiredColor = input.nextLine();
System.out.println("How many thorns does it have?");
Scanner input2 = new Scanner(System.in);
int desiredThorns = input2.nextInt();
System.out.println("What does it smell like?");
String desiredSmell = input.nextLine();
flowerPack.add(new FlowerClass(desiredName, desiredColor, desiredThorns, desiredSmell));
}
public static void searchFlower(){
System.out.println("Enter the flower you want to search for.");
Scanner input = new Scanner(System.in);
String userChoice = input.nextLine();
int occurrences = 0;
for (FlowerClass flower: flowerPack){
String name = flower.getName();
if (userChoice.equals(name)){
occurrences++;
}
else if(occurrences == 0){
System.out.println("Match not found.");
return;
}
}
System.out.println("Found " + occurrences + " " + userChoice);
}
public static void searchFlower(String desiredFlower){
int occurrences = 0;
String userChoice = desiredFlower;
for (FlowerClass flower: flowerPack){
String name = flower.getName();
if (userChoice.equals(name)){
occurrences++;
}
}
System.out.println("Found " + occurrences + " " + userChoice);
}
public static void displayFlowers(){
int repeats = 0;
/*for (FlowerClass flower: flowerPack){
System.out.println(flower.getName());
}
System.out.println("Number of flowers in pack: " + FlowerClass.numberFlowers());*/
//int occurrences = Collections.frequency(flowerPack, name);
//System.out.println(name + ": " + occurrences);
for (FlowerClass flower: flowerPack){
String name = flower.getName();
searchFlower(name);
}
}
}
Here is the FlowerClass:
public class FlowerClass {
public static int numberOfFlowers = 0;
public String flowerName = null;
public String flowerColor = null;
public int numberThorns = 0;
public String flowerSmell = null;
FlowerClass(){
}
FlowerClass(String desiredName, String desiredColor, int desiredThorns, String desiredSmell){
flowerName = desiredName;
flowerColor = desiredColor;
numberThorns = desiredThorns;
flowerSmell = desiredSmell;
numberOfFlowers++;
}
public void setName(String desiredName){
flowerName = desiredName;
}
public String getName(){
return flowerName;
}
public static int numberFlowers(){
return numberOfFlowers;
}
}
If you look at my last function in the main class, you'll see that I commented out the way I was attempting to implement Collections.frequency. I also tried making a multidimensional array of Strings and storing the names of the flowers and also the number of flowers in the arrays. This was counting everything correctly but I wasn't sure how to display the names alongside the counts. It was getting very messy so I abandoned that attempt for now in favor of trying these other two options. If I can find a way to erase repeated lines of output (or if I can find a way to get Collections to work) then I won't need to tinker with the multidimensional array.
Any tips would be very much appreciated. Thank you for your time.
Interesting code, but it doesn't work the way I would do it.
In this current case as you've done it, you would need to keep track of the flower names you have already encountered:
public static void displayFlowers(){
//int repeats = 0;
List<String> displayedFlowerTypes = new ArrayList<String>();
for (FlowerClass flower: flowerPack){
String name = flower.getName();
if(!displayedFlowerTypes.contains(name))
{
displayedFlowerTypes.add(name);
searchFlower(name);
}
}
}
What I would rather do is maintain a Map that keeps track of the counts of the flower types, and just obtain the numbers for the types from that:
public class MainClass {
static List<FlowerClass> flowerPack = new ArrayList<FlowerClass>();
static Map<String, Integer> flowerCount = new HashMap<String, Integer>();
public static void addFlower() {
if (FlowerClass.numberFlowers() == 25) {
System.out.println("There are 25 flowers in the flowerpack. Remove at least one in order to add more.");
return;
}
Scanner input = new Scanner(System.in);
System.out.println("What is the flower's name?");
String desiredName = input.nextLine();
System.out.println("What is the flower's color?");
String desiredColor = input.nextLine();
System.out.println("How many thorns does it have?");
Scanner input2 = new Scanner(System.in);
int desiredThorns = input2.nextInt();
System.out.println("What does it smell like?");
String desiredSmell = input.nextLine();
flowerPack.add(new FlowerClass(desiredName, desiredColor, desiredThorns, desiredSmell));
if(!flowerCount.containsKey(desiredName))
{
flowerCount.put(desiredName, 1);
}
else
{
int currentCount = flowerCount.get(desiredName);
flowerCount.put(desiredName, currentCount+1));
}
}
That way, you could just display the flowers as the following:
public static void displayFlowers() {
for (String name : flowerCount.keySet()) {
//searchFlower(name);
System.out.println("Found " + flowerCount.get(name) + " " + name);
}
}
You could put your Flower(s) in a Set. But the easiest solution I can think of is to sort your flowers. So first, implement a Comparator<FlowerClass>
public static class FlowerComparator implements Comparator<FlowerClass> {
#Override
public int compare(FlowerClass o1, FlowerClass o2) {
return o1.getName().compareTo(o2.getName());
}
}
Then you can sort with Collections.sort(List, Comparator)
FlowerComparator flowerComparator = new FlowerComparator();
Collections.sort(flowerPack, flowerComparator);
And then your for loop needs to be something like this (to stop searching for the same flower),
String lastName = null;
for (int i = 0; i < flowerPack.size(); i++){
FlowerClass flower = flowerPack.get(i);
String name = flower.getName();
if (lastName == null || !lastName.equals(name)) {
lastName = name;
searchFlower(name); // or return the number found, and then add that count to i.
}
}

Categories

Resources