Unable to print values based on key in Hashmap - java

I'm having trouble making option 7 work in my code (i.e. choice == 7), the one that outputs a student's set of quiz scores.
When I run the program, it simply asks for jumps back to the original set of choices.
Any help would be much appreciated.
package studentquizgrades;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class StudentQuizGrades {
public static void main(String[] args) {
Map<String, Student> map = new HashMap<>();
addStudent(map);
}
private static void addStudent(Map<String, Student> map) {
Scanner userInput = new Scanner(System.in);
boolean finish = false;
do {
System.out.println("Please choose an option: ");
System.out.println("Add student and quizzes - 1, Get all quiz scores - 2, Get highest quiz score- 3, ");
System.out.println("Get lowest quiz score - 4, Get class average - 5, View a list of all students - 6");
System.out.println("Get a student's quiz scores - 7, Quit - 8");
int choice = userInput.nextInt();
if (choice == 1) {
Set<String> keySet = map.keySet();
System.out.println("How many students would you like to add?");
int numberOfStudents = userInput.nextInt();
for (int counter = 0; counter < numberOfStudents; counter++) {
System.out.println("ENTER NAME");
Scanner addName = new Scanner(System.in);
String name = (addName.nextLine());
System.out.println("Enter First Quiz Score");
Scanner addQuiz1 = new Scanner(System.in);
int quiz1 = (addQuiz1.nextInt());
System.out.println("Enter Second Quiz Score");
Scanner addQuiz2 = new Scanner(System.in);
int quiz2 = (addQuiz2.nextInt());
System.out.println("Enter Third Quiz Score");
Scanner addQuiz3 = new Scanner(System.in);
int quiz3 = (addQuiz3.nextInt());
Student student = new Student(name, quiz1, quiz2, quiz3);
map.put(student.getKey(), student);
}
} else if (choice == 2) {
Set<String> keySet = map.keySet();
for (String currentKey : keySet) {
Student student = map.get(currentKey);
System.out.println();
System.out.println(currentKey);
System.out.println(Arrays.toString(student.getQuizGrades()));
System.out.println();
}
} else if (choice == 3) {
Set<String> keySet = map.keySet();
int max = 0;
String maxName = null;
for (String currentKey : keySet) {
Student student = map.get(currentKey);
int[] scores = student.getQuizGrades();
for (int counter = 1; counter < scores.length; counter++) {
if (scores[counter] > max) {
max = scores[counter];
maxName = currentKey;
}
}
}
System.out.println();
System.out.println("The highest quiz score was " + max + "; his/her name is " + maxName);
System.out.println();
} else if (choice == 4) {
Set<String> keySet = map.keySet();
int min = Integer.MAX_VALUE;
String minName = null;
for (String currentKey : keySet) {
Student student = map.get(currentKey);
int index = 0;
int[] scores = student.getQuizGrades();
for (int counter = 0; counter < scores.length; counter++) {
if (scores[counter] < min) {
minName = currentKey;
min = scores[counter];
}
}
}
System.out.println();
System.out.println("The lowest quiz score was " + min + "; his or her name is " + minName);
System.out.println();
} else if (choice == 5) {
Set<String> keySet = map.keySet();
int[] allGrades;
int sum = 0;
int counter2 = 0;
for (String currentKey : keySet) {
Student student = map.get(currentKey);
int[] scores = student.getQuizGrades();
for (int counter = 0; counter < scores.length; counter++) {
int j = scores[counter];
sum = sum + j;
counter2++;
}
}
int average = sum / counter2;
System.out.println("");
System.out.println("The class average is: " + average);
System.out.println("");
} else if (choice == 6) {
Set<String> keySet = map.keySet();
System.out.println("");
System.out.println("List of students: ");
for (String currentKey : keySet) {
Student student = map.get(currentKey);
System.out.println(currentKey);
}
}
else if(choice == 7){
Set<String> keySet = map.keySet();
System.out.println("");
System.out.println("Please enter a student's name: ");
String studentName = userInput.nextLine();
for (String currentKey : keySet) {
Student student = map.get(currentKey);
if(studentName == currentKey){
System.out.println(currentKey + "'s quiz scores:");
int [] quizArray = student.getQuizGrades();
for(int counter1 = 0; counter1 < quizArray.length; counter1++ ){
System.out.println(quizArray[counter1]);
}
}
}
}
else if (choice == 8) {
finish = true;
break;
}
} while (finish == false);
}
}
package studentquizgrades;
public class Student {
private String key;
private int grade1;
private int grade2;
private int grade3;
public Student(String key, int grade1, int grade2, int grade3){
this.key = key;
this.grade1 = grade1;
this.grade2 = grade2;
this.grade3 = grade3;
}
public String getKey(){
return key;
}
public int[] getQuizGrades(){
int [] anArray = {grade1, grade2, grade3};
return anArray;
}
public int getAverageScore(){
int average = (grade1 + grade2 + grade3)/3;
return average;
}
}

