Назад Зміст Вперед

8.7. Сортування масивів та ArrayList за допомогою інтерфейсів Comparable та Comparator

ArrayList - Реалізація List інтерфейсу на основі динамічно змінюваного масиву. У більшості випадків, найкраща можлива реалізація List інтерфейсу по споживанню пам'яті і продуктивності. У вкрай рідкісних випадках, коли потрібні часті вставки на початок або середину списку із дуже малою кількістю переміщень за списком, LinkedList буде вигравати в продуктивності (але раджу в цих випадках використовувати TreeList від apache).
Реалізація List інтерфейсу на основі двостороннього пов'язаного списку, тобто коли кожний елемент, що вказує на попередній і наступний елемент. Як правило, вимагає більше пам'яті і гірший, ніж ArrayList, має сенс використовувати лише в рідкісних випадках коли потрібно часто вставити/видалити в середину списку з мінімальними переміщеннями за списком (але раджу в цих випадках використовувати TreeList від apache).

Приклади/Example

Example 1: Сортування ArrayList<String>

import java.util.*;
public class Details  {
 public static void main(String args[]){
    ArrayList<String> listofcountries = new ArrayList<String>();
    listofcountries.add("India");
    listofcountries.add("US");
    listofcountries.add("China");
    listofcountries.add("Denmark");

    /*Несортований List*/
    System.out.println("Before Sorting:");
    for(String counter: listofcountries){
   System.out.println(counter);
  }

    /* Сортування*/
    Collections.sort(listofcountries);

    /* Sorted List*/
    System.out.println("After Sorting:");
    for(String counter: listofcountries){
   System.out.println(counter);
  }
 }
}
Результат:
Before Sorting:
India
US
China
Denmark
After Sorting:
China
Denmark
India
US

Sort an Array_Arrays.sort().


 String[] fruits = new String[] {"Pineapple","Apple", "Orange", "Banana"}; 
  
 Arrays.sort(fruits);
  
 int i=0;
 for(String temp: fruits){
  System.out.println("fruits " + ++i + " : " + temp);
 }
Результат:

fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple

Sort an ArrayList

Collections.sort().

 List<String> fruits = new ArrayList<String>();
   
 fruits.add("Pineapple");
 fruits.add("Apple");
 fruits.add("Orange");
 fruits.add("Banana");
 
 Collections.sort(fruits);
  
 int i=0;
 for(String temp: fruits){
  System.out.println("fruits " + ++i + " : " + temp);
 }
Результат:

fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple

Example 2: Сортування ArrayList<Integer>

Той же метод Collections.sort () можна використовувати для сортування Integer ArrayList.
import java.util.*;
public class ArrayListOfInteger  {

 public static void main(String args[]){
    ArrayList<Integer> arraylist = new ArrayList<Integer>();
    arraylist.add(11);
    arraylist.add(2);
    arraylist.add(7);
    arraylist.add(3);
    /* ArrayList before the sorting*/
    System.out.println("Before Sorting:");
    for(int counter: arraylist){
   System.out.println(counter);
  }

    /* Sorting of arraylist using Collections.sort*/
    Collections.sort(arraylist);

    /* ArrayList after sorting*/
    System.out.println("After Sorting:");
    for(int counter: arraylist){
   System.out.println(counter);
  }
 }
}
Результат:
Before Sorting:
11
2
7
3
After Sorting:
2
3
7
11

Example 3: Метод Comparator для сортування.

package beginnersbook.com;
import java.util.Comparator;
public class Student  {
    private String studentname;
    private int rollno;
    private int studentage;

    public Student(int rollno, String studentname, int studentage) {
        this.rollno = rollno;
        this.studentname = studentname;
        this.studentage = studentage;
    }
    ...
    //Getter and setter methods same as the above examples
    ...
    /*Comparator for sorting the list by Student Name*/
    public static Comparator<Student> StuNameComparator = new Comparator<Student>() {

 public int compare(Student s1, Student s2) {
    String StudentName1 = s1.getStudentname().toUpperCase();
    String StudentName2 = s2.getStudentname().toUpperCase();

    //ascending order
    return StudentName1.compareTo(StudentName2);

    //descending order
    //return StudentName2.compareTo(StudentName1);
    }};

