How to compare a string to multiple string arrays - java

I'm trying to write a program in which the user inputs their grocery list then based upon the type of item it is the program will give you a good order to shop for your items(i.e puts the meats together and the vegetables together)
here's my current problem, I can't get the user input to compare to the multiple string type arrays I have of store items.
String[] VegiFruit = {"Apples", "Lettuce", "Broccoli"};
String[] Meats = {"Ground beef", "Hambuger"};
Scanner USER_IN = new Scanner(System.in);
Methods Use = new Methods(); //This is another class I have, it just makes printing empty lines and lines of **** look nicer
Use.border();
System.out.println("Enter Item name then follow instructions.");
Use.space();
System.out.print("Item 1: ");
String InptOne = USER_IN.nextLine();
}
for (int i = 0; i < VegiFruit.length; i++)
{
if(Arrays.asList(VegiFruit).contains(InptOne))
{
System.out.println("Item is a VEGI");
}
}
for(int p = 0; p < Meats.length; p++)
{
if(Arrays.asList(Meats).contains(InptOne))
{
System.out.println("Item is a MEAT");
}
}

you need not go through the loops as contains method will compare with all the elements in the list.
I ran your code and the below works fine.
if(Arrays.asList(VegiFruit).contains(InptOne))
{
System.out.println("Item is a VEGI "+InptOne);
}
if(Arrays.asList(Meats).contains(InptOne))
{
System.out.println("Item is a MEAT "+InptOne);
}
However, please note that this is case senstive comparison and if the user does not enter the vegetable in your format then it will not work.
To solve that problem, you can take 2 approaches:
Have the list of veegetables/meat in caps and make the input.toUpperCase() before comparing it in contain method.
2.Use the answer on Array contains() without case sensitive lookup?

Related

To-do list and sort

I'm working on my school project and one of my idea was to create a to-do list by asking
Step 1. Enter your event
Step 2. user enters
Step 3. Enter your due date (decimal form)
Step 4. user enters
Step 5. Ask if user wants to enter more events (1 for yes, 0 for no)
Step 6. while user didn't enter 0, repeat the process 1-5
Then I want my code to sort my event according to my due date. I found something on StackOverflow that works for my program but I have the following problems:
When I run my program the system shows:
Note: Main.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
I've no idea why and hope this to be solved.
When I run my program, Step 2 is skipped after the first event is entered
Which means only 1 event and due date is entered, then you can only enter due dates.
I've no idea how this line of code works
Collections.sort(sortedList, Comparator.comparing(s -> arr_dues[stringListCopy.indexOf(s)]));
Which I should be able to understand if I'm submitting this. If you can, can you please explain a little about comparators or drop a link for a video that I would be able to watch to understand this concept.
Thank you very very very much. Here is my code.
static void to_do() {
int more = -1;
String event;
double due = 0.0;
Scanner in = new Scanner(System.in);
ArrayList<String> events = new ArrayList <String>();
ArrayList<Double> dues = new ArrayList <Double>();
System.out.println("To-Do List Generator:");
while (more != 0) {
System.out.println("Please enter your event");
event = in.nextLine();
events.add(event);
System.out.println("Please enter the due date in decimal form");
due = in.nextDouble();
dues.add(due);
System.out.println("Do you have more events to add? Yes enter 1, No enter 0");
more = in.nextInt();
}
System.out.println("Entry Successful. Here is your to do list");
String[] arr_events = new String[events.size()];
double[] arr_dues = new double[dues.size()];
for (int i=0; i<events.size();i++){
arr_events[i] = events.get(i);
}
for (int i=0; i<dues.size();i++){
arr_dues[i] = dues.get(i);
}
final List<String> stringListCopy = Arrays.asList(arr_events);
ArrayList<String> sortedList = new ArrayList(stringListCopy);
Collections.sort(sortedList, Comparator.comparing(s -> arr_dues[stringListCopy.indexOf(s)]));
String[] returnarr = new String[stringListCopy.size()];
Collections.sort(dues);
for (int i = 0; i<stringListCopy.size(); i++) {
returnarr[i] = sortedList.get(i);
}
for (int i = 0; i<arr_dues.length; i++) {
System.out.print(returnarr[i] + ", Due: ");
System.out.println(dues.get(i));
}
}
public static void main(String[] args) {
to_do();
}
Standard usage would be:
List<String> sortedList = new ArrayList<>(stringListCopy)
The issue here is likely in handling newlines. When you call in.nextInt() it is reading an integer from System.in but it is not reading the final newline which is then read by in.nextLine(). Try printing the value you are reading to see what it's doing.
Read the standard tutorial on sorting and lambdas. In summary, Collections.sort takes a Comparator. The Comparator interface has a number of static methods used to create comparators. Comparator.comparing creates a comparator that compares a value generated by a Function. Function is a functional interface so it can take a lambda. The statement you show can be interpreted as: sort the sortedList collection according to the natural ordering of values generated from each entry using the expression arr_dues[stringListCopy.indexOf(s)].
Also note that a much better design would be to encapsulate each event in a single object:
class Event {
private final String name;
private final LocalDate dueDate;
}
And have a single list of events:
List<Event> toDoList = new ArrayList<>();
The copying between collections and arrays is really not necessary.