You mix scanner.nextInt() and scanner.nextLine().
When you call scanner.nextInt() and then you call scanner.nextLine(), scanner.nextLine() returns the remain of the current line of the input entered by scanner.nextInt(), that is an empty String. And that before you may enter anything.
That's why you loop to the original set of choices.
You should avoid to chainnext() and nextLine(). Try to use only the one or the other one.
Besides, the code in the else if(choice == 7) block compares String values with == and besides this comparison is even not required since you perform a loop on the map of students to retrieve the student while you have a Map that may retrieve the information in a straight way :
Set<String> keySet = map.keySet();
System.out.println("");
System.out.println("Please enter a student's name: ");
String studentName = userInput.next();
for (String currentKey : keySet) {
Student student = map.get(currentKey);
if(studentName == currentKey){
System.out.println(currentKey + "'s quiz scores:");
int [] quizArray = student.getQuizGrades();
for(int counter1 = 0; counter1 < quizArray.length; counter1++ ){
System.out.println(quizArray[counter1]);
}
}
}
You could do simply :
System.out.println("");
System.out.println("Please enter a student's name: ");
String studentName = userInput.next();
Student student = map.get(studentName);
if (student!=null){
System.out.println(studentName + "'s quiz scores:");
int[] quizArray = student.getQuizGrades();
for (int counter1 = 0; counter1 < quizArray.length; counter1++) {
System.out.println(quizArray[counter1]);
}
}