    /*Comparator сортування list by Rollno*/    public static Comparator<Student> StuRollno = new Comparator<Student>() {

 public int compare(Student s1, Student s2) {

    int rollno1 = s1.getRollno();
    int rollno2 = s2.getRollno();

    /*For ascending order*/
    return rollno1-rollno2;

    /*For descending order*/
    //rollno2-rollno1;
   }};
    @Override
    public String toString() {
        return "[ rollno=" + rollno + ", name=" + studentname + ", age=" + studentage + "]";
    }

}
ArrayList class:
package beginnersbook.com;
import java.util.*;
public class Details  {

 public static void main(String args[]){
    ArrayList<Student> arraylist = new ArrayList<Student>();
    arraylist.add(new Student(101, "Zues", 26));
    arraylist.add(new Student(505, "Abey", 24));
    arraylist.add(new Student(809, "Vignesh", 32));

    /*Sorting based on Student Name*/
    System.out.println("Student Name Sorting:");
    Collections.sort(arraylist, Student.StuNameComparator);

    for(Student str: arraylist){
   System.out.println(str);
    }

    /* Sorting on Rollno property*/
    System.out.println("RollNum Sorting:");
    Collections.sort(arraylist, Student.StuRollno);
    for(Student str: arraylist){
   System.out.println(str);
    }
 }
}
Результат:
Student Name Sorting:
[ rollno=505, name=Abey, age=24]
[ rollno=809, name=Vignesh, age=32]
[ rollno=101, name=Zues, age=26]
RollNum Sorting:
[ rollno=101, name=Zues, age=26]
[ rollno=505, name=Abey, age=24]
[ rollno=809, name=Vignesh, age=32]

Example 4: Сортування ArrayList<Object> з Comparable.


Sort an Object with Comparable


public class Fruit{
 
 private String fruitName;
 private String fruitDesc;
 private int quantity;
 
 public Fruit(String fruitName, String fruitDesc, int quantity) {
  super();
  this.fruitName = fruitName;
  this.fruitDesc = fruitDesc;
  this.quantity = quantity;
 }
 
 public String getFruitName() {
  return fruitName;
 }
 public void setFruitName(String fruitName) {
  this.fruitName = fruitName;
 }
 public String getFruitDesc() {
  return fruitDesc;
 }
 public void setFruitDesc(String fruitDesc) {
  this.fruitDesc = fruitDesc;
 }
 public int getQuantity() {
  return quantity;
 }
 public void setQuantity(int quantity) {
  this.quantity = quantity;
 }
}
package com.mkyong.common.action;

import java.util.Arrays;

public class SortFruitObject{
 
 public static void main(String args[]){

  Fruit[] fruits = new Fruit[4];
  
  Fruit pineappale = new Fruit("Pineapple", "Pineapple description",70); 
  Fruit apple = new Fruit("Apple", "Apple description",100); 
  Fruit orange = new Fruit("Orange", "Orange description",80); 
  Fruit banana = new Fruit("Banana", "Banana description",90); 
  
  fruits[0]=pineappale;
  fruits[1]=apple;
  fruits[2]=orange;
  fruits[3]=banana;
  
  Arrays.sort(fruits);

  int i=0;
  for(Fruit temp: fruits){
     System.out.println("fruits " + ++i + " : " + temp.getFruitName() + 
   ", Quantity : " + temp.getQuantity());
  }
  
 } 
}
Exception in thread "main" java.lang.ClassCastException: 
com.mkyong.common.Fruit cannot be cast to java.lang.Comparable
 at java.util.Arrays.mergeSort(Unknown Source)
 at java.util.Arrays.sort(Unknown Source)
public class Fruit implements Comparable<Fruit>{
 
 private String fruitName;
 private String fruitDesc;
 private int quantity;
 
 public Fruit(String fruitName, String fruitDesc, int quantity) {
  super();
  this.fruitName = fruitName;
  this.fruitDesc = fruitDesc;
  this.quantity = quantity;
 }
 
