Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to sort nested lists in java

I have a json like below :

{ 
  "Student": [
    {  
      "name":"5",
      "Roll No":12345,
      "Subjects":[  
        {  
           "subjectCode":"Mat"
        },
        {  
           "subjectCode":"Sci"
        }
      ]
    } 
  ]
}

I want to sort list of subjects within each student and then sorting student objects with roll no.Can it be done with java8 in single line.

I am using below code :

list.forEach(studentObj -> {
    studentObj.getSubjects()
      .sort(Comparator.nullsLast(Comparator.comparing(Subject:: getSubjectCode)));
  });

then sorting the outside object

  list.sort(Comparator.nullsLast(Comparator.comparing(Student:: getRollNo)));
like image 351
Anuj Kumar Soni Avatar asked Jan 09 '19 09:01

Anuj Kumar Soni


People also ask

Can you sort a nested list?

There will be three distinct ways to sort the nested lists. The first is to use Bubble Sort, the second is to use the sort() method, and the third is to use the sorted() method.

How do I sort a list in Java 8 list?

There are multiple ways to sort a list in Java 8, for example, you can get a stream from the List and then use the sorted() method of Stream class to sort a list like ArrayList, LinkedList, or Vector and then convert back it to List. Alternatively, you can use the Collections. sort() method to sort the list.

Can we sort list of list in Java?

Summary. Collections class sort() method is used to sort a list in Java. We can sort a list in natural ordering where the list elements must implement Comparable interface. We can also pass a Comparator implementation to define the sorting rules.

How do you arrange a list in ascending order in Java?

Approach: An ArrayList can be Sorted by using the sort() method of the Collections Class in Java. This sort() method takes the collection to be sorted as the parameter and returns a Collection sorted in the Ascending Order by default.


2 Answers

If you were to implement the Comparable interface with your 2 classes Student and Subject you could make it really nice and short because you can use the Comparator.naturalOrder() static factory method

Also it allows you to change the way you want to define how Subjects or Students get ordered by simply changing their compareTo method

Student

class Student implements Comparable<Student> {
    String name;
    int rollNo;
    List<Subject> subjects = new ArrayList<>();

    // GETTERS/SETTERS

    @Override
    public int compareTo(Student student) {
        return Integer.compare(this.getRollNo(), student.getRollNo());
    }

}

Subject

class Subject implements Comparable<Subject> {
    String subjectCode;

    // GETTERS/SETTERS

    @Override
    public int compareTo(Subject subject) {
        return this.getSubjectCode().compareTo(subject.getSubjectCode());
    }

}

And then

// static import to make code lighter
import static java.util.Comparator.*;

// sort Students list, then sort Subjects list in each Student
list.sort(nullsLast(naturalOrder()));
list.forEach(s -> { if (s != null) {
   s.getSubjects().sort(nullsLast(naturalOrder())); 
}});

One liner version if you really need it

List<Student> sortedList = list.stream()
    .map(s -> {
        if (s != null) {
            s.getSubjects().sort(nullsLast(naturalOrder()));
        }
        return s;
    }).sorted(nullsLast(naturalOrder()))
    .collect(Collectors.toList());
like image 99
Bentaye Avatar answered Oct 01 '22 16:10

Bentaye


After parsing it to object you could write something like below:

List<Student> sorted = students.stream()
            .map(f -> new Student(f.getId(), f.getSubjects().stream().sorted(Comparator.comparing(Subject::getSubjectCode)).collect(Collectors.toList())))
            .sorted(Comparator.comparing(Student::getRollNo))
            .collect(Collectors.toList())
like image 24
Michał Marcinkowski Avatar answered Oct 01 '22 15:10

Michał Marcinkowski