Instead of if (studentName == currentKey) use if (studentName.equals(currentKey). You should always compare strings with equals(...), because == only checks the equality of references, not the objects itself. As studentName and current key are two independent instances, they are never equal in a comaprison with == as their references differ.
You should try to refactor your code, as there are multiple issues. As #markspace already pointed out, your loop is unnecessary and the critical if statement is not needed at all.
for (String currentKey : keySet) {
Student student = map.get(currentKey);
if(studentName == currentKey){
//...
}
}
This can be reduced to the following code as you deal with a map. That is the point of a map, not having to iterate through all elements, but to use a key to directly access an element.
Student student = map.get(currentKey);
if (student != null) {
// ...
}
Also, you should call nextLine(); after int choice = userInput.nextInt(); (and other next...(...); calls), because they do not consume the newline character. Otherwise studentName = userInput.nextLine(); will only contain the newline character leftover from last call to nextInt()...;.

Related

How do I relate one array input to another?

Say I have 2 Scanner filled arrays, name[] and age[]. Each one filled in order. If I am to find the oldest person in the array how do I print out their name AND their age, using the arrays?
For example the largest entry in age[] was 78. Is there a way to relate it with the name[] array to print it out?.
Reference code:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("How many entries ?");
int entries;
do {
entries = input.nextInt();
if (entries < 1) {
System.out.println("please enter a valid number!");
}
} while (entries < 1);
String[] name = new String[entries];
String[] gender = new String[entries];
int[] age = new int[entries];
for (int i = 0; i < entries; i++) {
System.out.println("Enter the name of person No" + (i + 1) + ".");
name[i] = input.next();
}
double ageSum = 0;
int max = 0;
for (int i = 0; i < entries; i++) {
System.out.println("How old is " + name[i] + " ?");
age[i] = input.nextInt();
ageSum += age[i];
max = Math.max(max, age[i]);
}
System.out.println("the oldest person is "
+ name[] + " whose " + max + " years old.");
}
Assuming that your arrays have the same size and the ages corresponding to the names then you can check for the highest age and store the indice of the element with the highest age.
Then you have your name at this indice.
int highestAgeIndice = 3; //indice of element with age 97 as example
names[highestAgeIndice] // the corresponding name
Calculating highest age and store its indice
int max = 0;
int highestInd = 0;
for (int i = 0; i < age.length; i++) {
if (age[i] > max) {
max = age[i];
highestInd = i;
}
}
System.out.println("the oldest person is " +
name[highestInd] + " whose " + max + " years old.");
The Code
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("How many entries ?");
int entries;
do {
entries = input.nextInt();
if (entries < 1) {
System.out.println("please enter a valid number!");
}
} while (entries < 1);
String[] name = new String[entries];
String[] gender = new String[entries];
int[] age = new int[entries];
for (int i = 0; i < entries; i++) {
System.out.println("Enter the name of person No" + (i + 1) + ".");
name[i] = input.next();
}
double ageSum = 0;
for (int i = 0; i < entries; i++) {
System.out.println("How old is " + name[i] + " ?");
age[i] = input.nextInt();
ageSum += age[i];
}
int max = 0;
int highestInd = 0;
for (int i = 0; i < age.length; i++) {
if (age[i] > max) {
max = age[i];
highestInd = i;
}
}
System.out.println("the oldest person is " +
name[highestInd] + " whose " + max + " years old.");
}
If you have two arrays name[] and age[], you can relate them by creating some class Person with fields of type the entries in these arrays, and get a list of persons List<Person>, something like this:
static class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
#Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public static void main(String[] args) {
String[] name = {"Junior", "Senior", "Middle"};
int[] age = {25, 78, 40};
List<Person> people = IntStream.range(0, name.length)
.mapToObj(i -> new Person(name[i], age[i]))
.collect(Collectors.toList());
// sort by age in reverse order
people.sort(Comparator.comparing(
Person::getAge, Comparator.reverseOrder()));
// output
people.forEach(System.out::println);
}
Output:
Person{name='Senior', age=78}
Person{name='Middle', age=40}
Person{name='Junior', age=25}
See also: How do I sort two arrays in relation to each other?
You could use indexOf on you array age for the Max age which will tell you the index of the associated name.
names[age.indexOf(Max)]

How to use 2D arrays with other classes

