Sorting Student names - java

im having a trouble finishing my work because i dont know how to do the sorting of names together with the grade in ascending and descending. i hope you guys can help.
import java.util.Scanner;
public class SortingStudents {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter the number of students: ");
int capacity = s.nextInt();
String [] name = new String[capacity];
Double [] grade = new Double[capacity];
for(int i = 0; i < capacity; i++) {
System.out.print("student's name: ");
name [i] = s.next();
System.out.print("grade: ");
grade [i] = s.nextDouble();
}
Scanner input = new Scanner(System.in);
System.out.println("Type A for Ascending D for Descending:");
char a=input.nextLine().charAt(0);
if(a == 'A' || a == 'a'){
for(int i = 0; i<grade.length;i++){
System.out.println(grade[i]+"\t" +grade[i]);
}
}
}

You are using Java, which is an object-oriented programming language. This means you can think about your problem in terms of classes which represent state in your problem domain and have behavior (methods) which manipulate this state.
In this case your code shows several responsabilities, for which you could create useful classes and/or methods:
entering data via the command line (number of students, name and grade and desired sorting direction)
a registry of students with a fixed size
sorting the student registry in the desired direction
Class names that come to mind are: DataEntry, Student, StudentRegistry. For sorting the students in different ways the standard approach is creating a Comparator class, see below.
The classes could look roughly like this:
public class Student {
private String name;
private Double grade;
// getters and setters ommitted for brevity
}
The registry:
public class StudentRegistry {
// it's easier to use a List because you are adding students one by one
private List<Student> students;
public StudentRegistry(int capacity) {
// ...constructor code initializes an instance of StudentRegistry
}
public void addStudent(Student student) {
// add a student to the list
}
public Student[] getStudents(Comparator<Student> comparator) {
// sort the list using the comparator and Collections.sort()
// use List.toArray() to convert the List to an array
// alternatively (java 8) return a Stream of Students
// or return an unmodifiable List (using Collections.unmodifiableList())
// you don't want to expose your modifiable internal List via getters
}
}
A comparator which can sort Ascending or Descending. You could consider adding the capability to sort either by grades or by names, that would be quite easy.
public class StudentComparator implements Comparator<Student> {
public enum Direction {
ASCENDING, DESCENDING
}
// optional addition:
//public enum Field{
// NAME, GRADE
//}
// if used, add Field parameter to the constructor
public StudentComparator(Direction direction) {
// initialize instance
}
#Override
public int compare(Student a, Student b) {
// implement Comprator method, see JavaDoc
}
#Override
public boolean equals(Object o) {
// implement equals, see JavaDoc
}
}
Class for letting the user enter data:
public class DataEntry {
public int getNumberOfStudents() {
// ...
}
public Student getStudent() {
// ...
}
public StudentComparator.Direction getSortingDirection() {
// ...
}
}
And a main class:
public class Main {
public static void main(String[] args) {
DataEntry dataEntry = new DataEntry();
int capacity = dataEntry.getCapacity();
StudentRegistry studentRegistry = new StudentRegistry(capacity);
for(int i=0; i<= capacity; i++) {
studentRegistry.addStudent(dataEntry.getStudent());
}
StudentComparator comparator = new StudentComparator(dataEntry.getSortingDirection());
Student[] students = studentRegsitry.getStudents(comparator);
}
}
This approach separates concerns of your problem in separate classes and methods, making the code much easier to understand, debug and test.
For example, to test the Main class you could set up a mock DataEntry class which provides predetermined values to your test. See the topic of unit testing.

If you want to do it your way without changing how the arrays are stored separately. You will not be able to use the Arrays.sort() method to sort your grades because that will not take the name array into account and you will lose the link between them so that the grades will no longer match with the names.
You could very quickly code up your own bubble sorter to quickly sort the array, and then you could use your loop to affect the name array at the same time. But if you don't want to code your own sorter, you will need to organise your grades and names array so that can be treated as one unit i.e in a separate class.
If you choose to code your own sorter then here is a great link to learn that: http://www.java-examples.com/java-bubble-sort-example
If you choose to change the way that you store the grades and names, here is how you can use the Arrays.sort() method:
http://www.homeandlearn.co.uk/java/sorting_arrays.html

You could just concatenate the name and grade and sort them, that way it could be a lot easier.

Related