 public String getFruitName() {
  return fruitName;
 }
 public void setFruitName(String fruitName) {
  this.fruitName = fruitName;
 }
 public String getFruitDesc() {
  return fruitDesc;
 }
 public void setFruitDesc(String fruitDesc) {
  this.fruitDesc = fruitDesc;
 }
 public int getQuantity() {
  return quantity;
 }
 public void setQuantity(int quantity) {
  this.quantity = quantity;
 }

 public int compareTo(Fruit compareFruit) {
 
  int compareQuantity = ((Fruit) compareFruit).getQuantity(); 
  
  //в порядку зростання
  return this.quantity - compareQuantity;
  
  //у порядку спадання
  //повертає compareQuantity - this.quantity;
  
 } 
}
compareTo()
  1. this.quantity – compareQuantity в порядку зростання
  2. compareQuantity – this.quantity в порядку спадання
fruits 1 : Pineapple, Quantity : 70
fruits 2 : Orange, Quantity : 80
fruits 3 : Banana, Quantity : 90
fruits 4 : Apple, Quantity : 100

Скажімо, нам потрібно, щоб впорядкувати ArrayList <Student> заснований на властивості студентського віку. Ось як це можна зробити - спочатку реалізувати Comparable інтерфейс, а потім перевизначити метод CompareTo.
package beginnersbook.com;
public class Student implements Comparable {
    private String studentname;
    private int rollno;
    private int studentage;

    public Student(int rollno, String studentname, int studentage) {
        this.rollno = rollno;
        this.studentname = studentname;
        this.studentage = studentage;
    }
    ...
    //getter and setter methods same as the above example 
    ...
    @Override
    public int compareTo(Student comparestu) {
        int compareage=((Student)comparestu).getStudentage();
        /* For Ascending order*/
        return this.studentage-compareage;

        /* For Descending order do like this */
        //return compareage-this.studentage;
    }

    @Override
    public String toString() {
        return "[ rollno=" + rollno + ", name=" + studentname + ", age=" + studentage + "]";
    }

}
Collections.sort на ArrayList
import java.util.*;
public class ArrayListSorting  {

 public static void main(String args[]){
    ArrayList<Student> arraylist = new ArrayList<Student>();
    arraylist.add(new Student(223, "Chaitanya", 26));
    arraylist.add(new Student(245, "Rahul", 24));
    arraylist.add(new Student(209, "Ajeet", 32));
         Collections.sort(arraylist);
    for(Student str: arraylist){
   System.out.println(str);
    }
 }
}
Результат:
[ rollno=245, name=Rahul, age=24]
[ rollno=223, name=Chaitanya, age=26]
[ rollno=209, name=Ajeet, age=32]
Comparable зробив свою роботу, навіщо потрібен Comparator?
Використовуючи Comparable ми можемо сортувати тільки за однією властивістю, яка повинна бути цілого типу. Для того, щоб впорядкувати ArrayList на основі декількох властивостей ми можемо використовувати Comparator.

Example 5: Сортування ArrayList<Object> за кількома властивостями з Comparator.

Сompare метод з Comparator для сортування.
package beginnersbook.com;
import java.util.Comparator;
public class Student  {
    private String studentname;
    private int rollno;
    private int studentage;

    public Student(int rollno, String studentname, int studentage) {
        this.rollno = rollno;
        this.studentname = studentname;
        this.studentage = studentage;
    }
    ...
    //Getter and setter methods same as the above examples
    ...
    /*Comparator for sorting the list by Student Name*/
    public static Comparator<Student> StuNameComparator = new Comparator<Student>() {

 public int compare(Student s1, Student s2) {
    String StudentName1 = s1.getStudentname().toUpperCase();
    String StudentName2 = s2.getStudentname().toUpperCase();

    //ascending order
    return StudentName1.compareTo(StudentName2);

    //descending order
    //return StudentName2.compareTo(StudentName1);
    }};