I have an assignment, I was wondering how I could go about using 2D arrays with another class, I have a class called Die that looks like this:
public class Die
{
private final int MAX = 6; // maximum face value
private int faceValue; // current value showing on the die
public Die()
{
faceValue = 1;
}
public int roll()
{
faceValue = (int)(Math.random() * MAX) + 1;
return faceValue;
}
public void setFaceValue(int value)
{
faceValue = value;
}
public int getFaceValue()
{
return faceValue;
}
public String toString()
{
String result = Integer.toString(faceValue);
return result;
}
}
Now in a main method i have to do the following
I have all the other parts done, I just cant seem to figure out this part.
My current code(Not started this part) is below
import java.util.Arrays;
import java.util.Scanner;
class ASgn8
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.print("How many players? ");
int playerCount = scan.nextInt();
scan.nextLine();
String[] playerNames = new String[playerCount];
int again = 1;
for(int i = 0; i < playerCount; i++)
{
System.out.print("What is your name: ");
playerNames[i] = scan.nextLine();
}
int randomNum = (int)(Math.random() * (30-10)) +10;
}
}
Do any of you java geniuses have any advice for me to begin?
Thanks!
Here is your main method, you just need to update your main method with this one,
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("How many players? ");
int playerCount = scan.nextInt();
scan.nextLine();
HashMap<String, ArrayList<Die>> hashMap = new HashMap<String, ArrayList<Die>>();
int again = 1;
for(int i = 0; i < playerCount; i++)
{
System.out.print("What is your name: ");
hashMap.put(scan.nextLine(),new ArrayList<Die>());
}
for(String key : hashMap.keySet()){
System.out.println(key + "'s turn....");
Die d = new Die();
System.out.println("Rolled : " + d.roll()) ;
hashMap.get(key).add(d);
System.out.println("Want More (Yes/No) ???");
String choice = scan.next();
while(choice != null && choice.equalsIgnoreCase("YES")){
if(hashMap.get(key).size()>4){System.out.println("Sorry, Maximum 5-Try you can...!!!");break;}
Die dd = new Die();
System.out.println("Rolled : " + dd.roll()) ;
hashMap.get(key).add(dd);
System.out.println("Want More (Yes/No) ???");
choice = scan.next();
}
}
for(String key : hashMap.keySet()){
System.out.println(key + " - " + hashMap.get(key));
}
}
EDITED
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("How many players? ");
int playerCount = scan.nextInt(); // get number of participant player...
scan.nextLine();
Die[] tempDie = new Die[5]; // temporary purpose
Die[][] finalDie = new Die[5][]; // final array in which all rolled dies stores...
String [] playerName = new String[playerCount]; // stores player name
int totalRollDie = 0; // keep track number of user hash rolled dies...
for(int i = 0; i < playerCount; i++) // get all player name from command prompt...
{
System.out.print("What is your name: ");
String plyrName = scan.nextLine();
playerName[i] = plyrName;
}
for(int i = 0; i < playerCount; i++){
System.out.println(playerName[i] + "'s turn....");
totalRollDie = 0;
Die d = new Die();
System.out.println("Rolled : " + d.roll()) ;
tempDie[totalRollDie] = d;
totalRollDie++;
System.out.println("Want More (Yes/No) ???");
String choice = scan.next();
while(choice != null && choice.equalsIgnoreCase("YES")){
if(totalRollDie < 5){ // if user want one more time to roll die then first check whether alread user has rolled 5-time or not.
Die dd = new Die();
System.out.println("Rolled : " + dd.roll()) ; // rolled and print whatever value get..
tempDie[totalRollDie] = dd;
totalRollDie++;
System.out.println("Want More (Yes/No) ???");
choice = scan.next();
}
}
finalDie[i] = new Die[totalRollDie];
for(int var = 0 ; var < totalRollDie ; var++){
finalDie[i][var] = tempDie[var]; // store Die object into finalDie array which can random number for all user..
}
}
for(int i = 0 ;i < playerCount ; i++){ // finally print whatever user's roll value with all try...
System.out.println(" --------- " + playerName[i] + " ------------ ");
for(Die de : finalDie[i]){
System.out.println(de);
}
}
tempDie = null;
}

How to fix my Array class

