Reputation: 181
I have a text file which looks something like this:
6
3.3 John Rodgers
3.9 Jim Braash
3.5 Kathy Calderon
3.2 Steve Hernandez
2.4 Stacy Lu
2.8 Faith Simmons
I've already written a Student
class, which has basic functions:
package com.company;
public class Student {
private String firstName;
private String lastName;
private double grades;
public Student(String firstName, String lastName, double grades) {
this.firstName = firstName;
this.lastName = lastName;
this.grades = grades;
}
@Override
public String toString() {
return lastName + ", " + firstName + ", " + grades;
}
@Override
public boolean equals(Object obj) {
if(obj == null){
return false;
}
Student other = (Student) obj;
if (other.firstName.equals(this.firstName) && other.lastName.equals(this.lastName) && other.grades == this.grades) {
return true;
} else {
return false;
}
}
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public double getGrade() {
return this.grades;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setGrades(double grades) {
this.grades = grades;
}
}
And this is my Main
class:
package com.company;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
Student[] s = initialize();
Student max = maxIndex(s);
Student min = minIndex(s);
double avg = avg(s);
flush(max, min, avg);
}
public static void flush(Student max, Student min, double avg) throws FileNotFoundException {
DecimalFormat df = new DecimalFormat("#.#");
double avgFormatted = Double.parseDouble(df.format(avg));
PrintWriter writer = new PrintWriter("final.txt");
writer.write("Highest: " + max);
writer.write("\n");
writer.write("Lowest: " + min);
writer.write("\n");
writer.write("Average GPA: " + avgFormatted);
writer.close();
}
public static Student[] initialize() throws FileNotFoundException {
Scanner reader = new Scanner(new File("data.txt"));
int size = reader.nextInt();
Student[] students = new Student[size];
int index = 0;
while (reader.hasNextLine()) {
double grades = reader.nextDouble();
String firstName = reader.next();
String lastName = reader.next();
Student student = new Student(firstName, lastName, grades);
students[index] = student;
index++;
}
return students;
}
public static double avg(Student[] students) {
double avg = 0;
double sum = 0;
for (int i = 0; i < students.length; i++) {
sum += students[i].getGrade();
avg = sum / students.length;
}
return avg;
}
public static Student maxIndex(Student[] students) {
int max = 0;
for (int i = 1; i < students.length; i++) {
if (students[i].getGrade() > students[max].getGrade()) {
max = i;
}
}
return students[max];
}
public static Student minIndex(Student[] students) {
int min = 0;
for (int i = 1; i < students.length; i++) {
if (students[i].getGrade() < students[min].getGrade()) {
min = i;
}
}
return students[min];
}
}
So, my question involves dealing with the file. Let's say I added the name Jim Braash again into my file without changing the integer at the top. So my file looks like this:
6
3.3 John Rodgers
3.9 Jim Braash
3.9 Jim Braash
3.5 Kathy Calderon
3.2 Steve Hernandez
2.4 Stacy Lu
2.8 Faith Simmons
Even though there are 7 lines, there are still only 6 students because one is repeated. I already implemented the equals()
method in my Student
class, but I am unable to figure out how I would skip the line in the main()
method and still have the same results as before. Thanks.
Upvotes: 2
Views: 140
Reputation: 2268
The other answers have good ideas. But, if you just want a simple way to do it using your equals()
method from your Student
class, you could try the following for your initialize()
method:
public static Student[] initialize() throws FileNotFoundException {
Scanner reader = new Scanner(new File("data.txt"));
int size = reader.nextInt();
Student[] students = new Student[size];
int index = 0;
while (reader.hasNextLine()) {
double grades = reader.nextDouble();
String firstName = reader.next();
String lastName = reader.next();
Student student = new Student(firstName, lastName, grades);
boolean duplicate = false;
for (int i = 0; i < students.length; i++) {
if (student.equals(students[i])) {
duplicate = true;
break;
}
}
if (!duplicate) {
students[index] = student;
index++;
}
}
reader.close(); // <--- Make sure to close the Scanner
return students;
}
Let me know if this works for you.
Upvotes: 1
Reputation: 518
Instead of array of Student, try use Set of student
A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element.
This data type have only unique item.
EDIT 1 With array
while (reader.hasNextLine()) {
Double grades = Double.valueOf(reader.next());
String firstName = reader.next();
String lastName = reader.next();
Student student = new Student(firstName, lastName, grades);
if (Arrays.stream(students).noneMatch(s -> student.equals(s))) {
System.out.println(student);
students[index] = student;
index++;
}
}
EDIT 2
You can replace max, min, avg calculation with streams
public static void main(String[] args) throws FileNotFoundException {
Student[] s = initialize();
Student max = Arrays.stream(s).max(Comparator.comparing(student -> student.getGrade())).orElse(null);
Student min = Arrays.stream(s).min(Comparator.comparing(student -> student.getGrade())).orElse(null);
double avg = Arrays.stream(s).map(student -> student.getGrade()).reduce(0d, (x,y) -> x + y).doubleValue() / s.length;
flush(max, min, avg);
}
Upvotes: 0
Reputation: 5345
Use HashSet<Student>
instead of Student[]
and override hascode
to conform to your equals
. You won't have any duplicates any more.
Be aware that you can cause serious problems with wrong implementations of equals
and hashcode
. Properties that are used in this methods shouldn't be modified. This would cause possible duplicates and/or that you may not be able to accesss or remove the modified element in a HashSet
.
Upvotes: 2