Java - while loop continues even when it should be done - java

I'm trying to write a controller which checks the input to get the right name from a "students" list, and somehow, even if I gave the right name, the loop continues.
I'm sure I missing something very obvious.
Here is the code:
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
while (!students.contains(str)){
System.out.println("Try again");
str = sc.nextLine();
}
edit:
the problem is with the class in the "student" list here's how the class and the list looks like:
// this gets filled right from a txt
List<Student> students = new ArrayList<>();
public class Student{
private String name;
private int gradeCount;
private int average;
private boolean homeWork;
...
}
and I would like to check the name data member in this class

You can't search for a String in a list of Student. You need to write your own contains() method, possibly something like this:
public boolean contains(List<Student> list, String s) {
for(Student student : list)
if(student.getName().equals(s)) return true;
return false;
}
Then you can do:
Scanner sc = new Scanner(System.in);
while (!contains(students, sc.nextLine()))
System.out.println("Try again");
This is of course assuming you have a getter for name.
Another option is for your Student to implement Comparable so that you can use various Collections methods and you can compare the Student objects to each other. An example of that would be:
public class Student implements Comparable<Student> {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int compareTo(Student s2) {
return name.compareTo(s2.getName());
}
}
You can then do the following:
ArrayList<Student> students = new ArrayList<>();
students.add(new Student("Chris"));
students.add(new Student("John"));
students.add(new Student("Frank"));
students.add(new Student("Devon"));
Student me = new Student("Chris");
students.contains(me); // true
Since you have Comparable now implemented, you can also sort the Student object by name by using Collections.sort(students).
More examples on using Comparable in Java https://www.mkyong.com/java/java-object-sorting-example-comparable-and-comparator/