Java; How would I store a persons favorite artist after entering multiple song names and artists?

Background: So, I am in an AP Computer Science class in the 11th grade (so you probably know we do not get very advanced). Usually, when we are assigned an assignment I am able to easily understand it and I am also very good at problem-solving when it comes to errors and other things just not working.
Explanation: I was assigned an assignment that seemed pretty easy, first you have someone enter a song title then they enter who the song artist is. They do this for as many songs as they want to (meaning it is in a while loop), then it will take the info they entered and put the song names into one ArrayList and the artists into another. After doing so I am supposed to figure out a way to figure out their "favorite artist" meaning if they enter the same artist multiple times it will print that artist as their favorite along with the song next to it.
Requirements: Needs to use ArrayLists, cannot contain information that we did not learn during class, cannot use classes and runners, and the print statement has to print out in evenly spaced columns and rows (which I already understood by using formatting and "%-10s %10s %n").
My Progress: I am at the point to where they enter all of the songs and I have made two double for loops (a for loop inside a for loop), the first to identify the favorite artist and the second to double-check if there are any other artists in the array. The first double for loop puts the favorite artist into a third ArrayList so that if there are multiple favorites (or an even amount of two artists repeated) then it will have all of them stored. The second for loop is used to remove any artists that did not repeat or repeated fewer times than a different artist so that the only thing in the third ArrayList is the "favorite" and/or the most repeated one.
The Songs and Artists used in teachers example(Test 1, 2, and 3 are for me to easily see the repeated artists songs):
1."back in black"
2."test1"
3."right now"
4."test2"
5."one"
6."sweet home alabama"
7."test3"
8."live and let die"
1."acdc"
2."the who"
3."van halen"
4."the who"
5."metallica"
6."lynyrd skynyrd"
7."the who"
8."guns n roses"
My Code:
import java.util.*;
public class SongArtists {
public static void main(String [] args) {
ArrayList<String> titles = new ArrayList<String>();
ArrayList<String> artists = new ArrayList<String>();
ArrayList<String> Favorite = new ArrayList<String>();
Scanner in = new Scanner(System.in);
int count = 0;
while (true) {
System.out.println("Enter song titles #" + count);
String title = in.nextLine();
count++;
if (title.equals("done")) {
break;
}
System.out.println("Who Performs " + title + "?");
String artist = in.nextLine();
titles.add(title);
artists.add(artist);
for (int i = 0; i < artists.size(); i++) {
for (int j = i; j < artists.size(); j++) {
if (artists.get(i).equals(artists.get(j))) {
Favorite.add(artists.get(i));
}
}
}
for (int i = 0; i < Favorite.size(); i++) {
for (int j = i; j < Favorite.size(); j++) {
if (Favorite.get(i).equals(Favorite.get(j))) {
Favorite.remove(i);
}
}
}
}
System.out.println("Your favorite artistss");
System.out.println("=====================");
System.out.printf("%-10s %10s %n", "artists", "Song\n");
for(int i = 0; i < Favorite.size(); i ++) {
System.out.printf("%-10s %10s %n", Favorite.get(i), titles.get(i));
}
}
}
Console Output:
Your favorite artists
=====================
Artist Song
the who test1
van halen right now
metallica test2
guns n roses one
First off: please use meaningful variable names. word, word2 are horrible names, may I recommend title, artist.
I'm not really understanding the question, but if you want to know how to keep track of the favorite artist I would do 1 of the following:
Use a Map that has a String key and an int value. The key is the artist name and the value is the amount of times the artist appears. Then use a separate String variable called topArtist and whenever you add an artist to the map, check to see if that artist appears more than the topArtist and if so, overwrite the topArtist
Use an ArrayList that contains Pairs of and follow the same logic as above, except whenever you try to add an artist check to see if the ArrayList already contains the artist and if so increase the int of the pair by 1.
Note: method 2 is slower because the ArrayList.contains() method is O(n) time complexity
Let me know if that solves your question or if you need clarification!

