0

I am trying to achieve a sort for object's field value stored in List.

I found the following solution to compare the string but How I can compare the String value and sort accordingly?

I am looking to sort the "Y" status values first then "N"

class Student {
    int rollno;
    String name, status;

    // Constructor
    public Student(int rollno, String name,
        String status) {
        this.rollno = rollno;
        this.name = name;
        this.status = status;
    }

    public String getStatus() {
        return status;
    }

}
ArrayList < Student > ar = new ArrayList < Student > ();
ar.add(new Student(111, "bbbb", "Y"));
ar.add(new Student(131, "aaaa", "N"));
ar.add(new Student(121, "cccc", "Y"));

Collections.sort(ar, (a, b) - > a.getStatus().compareTo(b.getStatus()));
Pshemo
  • 122,468
  • 25
  • 185
  • 269
Bravo
  • 61
  • 2
  • 7
  • 26
  • Please [edit] the post and fix the syntax errors. --- I recommend using a proper object or enum for `status`, not a `String`. – Turing85 Jan 04 '22 at 17:31
  • Your question is missing some information. What is the expected behavior when the string is neither "Y" nor "N"? Imo it would be simpler when you transfor the `status` to an enum and implement the comparision for that enum. – peterulb Jan 04 '22 at 17:38
  • Hello. I tried to clarify title of this question a bit. If you don't agree with my edit feel free to `rolback` it (there is an option for it in [*edit revision*](https://stackoverflow.com/posts/70582726/revisions) - pick version before my edit and use its `rolback` option). – Pshemo Jan 04 '22 at 18:00

3 Answers3

3

If I understood correctly you need refence to method getStatus() its natural order sort

ar.sort(Comparator.comparing(Student::getStatus));

if need reverse order

ar.sort(Comparator.comparing(Student::getStatus).reversed());
стасевич
  • 298
  • 2
  • 10
3

For this, you need a comparator class, that will compare the two students, in that case, if you want that when a student have "Y" in status, it's sorted before "N", you will need something like that :

    public static class StudentComparator implements Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        // Compare the students, return -1 if o1 is "greater" than o2. Return 1 if o2 is "greater" than o1
        if (o1.status.equals("Y")) return -1;
        if (o2.status.equals("Y")) return 1;
        return 0;
    }
}

And then you can compare like that :

    List<Student> ar = new ArrayList<Student>();
    ar.add(new Student(111, "bbbb", "Y"));
    ar.add(new Student(131, "aaaa", "N"));
    ar.add(new Student(121, "cccc", "Y"));

    Collections.sort(ar, new StudentComparator());

Output :

[Student{rollno=121, name='cccc', status='Y'}, Student{rollno=111, name='bbbb', status='Y'}, Student{rollno=131, name='aaaa', status='N'}]
Asonyx
  • 31
  • 1
  • 1
  • Your `Comparator#compare(Student, Student)` method can simply return the result of comparing the two "status" strings: `return o1.getStatus().compareTo(o2.getStatus());`. You don't need to do all that logic since `String` are inherently comparable. – hfontanez Jan 04 '22 at 17:53
2

The string "Y" comes lexicographically after "N", so you need to reverse the default ordering.

There are some ways to do it, one is negating the result of the comparison function:

Collections.sort(ar, (a, b) - > -a.getStatus().compareTo(b.getStatus());

Another is changing the order of the operands:

Collections.sort(ar, (a, b) - > b.getStatus().compareTo(a.getStatus());

fortran
  • 74,053
  • 25
  • 135
  • 175
  • These are clever, but I think they lack readability. What I mean by that is that the reversing order effect is not very obvious when you look at the code. – hfontanez Jan 04 '22 at 17:46
  • It is clever because most people will not think about this particular way to solve this problem. If we "google" this problem, what percentage of the results will show this answer? That's why I say it is clever. – hfontanez Jan 04 '22 at 19:39