User a primer read:
import java.util.ArrayList;
import java.util.Scanner;
public class Sandbox {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
Boolean found = false;
String input;
ArrayList<Student> students = new ArrayList<Student>();
students.add(new Student("Jim"));
students.add(new Student("Kim"));
students.add(new Student("Bill"));
students.add(new Student("Betty"));
System.out.println("Enter the name of a student to check");
input = keyboard.nextLine();
if(students.get(0).getName().equals(input)) {
System.out.println("You found " + students.get(0).getName());
found = true;
keyboard.close();
}
while(!found) {
System.out.println("Try again");
input = keyboard.nextLine();
for(int i = 1; i < students.size(); i++) {
if(students.get(i).getName().equals(input)) {
System.out.println("You found " + students.get(i).getName());
found = true;
keyboard.close();
break;
}
}
}
}
Student class
public class Student {
String name;
public Student () {
}
public Student (String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}

Assuming there's a getter for the Student object, you can map the list of Student objects to a list of students names (String) and then perform the .contains() call on that list. So try this:
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
// Create a List<String> of student names
List<String> names = students
.stream()
.map(student -> student.getName())
.collect(Collectors.toList());
while (!names.getName().contains(str)){
System.out.println("Try again");
str = sc.nextLine();
}

Scanner sc = new Scanner(System.in);
String str=null;
boolean isFound=false;
while (!isFound)
{
str = sc.nextLine();
for(Student stdObj:students)
if(stdobj.name.equals(str))
{
isFound=true;
break;
}
if(!isFound)
System.out.println("Try again");
}

Related

How to access hashmap object with class object as key

I want to make a program that updates the hashmap depending on the user input commands. How can I remove/update specific element of a hashmap by passing id variable of Student class as user input?
This is what I got so far:
class Student{
String name;
String secondname;
int id;
public Student(String name,String secondname,int id){
this.id = id;
this.name = name;
this.secondname=secondname;
}
public int getId(){
return this.id;
}
#Override
public String toString() {
return "Second Name: "+ this.secondname+ " Name: "+ this.name+ " ID: "+ this.id;
}
#Override
public boolean equals(Object o) {
if(this==o){
return true;
}
if (o==null){
return false;
}
if(getClass() != o.getClass()){
return false;
}
Student obj = (Student) o;
if (secondname == null) {
if(obj.secondname!= null){
return false;
}
}
else if(!secondname.equals(obj.secondname)){
return false;
}
if(name==null){
if(obj.name!=null){
return false;
}
}
else if(!name.equals(obj.name)){
return false;
}
if(getId()==0){
if(obj.getId()!=0){
return false;
}
}
else if (getId()!=obj.getId()){
return false;
}
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result= prime*result+id;
return result;
}
public class Main {
public static void main(String[] args) {
HashMap<Student,String> studentmap = new HashMap<>();
Student myname = new Student("Name","SecondName",1234);
Student mrx = new Student("Mr","X",2077);
Student msx = new Student("Ms","X",1111);
studentmap.put(myname,"A");
studentmap.put(mrx,"C");
studentmap.put(msx,"B");
while (true){
Scanner scan = new Scanner(System.in);
String x= scan.nextLine();
if (x.equals("add")){
System.out.println("Who do you want to add? ");
String y= scan.nextLine();
String [] splitted = y.split("\\s+");
studentmap.put(new Student(splitted[0],splitted[1],Integer.parseInt(splitted[2])),splitted[3]);
}
if(x.equals("remove")){
System.out.println("Who do you want to remove?");
String z= scan.nextLine();
int theid = Integer.parseint(z);
studentmap.remove(theid); // adding and printing works but this is what I have problem with
}
//if (x.equals("update")){
//String e= scan.nextLine();
//String [] splitted = e.split("\\s+");
//int theid = Integer.parseint(splited[0])
//studentmap.replace(theid,splitted[1]);
//}
if(x.equals("print")){
studenci.entrySet().forEach(entry->{
System.out.println(entry.getKey() + " Grade: " + entry.getValue());
});
}
if (x.equals("end")){
break;
}
}
}
The way I want this program to work is to make the user type a command like "delete", then make him type ID ex."1234" and then remove a hash map object whose Key's ID is 1234.
EDIT:
My assignment roughly translated to english:
Make a program using a map which keys are Student class objects (with fields: name ,secondname, id ), and the values are grades.
Program should allow the user to add, delete, update the grade and print the students list. In case of deleting and updating look up the object by ID.
You have to "find" the key from the Map<Student,String> first, which matches the id you have. After that you can use it to remove the entry from the Map<Student,String>. The code might look like this:
Student s = null;
for(Student k: studentmap.keySet()) {
if (k.getId() == theid) {
s = k;
break;
}
}
This will find you the key in the Map. After that you can remove the entry:
if (s != null) {
studentmap.remove(s);
}
It'd make more sense to change:
HashMap<Student,String> studentmap = new HashMap<>();
Student myname = new Student("Name","SecondName",1234);
Student mrx = new Student("Mr","X",2077);
Student msx = new Student("Ms","X",1111);
studentmap.put(myname,"A");
studentmap.put(mrx,"C");
studentmap.put(msx,"B");
Into:
HashMap<Integer,Student> studentmap = new HashMap<>();
Student myname = new Student("Name","SecondName",1234);
Student mrx = new Student("Mr","X",2077);
Student msx = new Student("Ms","X",1111);
studentmap.put( yname.getId(),myname);
studentmap.put(mrx.getId(),mrx);
studentmap.put(msx.getId(),msx);
Then when someone types 'remove', followed by the Id, you can delete like you want/wrote:
studentmap.remove(theid); // remove student 'myname' if 1234

Storing name, language mark ,english mark , and math mark. Getting the average of the three marks. I am not sure how to continue

This is how much I have done so far.
I am unsure how to continue from here.
Should I be using double for loops for a problem like this?
public class testing {
public static void main(String[] args) throws IOException{
Scanner sc = new Scanner(System.in);
System.out.println("How many people?");
String input = sc.nextLine();
int z = Integer.parseInt(input);
for(int i =0; i <=z; i++) {
System.out.println("Name,Language,English,Math?");
String input2 = sc.nextLine();
String[] myArr = new String[] {input2};
for(int j = 0; j<4; j++) {
String [] myArr1 = myArr[j].split(",");
System.out.println(myArr1[0]);
}
//System.out.println(myArr[0]);
//student student1 = new student(myArr[i]);
for(int j = 0; j< 4; j++) {
String[] studentpl = myArr[i].split(",");
}
//ArrayList<student> aList = new ArrayList<student>();
//aList.add(input2);
//student1 student new student1();
//student stu = new student(input);
}
}
}
First you need to make a list that will hold all the students. Also it might be useful to make a student class that will hold the students attributes (name, language, english, math). After getting the input for the number of students to be processed you can loop in getting the students data. Once you get the student data from the input, make an instance of a Student class and set all those acquired data to the class. Once all data has been set you then add the Student to your student list. I have included a sample code below, but this code does not have error checking in the inputs. For example you can do checking if the input for numberOfStudents is valid. This code can be improved but for simplicity sake I have disregarded those checking.
Here is the main class
public class Testing {
public static void main(String[] args) throws IOException{
Scanner sc = new Scanner(System.in);
System.out.println("How many people?");
int numberOfStudents = sc.nextInt();
ArrayList<Student> studentList = new ArrayList<Student>();
for(int i = 0; i < numberOfStudents; i++) {
System.out.println("Name,Language,English,Math?");
String dataInput = sc.nextLine();
String[] dataInput = dataInput.split(",");
// You can add here checking if the dataInput is valid. Example if it really contains all the needed input by checking the size of dataInput
Student student = new Student();
student.setName(dataInput[0]);
student.setLanguage(dataInput[1]);
student.setEnglish(dataInput[2]);
student.setMath(dataInput[3]);
studentList.add(student);
}
}
}
Here is the Student class. You should import this class to your main class.
public class Student {
private name;
private language;
private english;
private math;
// insert here getter and setter methods for each attribute
}
This should get you started:
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
System.out.println("How many people?");
int input = sc.nextInt(); sc.nextLine();
ArrayList<Student> students = new ArrayList<Student>();
for (int i = 0; i < input; i++) {
System.out.println("Name, Language, English, Math?");
String input2 = sc.nextLine();
String[] myArr = input2.split("[, ]+");
students.add(new Student(myArr[0], tryParse(myArr[1]), tryParse(myArr[2]), tryParse(myArr[3])));
}
for(Student s : students)
System.out.println(s.name);
}
public static double tryParse(String grade) {
return Double.parseDouble(grade);
}
}
class Student{
public String name;
public double language;
public double english;
public double math;
public Student(String name, double language, double english, double math) {
this.name = name;
this.language = language;
this.english = english;
this.math = math;
}
}
Try not to start class names with lowercase letters. It's bad practice.

Returning and displaying contents of ArrayList in different class?

I'm working on a project where I will tally a Student's choices and add them to a count array (still working on this part). For now, I'm trying to retrieve the choices that have been sent and added to a Student ArrayList in my Student class.
Student class:
public class Students {
private String name;
private ArrayList<Integer> choices = new ArrayList<Integer>();
public Students(){
name = " ";
}
public Students(String Name){
name = Name;
}
public void setName(String Name){
name = Name;
}
public String getName(){
return name;
}
public void addChoices(int Choices){
choices.add(Choices);
}
public ArrayList<Integer> getChoices(){
return choices;
}
Here is my main driver class:
public class P1Driver {
public static void main(String[] args) throws IOException{
ArrayList<Students> students = new ArrayList<Students>();
String[] choices = new String[100];
int[] count;
Scanner scan1 = new Scanner(new File("Choices.txt"));
Scanner scan2 = new Scanner(new File("EitherOr.csv"));
// Scan the first file.
int choicesIndex = 0;
while(scan1.hasNextLine()){
String line = scan1.nextLine();
choices[choicesIndex] = line;
choicesIndex++;
}
scan1.close();
// Scan the second file.
int studentIndex = 0;
while(scan2.hasNextLine()){
String line = scan2.nextLine();
String [] splits = line.split(",");
students.add(new Students(splits[0]));
for(int i = 1; i < splits.length; i++){
students.get(studentIndex).addChoices(Integer.parseInt(splits[i]));
}
studentIndex++;
}
scan2.close();
// Instantiate and add to the count array.
int countIndex = 0;
for(int i = 0; i < students.size(); i++){
if(students.get(i).getChoices(i) == -1){
}
}
The last part is where I am now. It's nowhere near done obviously (I'm right in the middle of it) but during my construction of a for loop to get the choices from the students, I'm getting an error that says, "The method getChoices() in the type Students is not applicable for the arguments (int)." Can someone explain what this means, where me error is, and possibly how to fix it? Thanks all.
getChoices(int i) is not a method you've defined.
if(students.get(i).getChoices(i) == -1){
}
getChoices() returns a list, so you can just use the get method on the list:
if(students.get(i).getChoices().get(i) == -1){
}
Alternatively, make a getChoice method:
public Integer getChoice(int i){
return choices.get(i);
}
Have you tried getChoices()[i] instead of getChoices(i)

How to sort an ArrayList by a users last name

How do I sort an ArrayList by a users last name? My program prints out the names in order by first name. Is there another collections.sort(..); method? Or a way without making a map.
public static void main(String[] args) throws FileNotFoundException {
String check = "y";
do {
Scanner fileRead = new Scanner(System.in);
System.out.println("Enter the name of the file: ");
File myFile = new File(fileRead.next());
ArrayList<String> names = new ArrayList<>();
Scanner scanTwo = new Scanner(myFile);
while (scanTwo.hasNextLine()) {
names.add(scanTwo.nextLine());
}
Collections.sort(names);
for (String name : names) {
System.out.println(name);
}
System.out.println();
Scanner ans = new Scanner(System.in);
System.out.println("Add another? y/n ");
check = ans.next();
} while (check.equals("y"));
}
Use Person class which would implement Comparable<Person> interface like:
public class Person implements Comparable<Person> {
String fname;
String lname;
//getter setter
public int compareTo(Person person) {
int comparedFname = this.fname.compareTo(person.getFname());
if (comparedFname == 0) {//if fname are same then compare by last name
return this.lname.compareTo(person.getLname());
}
return comparedFname;
}
}
Then you can create list of Person object and use Collections.sort method to sort your list.

How should I parse this in Java?

I'm having trouble understanding how to parse text documents with unknown amounts of 'students'. All my solutions are coming up strange and I'm having trouble with the Scanner. Breaking down the input, the first integer represents how many classes there are, the first string is the class name, the following are students with respective dates and variables that need to be stored along with the student, with an unknown amount of students. I want to store each student along with the class they are in.
My code is extremely messy and confusing so far:
String filename = "input.txt";
File file = new File(filename);
Scanner sc = new Scanner(file);
Student[] studArr = new Student[100];
int studCounter = 0;
boolean breaker = false;
boolean firstRun = true;
int numClasses = sc.nextInt();
System.out.println(numClasses);
while(sc.hasNextLine()){
String className = sc.nextLine();
System.out.println("Name: " + className);
String test = null;
breaker = false;
sc.nextLine();
// Breaks the while loop when a new class is found
while (breaker == false){
Student temp = null;
// Boolean to tell when the first run of the loop
if (firstRun == true){
temp.name = sc.nextLine();
}
else
temp.name = test;
System.out.println(temp.name);
temp.date = sc.nextLine();
if (temp.date.isEmpty()){
System.out.println("shit is empty yo");
}
temp.timeSpent = sc.nextInt();
temp.videosWatched = sc.nextInt();
temp.className = className;
studArr[studCounter] = temp;
studCounter++;
sc.nextLine();
test = sc.nextLine();
firstRun = false;
}
}
}
}
class Student {
public String name;
public String date;
public String className;
public int timeSpent;
public int videosWatched;
}
I don't need an exact answer, but should I be looking into a different tool then Scanner? Is there a method I can research?
Thanks for any assistance.
I came up with the following solution. Scanner is a fine tool for the job. The tricky part is that you have to sort of look ahead to see if you have a blank line or a date to know if you have a student or a class.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Parser {
private static String nextLine(Scanner sc) {
String line;
while (sc.hasNext()) {
if (!(line = sc.nextLine()).isEmpty()) {
return line;
}
}
return null;
}
public static ArrayList<Student>[] parseFile(String fileName) {
File file = new File(fileName);
try (Scanner sc = new Scanner(file)) {
int numClasses = sc.nextInt();
String className = nextLine(sc);
ArrayList<Student>[] classList = new ArrayList[numClasses];
for (int i = 0; i < numClasses; i++) {
classList[i] = new ArrayList<>();
while (true) {
String studentOrClassName = nextLine(sc);
if (studentOrClassName == null) {
break;
}
String dateOrBlankLine = sc.nextLine();
if (dateOrBlankLine.isEmpty()) {
className = studentOrClassName;
break;
}
int timeSpent = sc.nextInt();
int videosWatched = sc.nextInt();
classList[i].add(new Student(className, dateOrBlankLine, studentOrClassName, timeSpent,
videosWatched));
}
}
return classList;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return new ArrayList[0];
}
public static void main(String[] args) {
for (ArrayList<Student> students : parseFile("classList.txt")) {
if (!students.isEmpty()) {
System.out.println(students.get(0).className);
}
for (Student student : students) {
System.out.println(student);
}
}
}
static class Student {
public String className;
public String date;
public String name;
public int timeSpent;
public int videosWatched;
public Student(String className, String date, String name, int timeSpent,
int videosWatched) {
this.className = className;
this.date = date;
this.name = name;
this.timeSpent = timeSpent;
this.videosWatched = videosWatched;
}
public String toString() {
return name + '\n' + date + '\n' + timeSpent + '\n' + videosWatched + '\n';
}
}
}
Ask yourself, what does a Student contain? A name, date, number and number. So you want to do the following (not actual code) (format written in Lua code, very understandable. This means this will not run in Lua :P)
if line is not empty then
if followingLine is date then
parseStudent() // also skips the lines etc
else
parseClass() // also skips lines
end
end

Categories

Resources