Passing arrays as parameters and make calculations

I have to make a Java Program, where a user type in the total numbers of students, so I made this code:
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int numReaders = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of magazin readers:");
numReaders = scan.nextInt();
Now, after adding the total number of students, we should add their names into an array:
//Creating an array of names, where the length is the total number entered by the user
String[] nameStr = new String[numReaders];
int[] ages = new int[numReaders];
for(int i=0; i<numReaders; i++)
{
Scanner n = new Scanner(System.in);
System.out.println("Enter the name of reader: "+i);
nameStr[i] = n.next();
}
After that, we should add correspondingly the age of each name, so I made this portion of code:
for(int i=0; i<numReaders; i++)
{
Scanner a = new Scanner(System.in);
System.out.println("Enter the age of reader: "+i);
ages[i] = a.nextInt();
}
//Display the results
System.out.println("Number of readers is: "+numReaders);
for (int i=0; i<numReaders; i++)
{
System.out.println("The name of reader "+i+" is "+nameStr[i]+ " and his age is "+ages[i]);
}
After making this code, I tested it using Ideone and Command Prompt and it works properly:
Now, I need to call method according to selection of the user:
if he typed 'a' a method should be called to specify the name and the age of the oldest student.
If he typed 'b' a method called to see how many students have an age specified by the user and If he typed 'c', a function called to calculate the average age of them all.
I am new to methods so I don't know how to add arrays into methods and make statements.
Here is the full code:
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int numReaders = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of magazin readers:");
numReaders = scan.nextInt();
//Creating an array of names, where the length is the total number entered by the user
String[] nameStr = new String[numReaders];
int[] ages = new int[numReaders];
for(int i=0; i<numReaders; i++)
{
Scanner n = new Scanner(System.in);
System.out.println("Enter the name of reader: "+i);
nameStr[i] = n.next();
}
for(int i=0; i<numReaders; i++)
{
Scanner a = new Scanner(System.in);
System.out.println("Enter the age of reader: "+i);
ages[i] = a.nextInt();
}
//Display the results
System.out.println("Number of readers is: "+numReaders);
for (int i=0; i<numReaders; i++)
{
System.out.println("The name of reader "+i+" is "+nameStr[i]+ " and his age is "+ages[i]);
}
//Choosing a statistic
//if a:
System.out.println("Please choose a, b or C:");
Scanner stat = new Scanner(System.in);
char X;
X = stat.next().charAt(0);
if(X=='a')
System.out.println(X+X);
else if(X=='b')
//System.out.println(X);
//Scanner newAge = new Scanner(System.in);
//int ageToSearchFor = newAge.nextInt();
//maxAge(ageToSearchFor);
else
System.out.println(X);
}
}
Right, so to start with your user enters an input, for example 'a', so let's go with this:
Firstly, you need to create the method where the name of the oldest student is displayed, so let's call it 'getOldestStudent' - when naming methods this is the typical naming convention, starting lowercase and then moving to uppercase for each new word - try and make them as intuitive as possible.
When making the method signature, you need to give it its visibility and also what it is going to return. In this case, as you are only using one class, we will give it private, so it is only visible by this class.
Now we need to return 2 things, so we can either put these into a string or put them into an array, which is what I would recommend, so we are going to return an array. However, you want to input an array to search through, so this goes in tbe brackets as parameters (or arguments). Therefore our method signature is the following:
private String[] getOldestStudent(String[] students, int[] ages)
Then inside this method, you can simply do the code you need to find the oldest student, add their name and age to the array and then return this.
Need anymore help just drop a comment.
On a side note, you would have been better off creating a 'Student' object and then giving this object a 'name' property and an 'age' property and then simply making an array of students and getters and setters (or accessors and mutators) for these properties.
James Lloyd's covers your question pretty well, I thought I might add some input as I think you are struggling with some principles.
At first, I would do as James advised and create a class Student that stores the values for each person.
public class Student {
public String name;
public int age;
// Constructors allow you to create a new Object and set some variables
// when you create it.
public Student (String name) {
this.name = name;
}
}
I used public to avoid getters and setters for this explanation, but I'd use private most had I to write it by myself.
Anyways, that way you only have to use one instead of two arrays (and name and age are connected with each other, e.g., you know the age of a student you know the name of, whereas with two different arrays it could happen that you don't know if nameArray[0] belongs to ageArray[0].
So you have an array Student[] students = new Student[numReaders]; and you can set each Student after reading the input, i.e., after reading the name you call students[i] = new Student(name); If you want to set the age of a Student afterwards you can do so by using student[i].age = age.
Now that we have filled our array, we can advance to your actual question.
char method;
method = stat.next().charAt(0);
// I think switch is a little easier to read for such cases
switch(method) {
case 'a': Student oldest = getOldestStudent(students);
if (oldest != null)
System.out.println(oldest.name);
break;
case 'b': //another method
break;
default: // equals to else as if none of the other cases was fulfilled
break;
}
Now you can write your own method for each scenario you have to cover.
public Student getOldestStudent(Student[] students) {
// at first we check some cases that do not require further checks
if (students.length == 0) {
System.out.println("No students have been specified");
return null; // this might lead to a NullPointerException so check the return Object whether it is null before doing anything with it
} else if (students.length == 1)
return students[0];
// no we have to see which students if the oldest in the regular case
// the first student will be used for comparison
Student oldestStudent = students[0];
for (int i = 1; i < students.length; i++) {
// see if our current student is older
if (oldestStudent.age < students[i].age)
oldestStudent = students[i];
}
return oldestStudent;
}
This way you can easily access the Students name afterwards (see above in the switch). You can build all your methods like this by passing the array to the methods and iterating through it. Depending on whether you want to return one or more Students (as it might vary between the different methods) you have to change the return type from Student to Student[].

Java arrays in 2 arraylist

I have to write a program which allows the user to keep track of all the countries he has visited, and their capitals using 2 arraylists: Countries and Capitals. The user has three options to choose from a menu, he may either:
Add a country and its corresponding capital in the Countries and Capital arraylists respectively.
Query the system for the capital of a country by inputing the country's name. (If the country was visited, the capital should be displayed, else he should be given an error message: “You did not visit this country”).
Exit the program
For example the arraylist Countries contains [“England”, “France”, “Reunion”, “Nepal”] and the one for Capitals contains [“London”, “Paris”, “St.Denis”, “Kathmandu”]. If the user has visited Kenya whose capital is Nairobi, and wishes to add this to the arraylists, the Countries and Capitals arraylists should become: [“England”, “France”, “Reunion”, “Nepal”, “Kenya”] and Capitals contains [“London”, “Paris”, “St.Denis”, “Kathmandu”, “Nairobi”] respectively. If he wished to query for the capital of France the system should display “Paris”. If the user wishes to look for the capital of Australia – the system should display “You did not visit this country”.
So here is what I have come up so far:
import java.util.*;
public class MyClass {
public static void main(String[] args) {
ArrayList<String> countries = new ArrayList<String>();
Scanner sc = new Scanner(System.in);
String country;
String capital;
String search;
countries.add("England");
countries.add("France");
countries.add("Reunion");
countries.add("Nepal");
ArrayList<String> capitals = new ArrayList<String>();
capitals.add("London");
capitals.add("Paris");
capitals.add("St Denis");
capitals.add("Kathmandu");
System.out.println("Please choose one option:");
System.out.println("1. Add a new country and its capital.");
System.out.println("2. Search for the capital of a country.");
System.out.println("3. Exit.");
int opt = sc.nextInt();
if (opt == 1) {
country = sc.nextLine();
capital = sc.nextLine();
countries.add(country);
capitals.add(capital);
} else if (opt == 2) {
System.out.println("Enter the capital of the country.");
search = sc.next();
for (int i = 0; i < countries.size(); i++) {
for (int j = 0; j < capitals.size(); j++) {
if (search.equals(capitals.get(j))) {
System.out.println("The country is " + countries.get(i));
}
}
}
} else {
System.exit(0);
}
}
}
But actually, the for loop apparently does not work as when I enter the capital of the city, the program just terminates right there.
EDIT: I can't use HashMap but lists
You can just use a HashMap, with the country as key and the capital as value:
HashMap<String, String> hashMap = new HashMap<String, String>();
// add data to the HashMap
hashMap.put("England", "London"); //assign value "London" to key "England"
// get data from the HashMap
hashMap.get("England"); //returns "London"
EDIT: If you still want to use lists, you can do the following to retrieve the corresponding value. The benefit of this is that it works both ways:
capitals.get(countries.indexOf("England")); //it will return "London"
countries.get(capitals.indexOf("London")); //it will return "England"
Note this will only work if the lists are properly ordered (so the first country matches the first capital, the second country matches the second capital, etc)
Oh boy. Quite a few problems here.
First of all: Your code has no problem (related to what you call the problem) with the for loop.
You main method executes exactly one of the if branches, and then terminates. If you want the program to run re-prompting the menu after every completed operation until the terminate option is requested, you need to wrap the menu in a while loop:
int opt= sc.nextInt();
while (opt != 3) {
if (...)
}
System.exit(0);
In second place: in Java you usually don't do paired arrays (i.e. two arrays that are semantically linked by the positions of their elements). You can either create a class:
class CountryAndCapital {
String country;
String capital;
//...
}
ArrayListy<CountryAndCapital> myArray = new ArrayList<>();
or, as other have suggested, use a Map, which is a data structure that links one data to another (in this case, the capital to the country), and also prevents duplicates (in a sense...):
Map<String, String> countryToCapital = new HashMap<>();
countryToCapital.put("France", "Paris");
//...
Finally: if your arrays are paired, there is no need to iterate over both! You can iterate over the country one and just take that index over to the capitals one:
for(int i=0; i<capitals.size();i++) {
if(search.equals(capitals.get(i))) {
System.out.println("The country is "+countries.get(i));
}
}
There is a problem with you approach: There are countries with more than one capital
I think a good data structure that fits your needs would be a
Map<County,Capital[]>
Maps are very useful, the docs are here
Bonus dumb thought: If I visited Vatican City State, I'd have been at the same time in Rome, although not in Italy. Well... that would be true if the Vatican City had an airport, otherwise I surely have been in Italy right before
Put your code in while loop
Use HashMap instead
Give message before getting input from user
always try to take whole line as input when getting input from console
HashMap<String, String> countries = new HashMap<>();
Scanner sc = new Scanner(System.in);
String country;
String capital;
String search;
countries.put("England", "London");
countries.put("France", "Paris");
countries.put("Reunion", "St Denis");
countries.put("Nepal", "Kathmandu");
while (true) {
System.out.println("Please choose one option:");
System.out.println("1. Add a new country and its capital.");
System.out.println("2. Search for the capital of a country.");
System.out.println("3. Exit.");
System.out.print("Enter your choice : ");
int opt = Integer.parseInt(sc.nextLine());
if (opt == 1) {
System.out.print("Country : ");
country = sc.nextLine();
System.out.print("Capital : ");
capital = sc.nextLine();
countries.put(country, capital);
} else if (opt == 2) {
System.out.print("Enter the capital of the country : ");
search = sc.nextLine();
for(Map.Entry<String, String> entry : countries.entrySet()){
if(search.equals(entry.getValue())){
System.out.println("The country is " + entry.getKey());
break;
}
}
} else {
System.exit(0);
}
}

Random Generate String from ArrayList without replacement in JAVA

I am trying to create a program that will allow users to enter a list of names. And then the program will pull from the ArrayList randomly and pull each name one at a time until all names have been used. I have the scanner part completed as seen below:
public class Auction
{
public static void main (String[] args)
{
Scanner scan = new Scanner(System.in);
ArrayList<String> names = new ArrayList<String> ();
char quit = 'Y';
String playername = null;
while (quit == 'Y')
{
System.out.println("\nPlayer Name:");
playername = scan.next();
names.add (playername);
System.out.print("Enter Another Name? (Y/N) \n");
String word = scan.next();
word = word.toUpperCase();
quit = word.charAt(0);
}
}
}
I have another class where I tried to complete the random generation with no success. There doesn't appear to be any errors but it's not working either. I know I am way off on the "random without replacing" part but I was just trying to get it to work before I moved on. I'm not sure if I am even referencing the ArrayList from the other Auction Class. Like a lot of others, I am new to Java so be gentle. I have spent a week on this which should probably have taken me a few hours. I appreciate your help.
public class Draft
{
Random randomGenerator;
ArrayList<String> names;
String randName() {
int index = randomGenerator.nextInt(names.size());
System.out.println("Next on the Block" + names.get(index));
return names.get(index);
}
}
Just use Collections.shuffle() to shuffle the list itself:
Collections.shuffle(names);
Your list is now randomized and you can take elements from the top until it's empty. For example, using an iterator:
Iterator<List> it = names.iterator();
while (it.hasNext()) {
String name = it.next();
it.remove(); // optionally remove
System.out.println("Next on the block" + name);
}
Or, if there's no need to actually remove the name from the list, using a simple for loop:
for (String name : names) {
System.out.println("Next on the block" + name);
}

Categories