I am trying to figure out how to get my array to run correctly, I know I have to change the array value to an input but I cannot get the program to compile if any one can help that be great.
I am trying to have the program take input for grades and names of students and in the end output their name and grade.
Edit sorry this is my first it posting i have an error
Student.java:60: error: class, interface, or enum expected I am in java 101 so this is why it is such low level java, we only know the basics
import java.util.Scanner;
public class students
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("How many students?: ");
int numofstudents = keyboard.nextInt();
Student s = new Student();
s.setMultipleStudents();
s.toString();
System.out.println("Enter the Grade for the student: ");
int gradeofstudnets = keyboard.nextInt();
}
}
and my second class is
import java.util.Scanner;
public class Student
{
Scanner scan = new Scanner(System.in);
private String name;
private int grade;
private int[] multiplegradeinputs = new int[10];
private String[] multipleStudent = new String[10];
public Student()
{
}
public Student(String n, int g)
{
name = n;
grade = g;
}
public String setMultipleStudents()
{
String n = "";
for(int i = 1; i < multipleStudent.length; i++)
{
System.out.println("Enter student #" + i +" name: " );
n = scan.nextLine();
multipleStudent[i] = n;
}
return null;
}
public String multiplegradeinputs()
{
for(int i = 1; i <multiplegradeinputs.length; i++)
{
System.out.println("Enter the Grade of the student#" + i +" : ");
grade = scan.nextInt();
multiplegradeinputs[i] = grade;
}
} <--- error here
public String toString()
{
String temp = "";
for(int i = 1; i < multipleStudent.length; i++)
{
temp += multipleStudent[i] + " ";
}
return temp;
}
}
Add return statement in your multiplegradeinputs() method:
public String multiplegradeinputs()
{
for(int i = 1; i <multiplegradeinputs.length; i++)
{
System.out.println("Enter the Grade of the student#" + i +" : ");
grade = scan.nextInt();
multiplegradeinputs[i] = grade;
}
return null; //Add this line
}
Or change your methods to void return type if they dont return anything.
Class names have to be capitalized in java, so instead of
public class students
you should write
public class Students
Also instead of writing
keyboard.nextInt();
You should write
Integer.parseInt(keyboard.nextLine());
This is mainly because java is full of bugs and technical specifications that you won't find easily. Let me know if this fixes it for you, since you didn't post the exact error message you got.
As for the error that you pointed out, it's because your function expects a String as a return value no matter what, so either change that to void if you can or return a null string. To do that just add the following line at the very end of the method.
return null;
You should create a Student object which holds the properties of the student, e.g. Name and Grades. You should then store all the student objects in some kind of data structure such as an array list in the students class.
Adding to the answer provided by #hitz
You have a bug in the for loops:
for(int i = 1; i <multiplegradeinputs.length; i++)
for(int i = 1; i < multipleStudent.length; i++)
You will never populated multiplegradeinputs[0] and multipleStudent[0] because you start the loop at index == 1 and thus you will have only 9 student names stored instead of 10.
Change to:
for(int i = 0; i <multiplegradeinputs.length; i++)
for(int i = 0; i < multipleStudent.length; i++)
Remember even though the length in 10, the indices always start with 0 in Java and in your case will end with 9.
import java.util.Scanner;
public class Student
{
Scanner scan = new Scanner(System.in);
private String name;
private int grade;
private int[] multiplegradeinputs = new int[10];
private String[] multipleStudent = new String[10];
public Student()
{
}
public Student(String n, int g)
{
name = n;
grade = g;
}
public String setMultipleStudents()
{
String n = "";
for(int i = 1; i < multipleStudent.length; i++)
{
System.out.println("Enter student #" + i +" name: " );
n = scan.nextLine();
multipleStudent[i] = n;
}
return null;
}
public void multiplegradeinputs()
{
for(int i = 1; i <multiplegradeinputs.length; i++)
{
System.out.println("Enter the Grade of the student#" + i +" : ");
grade = scan.nextInt();
multiplegradeinputs[i] = grade;
}
}
public String toString()
{
String temp = "";
for(int i = 1; i < multipleStudent.length; i++)
{
temp += multipleStudent[i] + " ";
}
return temp;
}
}
this is the 2nd class
import java.util.Scanner;
public class students
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("How many students?: ");
int numofstudents = keyboard.nextInt();
Student s = new Student();
s.setMultipleStudents();
s.toString();
System.out.println("Enter the Grade for the student: ");
int gradeofstudnets = keyboard.nextInt();
}
}
You are missing a return value in the multiplegradeinputs() method.

How to arrange an array in descending order alongside a string array

