Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Java Enums: How to Use Configurable Sorting Fields

DZone's Guide to

Java Enums: How to Use Configurable Sorting Fields

Want to learn more about how to use Java enums with configurable sorting fields? Check out this tutorial to learn more about using enums with sorting fields.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

In continuation of my previous article, Java Enums: How to Make Much More Useful, here I am with an idea on how we can also use enums as defined sorting fields for model-data in a configurable manner. This sorting logic will work to sort the data on multiple fields, just like we do by using the OrderBy clause of the SQL query. As we have seen so far, we can have defined methods as enum members. Now, I am using the same idea to make it Comparator (enums can implement interfaces).

This example is applicable for Java 7 or below only. For Java 8 or above with rich java.util.Comparator APIs and power of Lambdas You simply need of the Pojo class (Student). See the end of the article for Java 8 approach.

Still, I must say that this article is to just give an idea on how and what you can do with enums in similar way. Just imagine and create your own examples.

Steps

  • Define your model-data (POJO) class and decide how to sort the fields. I will use the Student class for the example below:

package sort;

public class Student {
     private int rollno;
     private String name;
     private int age;
     private int marks;

     public Student() {
              super();
     }

     Student(int rollno, String name, int age, int marks) {
        this.rollno = rollno;
        this.name = name;
        this.age = age;
        this.marks = marks;
     }

      public int getRollno() {
      return rollno;
      }

      public void setRollno(int rollno) {
      this.rollno = rollno;
      }

      public String getName() {
      return name;
      }

      public void setName(String name) {
      this.name = name;
      }

      public int getAge() {
      return age;
      }

      public void setAge(int age) {
      this.age = age;
      }

      public int getMarks() {
      return marks;
      }

      public void setMarks(int marks) {
      this.marks = marks;
      }

      public boolean getResult() {
          // return true if pass (more than 50 marks)
          return (marks > 50);
      }

      @Override
      public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append("Student [rollno=").append(rollno)
            .append(", name=").append(name)
            .append(", age=").append(age)
            .append(", marks=").append(marks)
            .append(", result=").append((getResult() ? "Pass" : "Fail"))
            .append("]");
            return builder.toString();
      }

}


  • Create an enum for representing the sorting order as ASC or DESC. I will use the SortingOrder  enum for the following example:
package sort;

public enum SortingOrder {
ASC,
DESC
}


  • Create an enum having all the sorting-fields as a member. I will use the SortingField enum for the example here. This enum will act as a sub-comparator (this will be more clear at the end).  

  • Implement the  java.util.Comparator interface at the enum-level in the SortingField. This will make all of the enum members abstract, and you need to implement a compare method of the interface at each of the enum members.

  • It is optional to implement them in thejava.util.Comparator and the SortingField . But, I like to do it this way to make sure that we are following the right pattern to compare fields. We get an additional Comparator, which we can also use if we would like to only sort on one field.  This will give us additional benefits. See the below code: 

// 1st way
SortingFieldsOrder order = new SortingFieldsOrder().addField(SortingField.NAME);
Collections.sort(studentList, new StudentComparator(order));
printStudentList(studentList);

// 2nd way
Collections.sort(studentList, SortingField.NAME);
printStudentList(studentList);
// Both are same here.
// Remember we have implemented java.util.Comparator also at SortingField.
// This will work only when we have to sort on ONE field.


Below is the code for the  SortingField:

package sort;

import java.util.Comparator;

public enum SortingField implements Comparator<Student> {

   AGE {
      @Override public int compare(Student student1, Student student2) {
      return Integer.compare(student1.getAge(), student2.getAge());
      }
   },

   NAME {
      @Override public int compare(Student student1, Student student2) {
           if (student1.getName() != null && student2.getName() != null) {
              return student1.getName().compareTo(student2.getName());
           } else if (student1.getName() != null) {
           return 1;
           } else {
           return -1;
           }
      }
   },

   ROLLNO {
      @Override public int compare(Student student1, Student student2) {
      return Integer.compare(student1.getRollno(), student2.getRollno());
      }
   },

   MARKS {
       @Override public int compare(Student student1, Student student2) {
                return Integer.compare(student1.getMarks(), student2.getMarks());
       }
   },

   RESULT {
         @Override public int compare(Student student1, Student student2) {
               // the default will be reverse order (descending), pass has to come up 
               // so, comparison will be student 2 vs student1
               return Boolean.compare(student2.getResult(), student1.getResult());
         }
   };

// Below common method to control ASC or DESC order. the default is ASC.
  public int compare(Student student1, Student student2, SortingOrder order) {
    return (SortingOrder.DESC.equals(order)) ? compare(student2, student1) : compare(student1, student2);
    }
}


  • Here, please note that I have added one extra method (over-loaded) called  compare(), based on the given SortingOrder (ASC/DESC).