Access elements of arraylist of arraylist of arraylist?

I am new to Java, and I am currently using BlueJ for a project. I am having troubles accessing the objects inside an ArrayList of an ArrayList of such objects. Say I have a Student object:
public class Student
{
private String homeAddress;
private String monthBorn;
private String yearBorn;
private int;
public Student(String homeAddress, String monthBorn, String yearBorn,
int finalGrade)
{
this.homeAddress = homeAddress;
this.monthBorn = monthBorn;
this.yearBorn = yearBorn;
this.finalGrade = finalGrade;
}
}
And then methods to get address, month, year and grade. Then I have a class Class, which is an ArralyList of Student objects:
public class Classroom
{
private String classroom;
private ArrayList<Student> listOfStudents;
public Classroom (String classroom)
{
this.classroom = classroom;
listOfStudents = new ArrayList<Student>();
}
}
And this class includes methods to add Student objects, to list all the students in the class (listAllStudentsInClassroom) which returns an ArrayList of Student, to find the Student with the highest grade in the class (getHighestGradeStudent), and to a list of students with grades higher than a certain amount.
Finally, the class School, which is an ArrayList of Classroom:
public class School
{
private ArrayList<Classroom> school;
public School()
{
school = new ArrayList<Classroom>();
}
}
This includes methods to add a class object, and it should include methods to return the Student with the highest grade ever and a list of students from all classes with grades higher than a certain one. However, I can only get the methods to iterate through only the first class added! Here is the code for getHighestGradeStudentEver so far:
public Student getHighestGradeStudentEver ()
{
Student s = school.get(0).getHighestGradeStudent();
int highestGrade = school.get(0).listAllStudentsInClassroom().get(0).getFinalGrade();
for(int i =1; i< school.size(); i++){
int highestGrade = school.get(i).listAllStudentsInClassroom().get(i).getFinalGrade();
if(value > (highestValue)){
highestValue = value;
s = school.get(i).getHighestGradeStudent();
}
}
return s;
}
This only returns the student with the highest grade from the first classroom object added to School. What am I doing wrong? Sorry for the long question, I tried to be as clear as possible!
If you can already get the highest graded student in a class, you can get that for all the classes, and find the highest grade out of all of those.
// find the highest grade in each class
ArrayList<Student> highestInEachClass = new ArrayList<>();
for (Classroom classroom : school) {
highestInEachClass.add(classroom.getHighestGradeStudent());
}
// find the highest grade overall
Student highestGradeStudent = highestInEachClass.get(0);
for (Student student : highestInEachClass) {
if (highestGradeStudent.getFinalGrade() < student.getFinalGrade()) {
highestGradeStudent = student;
}
}
return highestGradeStudent;
Alternatively, use Stream:
return school.stream().flatMap(x -> x.getListOfStudents().stream())
.sorted(Comparator.comparing(Student::getFinalGrade).reversed())
.findFirst().orElse(null);
As I understand your question, you already have a function Classroom.getHighestGradeStudent() which gives you the best student of that class. You also have a way to get the grade of a given student, since the Student object contains .finalGrade.
You want to loop through all classrooms in the school, and find the student with the highest grade.
So you have your for loop, which iterates over the classrooms. And for every classroom, you get some arbitrary student's final grade:
int highestGrade = school.get(i).listAllStudentsInClassroom().get(i).getFinalGrade();
^
This is likely not what you want. Instead, you want the best student's grade from that classroom. For that, you should instead use
int highestGrade = school.get(i).getHighestGradeStudent().getFinalGrade();
(If my assumption is wrong and you do not have a function getHighestGradeStudent() of a given classroom, you would need to loop over the result of listAllStudentsInClassroom() (or store that list sorted))
Then, you can continue with your code as you're doing, by updating the stored best student s if the best student of the current classroom is better than what you previously had in s.
But make sure you use either highestGrade or highestValue, not both of them. As your code stands, I don't see highestValue defined anywhere.
Note, that it's possible to make this code more efficient, if you only search for the best student in a given class once. I would do
Student bestOfClassroom = school.get(i).getHighestGradeStudent();
int highestGrade = bestOfClassroom.getFinalGrade();
so you already have your student to store in s by simply doing s = bestOfClassroom instead of searching through the whole list again.
But this is an optimization that should not be relevant for the Correctness of your program.

Finding specific instance of class? [duplicate]