here is my code... I need all the contestants to be ranked according to their votes... as you can see there are seperate arrays for the names and vote count(tally)... I was told that bubble sort would work but i cant see how because bubble sort replaces the insides so if tally[2] is greater than tally[1], it will become the new tally[1] meanwhile the name stays the same as name[1] does not change with name[2]...I would prefer that you use basic codes as i am a total noob with programming and have only recently started...also, any recommendations about how i can write my code better/shorter is appreciated
import java.util.*;
public class FroshNight {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String dec = "0";
System.out.println("How many blocks?");
int contno = sc.nextInt();
int winner = 0;
String winname = "a";
String[] code = new String[contno];
int total = 0;
int counter = 0;
String[] contname = new String[contno];
int[] tally = new int[contno];
while (counter<contno) {
System.out.print("Name of Pair:");
contname[counter]=sc.next();
counter++;
}
counter=0;
while (counter<contno) {
System.out.println("Choose a vote code for "+ contname[counter]+"(must not be x)");
code[counter] = sc.next();
counter++;
}
boolean stop = false;
counter=0;
while(stop == false){
System.out.println("Input Vote (x to exit): ");
dec = sc.next();
if(dec.equals("x")) {
stop = true;
}
counter = 0;
while(counter<contno){
if(dec.equals(code[counter])){
tally[counter] +=1;
counter = contno;
}
counter++;
}
}
//>> aft. else
counter = 0;
while(counter<contno){
total += tally[counter];
counter++;
;
}
counter=0;
while(counter<contno){
if(tally[counter]>winner){
winner = tally[counter];
winname = contname[counter];
}
counter++;
}
System.out.print("The Winner is: "+ winname +" - "+winner );
System.out.println("("+((double)winner/total)*100+"%)");
counter = 0;
while (counter<contno) {
System.out.print(contname[counter]+" - Score:");
System.out.print(tally[counter]);
System.out.println("("+((double)tally[counter]/total)*100+"%)");
counter++;
}
//>>> end while
// add rankings here^^
}
}

Student scores sorting help needed for Java

import java.util.Scanner;
import java.util.Arrays;
class StudentScores {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the # of students");
int numOfStudents = input.nextInt();
int[] scores = new int[numOfStudents];
String[] names = new String[numOfStudents];
for (int i = 0; i < numOfStudents; i++) {
input.nextLine();
System.out.print("Enter name: ");
names[i] = input.nextLine();
System.out.print("Enter score: ");
scores[i] = input.nextInt();
}
// This doesn't sort anything, it just prints out the result in unsorted way
/*for (int i = 0; i < numOfStudents; i++) {
System.out.println(names[i] + " " + scores[i]);
}*/
Arrays.sort(scores);
reverse(scores);
for (int u: scores) {
System.out.println(u);
}
}
public static int[] reverse(int[] array) {
for (int i = 0, j = array.length - 1; i < j; i++, j--) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
}
The original question is:
Write a program that prompts the user to enter the number of students, the students’ names, and their scores, and prints student names in decreasing order of their scores.
My question is how do you display the name with the sorted list of scores?
You necessarily don't have to give me a complete solution, just give me a hint so I can solve it myself.
You can encapsulate the related fields into a class, e.g. a StudentRecord can encapsulate the fields name and score.
Now, you sort a collection of these objects based on the second field, score. When it comes time to print the sorted result, you iterate through the collection and print the first field, name.
To illustrate:
public class StudentRecord implements Comparable<StudentRecord> {
private String name;
private int score;
public StudentRecord(String name, int score) {
this.name = name;
this.score = score;
}
#Override
public int compareTo(StudentRecord other) {
if (score == other.score) return 0;
else if (score < other.score) return -1;
else return 1;
}
#Override
public String toString() {
return name;
}
public static void main(String[] args) {
StudentRecord stu1 = new StudentRecord("Matt", 50);
StudentRecord stu2 = new StudentRecord("John", 90);
if (stu1.compareTo(stu2) == 0) {
System.out.println(stu1.toString() + " has the same score with " + stu2.toString());
}
else if (stu1.compareTo(stu2) < 0) {
System.out.println(stu1.toString() + " has a lower score than " + stu2.toString());
}
else {
System.out.println(stu1.toString() + " has a higher score than " + stu2.toString());
}
// output:
// Matt has a lower score than John
}
}
In many sorting algorithms, implementing the Comparable interface gives the algorithm enough information to sort a collection of such objects implementing said interface.
You're not going to be able to use Arrays.sort() for this problem because you need to sort both arrays together. Write a sorting function that sorts the scores in order, and every time it swaps two scores, swap the students with those scores as well.

Categories

Resources