// Below common method to control ASC or DESC order. the default is ASC.
public int compare(Student student1, Student student2, SortingOrder order) {
return (SortingOrder.DESC.equals(order)) ? compare(student2, student1) : compare(student1, student2);
}


  • Create one Pojo class to maintain the user-defined SortingField and the  SortingOrder together. I will use the  SortingFieldOrder  class for this example.  Please note here that I have overridden both the  hashCode() and  equals() method just to make sure that we can't add a   SortingField  twice in the  SortingOrder list. And, hence, I have checked only for the  SortingField  in the both of the methods — not the  SortingOrder .
package sort;

public class SortingFieldOrder {

      private SortingField sortingField;

      private SortingOrder sortingOrder;

      public SortingFieldOrder() {
      super();
      }

      public SortingFieldOrder(final SortingField sortingField) {
            this();
            this.sortingField = sortingField;
      }

      public SortingFieldOrder(final SortingField sortingField, final SortingOrder sortingOrder) {
            this(sortingField);
            this.sortingOrder = sortingOrder;
      }

      public SortingField getSortingField() {
      return sortingField;
      }

      public void setSortingField(SortingField sortingField) {
      this.sortingField = sortingField;
      }

      public SortingOrder getSortingOrder() {
      return sortingOrder;
      }

      public void setSortingOrder(SortingOrder sortingOrder) {
      this.sortingOrder = sortingOrder;
      }

      @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + ((sortingField == null) ? 0 : sortingField.hashCode());
          return result;
      }

      // checked only for SortingField to make sure that we can't add any field twice.
      @Override
      public boolean equals(Object obj) {
          if (this == obj)
          return true;
          if (obj == null)
          return false;
          if (getClass() != obj.getClass())
          return false;
          SortingFieldOrder other = (SortingFieldOrder) obj;
          if (sortingField != other.sortingField)
              return false;
          return true;
      }

      @Override
      public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append("SortingFieldOrder [sortingField=").append(sortingField)
            .append(", sortingOrder=").append(sortingOrder)
            .append("]");
            return builder.toString();
      }

}


  • Next, you will need to create one more Pojo class to maintain the user-defined order of the  SortingFieldOrder. I will use the SortingFieldsOrderBean class for the example. We can also avoid creating this order class since its just stores a list to maintain the order. We can also create a list directly to store the order of the fields. But, for making the code as clean as possible, I am creating the SortingFieldsOrderBean class.

package sort;

import java.util.ArrayList;
import java.util.List;

public class SortingFieldsOrderBean {

      private List<SortingFieldOrder> fieldsOrder = new ArrayList<SortingFieldOrder>();

      public SortingFieldsOrderBean() {
      super();
      }

      // To Create SortingFieldOrder in ASC or DESC order
      public synchronized SortingFieldsOrderBean addField(final SortingFieldOrder fieldOrder) {
            // contains will check the implemented equals method of SortingFieldOrder
            // and will make sure that we have not added any SortingField twice.
            if (!fieldsOrder.contains(fieldOrder)) {
            fieldsOrder.add(fieldOrder);
            }
            return this;
      }

      // To Create SortingFieldOrder in ASC order
      public synchronized SortingFieldsOrderBean addField(final SortingField field) {
            SortingFieldOrder fieldOrder = new SortingFieldOrder(field);
            if (!fieldsOrder.contains(fieldOrder)) {
            fieldsOrder.add(fieldOrder);
            }
            return this;
      }

      // To Create SortingFieldOrder in ASC or DESC order
      public synchronized SortingFieldsOrderBean addField(final SortingField field, final SortingOrder order) {
            SortingFieldOrder fieldOrder = new SortingFieldOrder(field, order);
            if (!fieldsOrder.contains(fieldOrder)) {
            fieldsOrder.add(fieldOrder);
            }
            return this;
      }

      public List<SortingFieldOrder> getFieldsInOrder() {
      return fieldsOrder;
      }

      @Override
      public String toString() {
      return "SortingFieldsOrderBean [fieldsOrder=" + fieldsOrder + "]";
      }

}


  • Create one more Comparator class (sub-class of the  java.util.Comparator), which will receive the SortingFieldsOrderBean as a parameter and will perform a comparison based on the order of fields passed. This Comparator class will act as the  main-comparator , and the  SortingField enum will act as a sub-comparator. I will use the StudentComparator   class as the main-comparator for the following example:

package sort;

import java.util.Comparator;
import java.util.List;

public class StudentComparator implements Comparator<Student> {

      private SortingFieldsOrderBean orderBean;

      public StudentComparator(final SortingFieldsOrderBean orderBean) {
          super();
          if (orderBean == null || orderBean.getFieldsInOrder() == null || orderBean.getFieldsInOrder().isEmpty()) {
          throw new IllegalArgumentException("SortingFieldsOrderBean can't be null or empty");
          }
          this.orderBean = orderBean;
      }

      @Override
      public int compare(Student student1, Student student2) {
          List<SortingFieldOrder> orderFields = orderBean.getFieldsInOrder();
          return compareInFieldOrder(orderFields, student1, student2);
      }

      // recursive method to perform sorting on multiple fields and order.
      private int compareInFieldOrder(final List<SortingFieldOrder> orderFields, final Student student1,
      final Student student2) {
            SortingFieldOrder fieldOrder = orderFields.get(0);
            SortingField field = fieldOrder.getSortingField();
            SortingOrder order = fieldOrder.getSortingOrder();
            int comparisonResult = field.compare(student1, student2, order);
            // we check if the objects are same on the field comparison;
            // if yes and there are any remaining fields to compare
            // we call the method recursively by taking the sublist of order fields.
            if (comparisonResult == 0 && orderFields.size() > 1) {
            return compareInFieldOrder(orderFields.subList(1, orderFields.size()), student1, student2);
            }
      return comparisonResult;
      }

}


  • Finally, create a main executable class to test the code. I will create a Main class for the example below:

package sort;

import java.util.ArrayList;
import java.util.Collections;

public class Main {

      public static void main(String[] args) {
          // preparing some hard-coded data to keep code simple and focused.
          ArrayList<Student> studentList = new ArrayList<Student>();
          studentList.add(new Student(101, "Vijay", 24, 98));
          studentList.add(new Student(109, "Ajay", 27, 86));
          studentList.add(new Student(108, "Jai", 26, 49));
          studentList.add(new Student(106, "Ajay", 23, 45));
          studentList.add(new Student(104, "Jai", 26, 62));
          studentList.add(new Student(103, "Vijay", 23, 98));
          studentList.add(new Student(105, "Jai", 21, 54));

          System.out.println("Sorting by Name...");

          // SortingFieldsOrderBean order = new SortingFieldsOrderBean();
          // order.addField(SortingField.NAME);
          // Or in short because of chaining based implementation of addField method by
          // returning current object (return this)
          SortingFieldsOrderBean order = new SortingFieldsOrderBean().addField(SortingField.NAME);

          Collections.sort(studentList, new StudentComparator(order));
          printStudentList(studentList);

          System.out.println("Sorting by Name and age (both ascending)...");
          order = new SortingFieldsOrderBean().addField(SortingField.NAME).addField(SortingField.AGE);
          Collections.sort(studentList, new StudentComparator(order));
          printStudentList(studentList);

          System.out.println("Sorting by Name and age (desc) and rollno...");
          order = new SortingFieldsOrderBean().addField(SortingField.NAME).addField(SortingField.AGE, SortingOrder.DESC)
          .addField(SortingField.ROLLNO);
          Collections.sort(studentList, new StudentComparator(order));
          printStudentList(studentList);

          System.out.println("sorting by age...");
          order = new SortingFieldsOrderBean().addField(SortingField.AGE);
          Collections.sort(studentList, new StudentComparator(order));
          // Or Simply we can write as below
          // Collections.sort(studentList, SortingField.AGE);
          // Remember we have implemented java.util.Comparator in the SortingField as well
          // This will work ONLY when we have to sort on ONE field only.
          printStudentList(studentList);

          System.out.println("sorting by rollno in descending order...");
          order = new SortingFieldsOrderBean().addField(SortingField.ROLLNO, SortingOrder.DESC);
          Collections.sort(studentList, new StudentComparator(order));
          // Or Simply we can write as below
          // Collections.sort(studentList, SortingField.ROLLNO);
          printStudentList(studentList);

          System.out.println("sorting by result, marks descending, rollno in ascending order...");
          order = new SortingFieldsOrderBean().addField(SortingField.RESULT)
          .addField(SortingField.MARKS, SortingOrder.DESC).addField(SortingField.ROLLNO);
          Collections.sort(studentList, new StudentComparator(order));
          printStudentList(studentList);

}

private static void printStudentList(ArrayList<Student> studentList) {
          for (Student student : studentList) {
                  System.out.println(student);
          }
          System.out.println();
}
}