This question already has answers here:
How to find an object in an ArrayList by property
(8 answers)
Closed 5 years ago.
I've just started learning java and I'm trying to create an application to register students.
Based on this question how-would-i-create-a-new-object... I created a while loop to create an instance of a class.
public class RegStudent {
ArrayList<Student> studentList = new ArrayList<>();
Scanner input = new Scanner(System.in);
public void reggaStudent(int start) {
while (start != 0) {
String programNamn, studNamn;
int totalPoint, antalKurser;
System.out.println("Vad heter programmet?");
programNamn = input.nextLine();
System.out.println("Vad heter studenten");
studNamn = input.nextLine();
System.out.println("Hur många poäng har studenten?");
totalPoint = input.nextInt();
System.out.println("Hur många kurser är studenten registrerad på?");
antalKurser = input.nextInt();
// Add student to list of students
studentList.add(new Student(totalPoint, antalKurser,
programNamn, studNamn));
System.out.println("Vill du registrera in en fler studenter? "
+ "Skriv 1 för ja och 0 för nej");
start = input.nextInt();
input.nextLine();
} // End of whileloop
}
}
The class is:
public class Student {
private int totalPoint;
private int antalKurser;
private String programNamn;
private String studNamn;
private static int counter;
public Student(int totalPoint, int antalKurser, String program, String studNamn) {
this.totalPoint = totalPoint;
this.antalKurser = antalKurser;
this.programNamn = program;
this.studNamn = studNamn;
counter++;
}
public int getTotalPoint() {
return totalPoint;
}
public void setTotalPoint(int totalPoint) {
this.totalPoint = totalPoint;
}
public int getAntalKurser() {
return antalKurser;
}
public void setAntalKurser(int antalKurser) {
this.antalKurser = antalKurser;
}
public String getProgramNamn() {
return programNamn;
}
public void setProgramNamn(String programNamn) {
this.programNamn = programNamn;
}
public String getStudNamn() {
return studNamn;
}
public void setStudNamn(String studNamn) {
this.studNamn = studNamn;
}
public static int getCount(){
return counter;
}
#Override
public String toString() {
return String.format(" Namn: %s, Program: %s, Antal poäng: %d, "
+ "Antal kurser: %d\n ", studNamn, programNamn, totalPoint, antalKurser);
}
}
How do I go about to get and set the instance variables in specific instance? I.e find the instances.
I understand it might be bad design but in that case I would appreciate some input on how to solve a case where i wanna instantiate an unknown number of students.
I've added a counter just to see I actually created some instances of the class.
You simply query objects for certain properties, like:
for (Student student : studentList) {
if (student.getProgramName().equals("whatever")) {
some match, now you know that this is the student you are looking for
In other words: when you have objects within some collection, and you want to acquire one/more objects with certain properties ... then you iterate the collection and test each entry against your search criteria.
Alternatively, you could "externalize" a property, and start putting objects into maps for example.
studentList.add(new Student(totalPoint, antalKurser,
programNamn, studNamn));
You now have your Student objects in a list. I assume you have something like
List<Student> studentList = new ArrayList<>();
somewhere in your code. After you populate the list with Student objects, you can use it to find instances. You need to decide what criteria to use for a search. Do you want to find a student with a specific name? Do you want to find all students in a given program? Do you want to find students with more than a certain number of points?
Maybe you want to do each of these. Start by picking one and then get a piece of paper to write out some ideas of how you would do the search. For example, say you want to find a student with the name "Bill". Imagine that you were given a stack of cards with information about students. This stack of cards represents the list in your program. How would you search this stack of cards for the card with Bill's name on it? Describe the steps you need to take in words. Don't worry about how you will code this yet. The first step in writing a computer program is breaking the solution down into small steps. After you have a clear idea how you might do this by hand in the physical world, you can translate your description into Java code.

Can't add objects to priority queue

I need to add a Jedi object to a queue. None of the add methods that I know are working and all give the "cannot find symbol - method add(jedi1).I didn't learn much about Queues in my last class so I'm not exactly sure what I'm doing. Other things to note are 3 specifics of this.
1)Modify the heap operations to keep the maximum – rather than the minimum – element in the root. Refer to the Heap lab assignment for the algorithm.
2) Utilize an array with a varying size limit (if <10% utilization reduce it by half; if full, double the size).
3) Implement the heap to receive any generic object with a comparable method.
4) Allow for duplicate value with the following rule: If a duplicate value is entered, the new element with similar value should be considered to have less priority than an existing element.
public class PriorityQueue<JediQ>
{
Scanner reader = new Scanner(System.in);
public void main(String[] args)
{
while (true)
{
System.out.println("Please select an option");
System.out.println("1 - Add a Jedi ");
System.out.println("2 - Remove an element");
System.out.println("3 - Print head value");
System.out.println("4 - Compare value to head value");
System.out.println("5 - Print Array");
System.out.println("6 - Exit");
int x = 0;
x = reader.nextInt();
if (x == 1)
{
PriorityQueue<JediQ> line = new PriorityQueue<JediQ>();
System.out.println("Enter the name of the Jedi");
String Name = reader.next();
System.out.println("Enter the midi count");
double midi = reader.nextInt();
Jedi jedi1 = new Jedi(Name, midi);
line.add(jedi1);
System.out.print("Jedi was added");
}
if (x == 6)
{
System.exit(0);
}
}
}
}
Your problem is a vast lack of basic knowledge about everything; so I give you some things to start with:
First of all, that error message means: your implementation of that PriorityQueue ... does not have an add() method. Because: you didn't write it! So you start with something like:
public class PriorityQueue<T> {
public void add(T newElement) { ...
Which leads to the second major problem: the usage of generic types. As you can see in my example, you say: "my queue class, should be accepting any kind of object". And only later on, when instantiating a queue object; then you declare that this instance should be for Jedis, like:
PriorityQueue<Jedi> jedis = new PriorityQueue<>();
jedies.add(lukeSkywalkerHisUnknownCousin);
But of course, the real fun within this exercise is the implementation of a priority queue, so that it provides all the methods that a queue should have; and that they work as outlined in your assignment! And obviously, that is your assignment, so I leave that as exercise to the reader!
Final hint: if you want to understand the methods you ought to implement, you can have a look at java's own PriorityQueue and its methods!
Use below method.
line.offer(yourObject);
Please read the basics of collections framework. You able to add/ modify / delete objects out of any collections because the wrapper classes have provided the methods for that.
For eg. When you add int ( that becomes Integer as collection only stores Object). the default Comparator is used. as below:
public class PriorityQueueExample
{
public static void main(String[] args)
{
//Creating a PriorityQueue with default Comparator.
PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
//Inserting elements into pQueue.
pQueue.offer(21);
pQueue.offer(17);
//Removing the head elements
System.out.println(pQueue.poll());
To add custom objects in any collection you need to use either Comparator or Comparable.
class JediQ
{
String name;
int midi;
//Constructor Of JediQ
public JediQ(String name, int midi)
{
this.name = name;
this.midi = midi;
}
#Override
public String toString()
{
return name+" : "+midi;
}
}
and then adding the object as below:
class MyComparator implements Comparator<JediQ>
{
#Override
public int compare(JediQ e1, JediQ e2)
{
return e1.name - e2.name;
}
}
MyComparator comparator = new MyComparator();
PriorityQueue<JediQ> pQueue = new PriorityQueue<JediQ>(7, comparator);
pQueue.offer(new JediQ("AAA", 150));

Insert Object into Java Array

I got from my teacher the next assignment -
I need to build a Course class and Student class
and to insert every Student into the Course class
Each Student has an Id,name and grade.
I have tried the next code:
public class Course {
Student[] android = new Student[100];
private void addStudent(Student a) {
for (int i=0;i<android.length;i++) {
if (android[i] == null) {
android[i] = a;
break;
}
}
}
public static void main(String[] args) {
addStudent(Joe);
}
}
I need to insert a Student that i have created in the Students class to the first null position in the array.
When i try addStudent(Joe); it gives me an error : "Joe cannot be resolved to a variable"
The Student class code:
public class Student {
private float grade;
private String name;
private long id;
public Student(long c,String b,float a) {
grade = a;
name = b;
id = c;
}
public static void main(String[] args) {
Student Joe = new Student(1,"Joe",40);
}
**The array holds 100 students (null at start)
When adding a student - i need to check for the first null value in the array and put it
there
When printing the students: i need to print only the non-null Objects in the array**
This code
Array[] Android = new Array[100];
is creating an array of type Array, so you can only store Array objects in it.
If you want to store Students, you need to create an array that, instead:
Student[] android = new Student[100];
Also, you need to realize that arrays in Java are indexed from 0. That is, you cannot reference a position that is the same as the size of the array. In your case, you have made
an array with 100 elements, but your for-loop is trying to put 101 objects in it.
Furthermore, your question text implies you only want to insert the new Student object once, but your loop puts it into every empty location in your array.
Try this instead:
for (int i=0;i<android.length;i++) { // < instead of <=, don't hardcode the length
if (android[i] == null) {
android[i] = a;
break; // once we insert a, stop looping
}
}
Update
The reason that the compiler can't find Joe is an issue of scope. You have declared Joe as a local variable in the main() method in the Student class. If you want the compiler to be able to see it, you need to declare it in the same method you are using it:
public static void main(String[] args) {
Student Joe = new Student(1,"Joe",40);
addStudent(Joe);
}
A quick google search of "Java variable scope tutorial" should give you plenty of reading about how and when you can use local and member variables.
insert method of student S (1111,"ahmed",3.5)in the position "p" in array of students(id,name,GBG)array size 100 and curent size =3.
-remove method that remove the student having GBG =2.5from the array of student .array size 100 and currentsize=3
First, change the
Array[] Android = new Array[100];
to
Student[] listOfStudent = new Student[100];
What this does is creates a array of size 100, and the type of the array is Students, which is what you will be inserting into the array. You are also going to have to change
for (int i=0;i<=100;i++) {
if (Android[i] == null) {
Android[i] = a;
}
}
to
for(int i=0; i < listOfStudents.length; i++){
if(listOfStudents[i] == null){
listOfStudent[i] = a;
}
}
otherwise you will get a "List Out of Bounds" error. It is better to not hard code values into your code - good practice for the future!
Good Luck!

Understanding ArrayLists and how they are used for a TUI

Beforehand: This is a homework assignment so I need answers with explanations.
I am a first year student and my teacher is extremely vague while teaching so
I need some help understanding how to use the ArrayList in his instructions.
**I just need help understanding how this all works. I'm writing the code but I don't know how any of it works.
The Textual User Interface is supposed to be written in another class that I haven't done yet.**
My instructions were:
GradeManager Class 
Start by developing a class to describe a GradeManager. Because this exercise is far more about writing an interactive application, we'll keep this class SIMPLE. Our GradeManager will just keep track of an ArrayList of scores and define the following methods:
A single constructor that accepts no parameters, but sets up the ArrayList so that it is 
capable of holding some scores 
A method called addScore that will accept a score and add it to the ArrayList 
A method called getAverage that will return the average of all scores in the ArrayList
GradeTUI Class 
This class will keep track of a GradeManager object as an instance variable.  You will need to write a 
constructor that accepts the GradeManager object that it will be using.  
 
This class will also contain a method named run.  This method will give the user the ability to either (1) 
enter a score to be stored (in the GradeManager object) or (2) display the average of all scores entered 
so far.  Allow the user to continue this program by choosing one of these options until they are finished. 
 
Driver Class 
Once you are satisfied that these classes are defined and working properly, develop a driver class 
containing a main method that will create an instance of GradeManager, pass this object to the 
GradeTUI constructor, and then use the GradeTUI object to call run. 
This is what I wrote:
public class GradeManager {
private ArrayList<Integer> gradeList;
public GradeManager() {
ArrayList<Integer> gradeList = new ArrayList<Integer>();
this.gradeList = gradeList;
}
public void addScore(int score) {
this.gradeList.add(score);
}
public double getAverage(ArrayList<Integer> gradeList) {
Integer aScore = 0;
if (!gradeList.isEmpty()) {
for (Integer grade : gradeList) {
aScore += grade;
}
return aScore.doubleValue() / gradeList.size();
}
return aScore;
}
}
First: I think the getAverage Method should use the internal ArrayList instead of a parameter.
Otherwise you don't have any read access to that lists contents.
You can use your GradeManager in the following way:
GradeManager manager = new GradeManager();
while(condition) {
int score = readScoreFromInput();
manager.addScore(score);
}
double averageScore = manager.getAverage();
print(averageScore);
So you get the average of all the scores you have just input.
The concrete implementation of the loop (and the exit condition) is up to you - it could be a predefined number of iterations or a special input like -1 for example.

Categories