    /*Comparator for sorting the list by roll no*/
    public static Comparator<Student> StuRollno = new Comparator<Student>() {

 public int compare(Student s1, Student s2) {

    int rollno1 = s1.getRollno();
    int rollno2 = s2.getRollno();

    /*For ascending order*/
    return rollno1-rollno2;

    /*For descending order*/
    //rollno2-rollno1;
   }};
    @Override
    public String toString() {
        return "[ rollno=" + rollno + ", name=" + studentname + ", age=" + studentage + "]";
    }

}
ArrayList class:
package beginnersbook.com;
import java.util.*;
public class Details  {

 public static void main(String args[]){
    ArrayList<Student> arraylist = new ArrayList<Student>();
    arraylist.add(new Student(101, "Zues", 26));
    arraylist.add(new Student(505, "Abey", 24));
    arraylist.add(new Student(809, "Vignesh", 32));

    /*Sorting based on Student Name*/
    System.out.println("Student Name Sorting:");
    Collections.sort(arraylist, Student.StuNameComparator);

    for(Student str: arraylist){
   System.out.println(str);
    }

    /*Сортування за Rollno властивостями*/
    System.out.println("RollNum Sorting:");
    Collections.sort(arraylist, Student.StuRollno);
    for(Student str: arraylist){
   System.out.println(str);
    }
 }
}
Результат:
Student Name Sorting:
[ rollno=505, name=Abey, age=24]
[ rollno=809, name=Vignesh, age=32]
[ rollno=101, name=Zues, age=26]
RollNum Sorting:
[ rollno=101, name=Zues, age=26]
[ rollno=505, name=Abey, age=24]
[ rollno=809, name=Vignesh, age=32]

Sort an Object with Comparator

Сортування з кількома властивостями, клас Fruit: сортування з фруктами “fruitName” (назва) або “Quantity” (кількість).
import java.util.Comparator;

public class Fruit implements Comparable<Fruit>{
 
 private String fruitName;
 private String fruitDesc;
 private int quantity;
 
 public Fruit(String fruitName, String fruitDesc, int quantity) {
  super();
  this.fruitName = fruitName;
  this.fruitDesc = fruitDesc;
  this.quantity = quantity;
 }
 
 public String getFruitName() {
  return fruitName;
 }
 public void setFruitName(String fruitName) {
  this.fruitName = fruitName;
 }
 public String getFruitDesc() {
  return fruitDesc;
 }
 public void setFruitDesc(String fruitDesc) {
  this.fruitDesc = fruitDesc;
 }
 public int getQuantity() {
  return quantity;
 }
 public void setQuantity(int quantity) {
  this.quantity = quantity;
 }

 public int compareTo(Fruit compareFruit) {
 
  int compareQuantity = ((Fruit) compareFruit).getQuantity(); 
  
  //в порядку зростання
  return this.quantity - compareQuantity;
  
  //в порядку спадання
  //повертає compareQuantity - this.quantity;
  
 }
 
 public static Comparator<Fruit> FruitNameComparator 
                          = new Comparator<Fruit>() {

     public int compare(Fruit fruit1, Fruit fruit2) {
      
       String fruitName1 = fruit1.getFruitName().toUpperCase();
       String fruitName2 = fruit2.getFruitName().toUpperCase();
       
       //в порядку зростання
       return fruitName1.compareTo(fruitName2);
       
       //в порядку спадання
       //повертає fruitName2.compareTo(fruitName1);
     }

 };
}

1. Сортування за властивістю "fruitName" в порядку спадання.
Arrays.sort(fruits, Fruit.FruitNameComparator);
Результат:

fruits 1 : Apple, Quantity : 100
fruits 2 : Banana, Quantity : 90
fruits 3 : Orange, Quantity : 80
fruits 4 : Pineapple, Quantity : 70
2. Сортування за властивістю “quantity” в порядку зростання.
Arrays.sort(fruits)
Результат:

fruits 1 : Pineapple, Quantity : 70
fruits 2 : Orange, Quantity : 80
fruits 3 : Banana, Quantity : 90
fruits 4 : Apple, Quantity : 100


.