Here is the output of the program:

Sorting by Name...
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]

Sorting by Name and age (both ascending)...
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]

Sorting by Name and age (desc) and rollno...
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]

sorting by age...
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]

sorting by rollno in descending order...
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]

sorting by result, marks descending, rollno in ascending order...
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]


Now, I will take a look at an uncommon case to handle. Suppose we like to have a different sorting for the students that pass or fail. For the students who pass, we will sort them based on the given sorting order. But, for all the students who fail, sorting the order is fixed by the name and RollNo in the ascending order.

To handle this uncommon case, we have to write a new main comparator and make sure that the first will always check for the result to distinguish between pass and fail students. For all students who pass, we will follow the given sorting-fields-order. Otherwise, for all students that failed, we will sort them by the fixed sorting order, Result, Name and RollNo. I am using  StudentResultComparator for the example.

package sort;

import java.util.Comparator;
import java.util.List;

public class StudentResultComparator implements Comparator<Student> {

      private SortingFieldsOrderBean orderBean;

      public StudentResultComparator(final SortingFieldsOrderBean orderBean) {
          super();
          if (orderBean == null || orderBean.getFieldsInOrder() == null || orderBean.getFieldsInOrder().isEmpty()) {
          throw new IllegalArgumentException("SortingFieldsOrderBean can't be null or empty");
          }
        // by adding the Result as a 1st sorting field, I am forcing the 1st sorting to be done on pass vs fail.
          orderBean.getFieldsInOrder().add(0, new SortingFieldOrder(SortingField.RESULT));
          this.orderBean = orderBean;
      }

      @Override
      public int compare(Student student1, Student student2) {
      List<SortingFieldOrder> orderFields = orderBean.getFieldsInOrder();
      return compareInFieldOrder(orderFields, student1, student2);
      }

      // recursive method to perform sorting on multiple fields and order.
      private int compareInFieldOrder(final List<SortingFieldOrder> orderFields, final Student student1,
      final Student student2) {
            int comparisonResult = 0;
            // if students are pass, sort in the given order
            // else force to sort on name and rollno (fixed)
            if (student1.getResult()) { //for all pass
                SortingFieldOrder fieldOrder = orderFields.get(0);
                SortingField field = fieldOrder.getSortingField();
                SortingOrder order = fieldOrder.getSortingOrder();
                comparisonResult = field.compare(student1, student2, order);
                // we check if the objects are same on the field comparison;
                // if yes and there are any remaining fields to compare
                // we call the method recursively by taking the sublist of order fields.
                if (comparisonResult == 0 && orderFields.size() > 1) {
                return compareInFieldOrder(orderFields.subList(1, orderFields.size()), student1, student2);
                }
            } else { // else for all fail, force to sort on name and rollno (fixed)
                if ((comparisonResult = SortingField.RESULT.compare(student1, student2)) == 0) {
                    if ((comparisonResult = SortingField.NAME.compare(student1, student2)) == 0) {
                        comparisonResult = SortingField.ROLLNO.compare(student1, student2);
                }
                }
            }
            return comparisonResult;
      }

}


Below is the code to test the sorting:

package sort;

import java.util.ArrayList;
import java.util.Collections;

public class MainResult {

