0

I am trying to write a method which will take an ArrayList of Student objects and return me a String array with the names of the Students in the order of their scores (student name with highest score will be at index 0).

public static void orderStudent(List<Student> ls) {

    for (Student stu : ls) {
        System.out.println("Name: " + stu.getName() + ", Score: "
                + stu.getScore());
    }
}

The above snippet when executed will print something like

Name: Alex, Score: 10.35
Name: Bob, Score: 11.2
Name: Charles, Score: 8.22

I want the orderStudent method to return a String array which would have the contents [Bob, Alex, Charles] Bob being the top scorer followed by Alex and Charles.

5
  • Which Java are you using(is it 8)? Commented Jan 15, 2015 at 3:12
  • ... return me a String array ... First step to that would be make the method Student[], not void. Commented Jan 15, 2015 at 3:17
  • Ofcourse. I had posted the method as is. The return type would be changed to Student[] and the method will have a return studarray; statment at the end. Commented Jan 15, 2015 at 3:24
  • 1
    Actually the return type should be String[] Commented Jan 15, 2015 at 3:25
  • Thanks Jason. The method just returns the Student names in a String array. Commented Jan 15, 2015 at 3:27

5 Answers 5

2

First you need to sort your List and then you need to construct String[]

You can use CompareToBuilder class without making any changes to your existing POJO class.

On CompareToBuilder you need to add the property on which you need to sort your collection. You can see the below code:

import org.apache.commons.lang3.builder.CompareToBuilder;
...

public static String[] orderStudent(List<Student> list) {

    String[] students = new String[list.size()];

    Collections.sort(list, new Comparator<Student>() {
        @Override
        public int compare(Student object1, Student object2) {
            return new CompareToBuilder().append(object2.getScore(), object1.getScore()).toComparison();
        }
    });

    for (int index = 0; index < list.size(); index++) {
        Student student = list.get(index);
        students[index] = student.getName();
        System.out.println("Name: " + student.getName());
    }

    return students;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Instantiating a CompareToBuilder each time a comparison is made is inefficient, especially given that the comparison is so simple.
@Jason is there any other way to do this without writing the comparison logic if I have to sort based on multiple fields
What would be ideal is if the CompareToBuilder could somehow be constructed outside the compare method, so that it doesn't get constructed for each comparison. But I don't think that is possible. It is inefficient in this instance because we are only comparing one field, so writing the actual comparison is better.
I've edited my answer to show how simple it could be.
2

If Student implements the Comparable interface and sorts by Score, then you simply sort the list, and build your array of names.

If you can't edit the Student class, you need to write a class that implements Comparator<Student> and use that to sort the list and then build your array of names.

Simplifying @PrasadKhode's answer:

public static String[] orderStudent(List<Student> list) {

    String[] students = new String[list.size()];

    Collections.sort(list, new Comparator<Student>() {
        @Override
        public int compare(Student object1, Student object2) {
            return Integer.compare(object2.getScore(), object1.getScore());
        }
    });

    for (int index = 0; index < list.size(); index++) {
        Student student = list.get(index);
        students[index] = student.getName();
        System.out.println("Name: " + student.getName());
    }

    return students;
}

There's no need to create an instance of a CompareToBuilder for each comparison for scores. That's inefficient.

2 Comments

Yes, I could do that. But what if I dont have the access to make changes to Student class (meaning if it is from an external jar or a framework class)
So you write a class that implements Comparator<Student> and use that to sort the array.
1

Replaced the array by a list:

public static List<String> orderStudent(List<Student> ls) {
    Collections.sort(ls, new Comparator<Student>() {
        @Override
        public int compare(Student o1, Student o2) {
            return o2.getScore().compareTo(o1.getScore());
        }
    });
    List<String> result = new ArrayList<String>();
    for(Student s : ls) {
        result.add(s.getName());
    }
    return result;
}

If using Java 8 it would be less than two lines...

Comments

1
  1. You need to define in your Student object some to string serialization ( optional )
  2. You need to sort your object with custom comporator that orders by score ( required )

    Collections.sort(List list, Comparator c)

    • list is your list
    • c is comparator
  3. iterate over the sorted collection and print

Comments

1

You need to implement 2 things in your Student Class: Comparable, and a override to the .toString() method. First, define you student class like:

public class Student implements Comparable<Student>

Then you must define the .compareTo() Method as follows:

//used for sorting later
public int compareTo(Student other) {
    return this.getScore().compareTo(other.getScore());//Assuming Student.score is not a primitive type
}

Also override the .toString() method as follows:

//used for printing later
public string toString() {
    return "Name: " + this.getName() + ", Score: " + this.getScore().toString();
}

Now you can simply change your orderStudents function to the following:

public static void orderStudent(List<Student> ls) {

// this will sort your collection based on the logic in the `Student.compareTo()` method.
ls = Collections.sort(ls);

for (Student stu : ls) {
//this will print the student object based on the `Student.toString()` method
        System.out.println(stu);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.