    public static void main(String[] args) {
          // preparing some hard-coded data to keep code simple and focused.
          ArrayList<Student> studentList = new ArrayList<Student>();
          studentList.add(new Student(101, "Vijay", 24, 98));
          studentList.add(new Student(109, "Ajay", 27, 86));
          studentList.add(new Student(108, "Jai", 26, 49));
          studentList.add(new Student(106, "Ajay", 23, 45));
          studentList.add(new Student(104, "Jai", 26, 62));
          studentList.add(new Student(103, "Vijay", 23, 98));
          studentList.add(new Student(105, "Jai", 21, 54));

          System.out.println("Sorting by Name...");

          // SortingFieldsOrderBean order = new SortingFieldsOrderBean();
          // order.addField(SortingField.NAME);
          // Or in short because of chaining based implementation of addField method by
          // returning current object (return this)
          SortingFieldsOrderBean order = new SortingFieldsOrderBean().addField(SortingField.NAME);

          Collections.sort(studentList, new StudentResultComparator(order));
          printStudentList(studentList);

          System.out.println("Sorting by Name and age (both ascending)...");
          order = new SortingFieldsOrderBean().addField(SortingField.NAME).addField(SortingField.AGE);
          Collections.sort(studentList, new StudentResultComparator(order));
          printStudentList(studentList);

          System.out.println("Sorting by Name and age (desc) and rollno...");
          order = new SortingFieldsOrderBean().addField(SortingField.NAME).addField(SortingField.AGE, SortingOrder.DESC)
            .addField(SortingField.ROLLNO);
          Collections.sort(studentList, new StudentResultComparator(order));
          printStudentList(studentList);

          System.out.println("sorting by age...");
          order = new SortingFieldsOrderBean().addField(SortingField.AGE);
          Collections.sort(studentList, new StudentResultComparator(order));
          // Or Simply we can write as below
          // Collections.sort(studentList, SortingField.AGE);
          // Remember we have implemented java.util.Comparator in the SortingField as well
          // This will work ONLY when we have to sort on ONE field only.
          printStudentList(studentList);

          System.out.println("sorting by rollno in descending order...");
          order = new SortingFieldsOrderBean().addField(SortingField.ROLLNO, SortingOrder.DESC);
          Collections.sort(studentList, new StudentResultComparator(order));
          // Or Simply we can write as below
          // Collections.sort(studentList, SortingField.ROLLNO);
          printStudentList(studentList);

          System.out.println("sorting by result in ascending order...");
          order = new SortingFieldsOrderBean().addField(SortingField.RESULT)
            .addField(SortingField.MARKS, SortingOrder.DESC).addField(SortingField.ROLLNO);
          Collections.sort(studentList, new StudentResultComparator(order));
          printStudentList(studentList);

      }

    private static void printStudentList(ArrayList<Student> studentList) {
          for (Student student : studentList) {
            System.out.println(student);
          }
          System.out.println();
    }
}


Please notice that the program is the same as the previous Mainexcept that we have used our newly written StudentResultComparator instead of  StudentComparator.

Here is the output of the program:

Sorting by Name...
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]

Sorting by Name and age (both ascending)...
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]

Sorting by Name and age (desc) and rollno...
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]

sorting by age...
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]

sorting by rollno in descending order...
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]

sorting by result in ascending order...
Student [rollno=101, name=Vijay, age=24, marks=98, result=Pass]
Student [rollno=103, name=Vijay, age=23, marks=98, result=Pass]
Student [rollno=109, name=Ajay, age=27, marks=86, result=Pass]
Student [rollno=104, name=Jai, age=26, marks=62, result=Pass]
Student [rollno=105, name=Jai, age=21, marks=54, result=Pass]
Student [rollno=106, name=Ajay, age=23, marks=45, result=Fail]
Student [rollno=108, name=Jai, age=26, marks=49, result=Fail]


Java 8 Approach

Now, I am using Java 8  with the  java.util.Comparator APIs and the power of Lambdas. In that case, we need only the Pojo (Student) class. That's all! Interesting, isn't it?

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class MainJava8 {

   public static void main(String[] args) {
   // preparing some hard-coded data to keep code simple and focused.
      ArrayList<Student> studentList = new ArrayList<Student>();
      studentList.add(new Student(101, "Vijay", 24));
      studentList.add(new Student(109, "Ajay", 27));
      studentList.add(new Student(108, "Jai", 24));
      studentList.add(new Student(106, "Ajay", 23));
      studentList.add(new Student(104, "Jai", 26));
      studentList.add(new Student(103, "Vijay", 23));
      studentList.add(new Student(105, "Jai", 21));

      System.out.println("Sorting by Name...");
      Collections.sort(studentList, Comparator.comparing(Student::getName));
      printStudentList(studentList);

      System.out.println("Sorting by Name and age (both ascending)...");
      Collections.sort(studentList, Comparator.comparing(Student::getName).thenComparing(Student::getAge));
      printStudentList(studentList);

      System.out.println("Sorting by Name and age (desc) and rollno...");
      Collections.sort(studentList, Comparator.comparing(Student::getName).thenComparing(Student::getAge).reversed().thenComparing(Student::getRollno));
      printStudentList(studentList);
      System.out.println("sorting by age...");
      Collections.sort(studentList,Comparator.comparing(Student::getAge));
      printStudentList(studentList);

      System.out.println("sorting by rollno in descending order...");
      Collections.sort(studentList, Comparator.comparing(Student::getRollno).reversed());
      printStudentList(studentList);


   }

    private static void printStudentList(ArrayList<Student> studentList) {
    studentList.stream().forEach(System.out::println);
    }

}


Liked the Article? Please don't forget to click the like button!

Happy coding!

Need more articles on Design Patterns? Below are some of them I have shared with you.

Some additional Articles:

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
java ,enums ,comparator ,tutorial ,sorting fields ,sorting order ,configurable

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}