oruji.github.io
oruji.github.ioPersian Tutorials
ایجاد: 1396/11/22 12:19 - ویرایش: 1396/11/22 22:23
A A

جاوا مرتب (Sort) کردن شیء با Comparable و Comparator

در این آموزش از کتاب برخط جاوا، نحوه و چگونگی مرتب (Sort) کردن یک آبجکت یا شیء را با استفاده از java.lang.Comparable و java.util.Comparator با بیان چند مثال توضیح می دهیم.

مرتب (Sort) کردن یک آرایه در جاوا

برای sort کردن یک آرایه در جاوا، از Array.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) کردن یک 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

استفاده از Comparable برای مرتب سازی آبجکت در جاوا

اکنون نوبت به آبجکت رسیده است، اجازه دهید یک کلاس به نام Fruit ایجاد کنیم:

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; } }

برای sort کردن این آبجکت ممکن است دوباره به Arrays.sort() فکر کنید. مثال زیر را نگاه کنید:

package org.amoozesh.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()); } } }

تلاش خوبی بود، ولی، انتظار دارید که Arrays.sort() چه کاری انجام دهد؟ شما حتی اشاره ای به چیزی که باید در کلاس Fruit مرتب شود نکرده اید. بنابراین خطای زیر رخ خواهد داد:

Exception in thread "main" java.lang.ClassCastException: org.amoozesh.common.Fruit cannot be cast to java.lang.Comparable at java.util.Arrays.mergeSort(Unknown Source) at java.util.Arrays.sort(Unknown Source)

برای Sort کردن یک آبجکت یا شیء توسط خصوصیات آن، شما باید آبجکت ای ایجاد کنید که اینترفیس Comparable را Implement کرده و متد CompareTo() آن را override کند. اجازه دهید نگاهی دوباره به کلاس جدید Fruit بیاندازیم:

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(); //ascending order return this.quantity - compareQuantity; //descending order //return compareQuantity - this.quantity; } }

کلاس جدید Fruit اینترفیس Comparable را پیاده سازی کرده است، و متد CompareTo() را برای مقایسه تعداد خصوصیت به طور صعودی override کرده است.

نکته

توضیح متد compareTo() کمی سخت است، در مرتب سازی integer، تنها بخاطر داشته باشید که:

  1. this.quantity - compareQuantity ترتیب صعودی است.
  2. compareQuantity - this.quantity ترتیب نزولی است.

کد را دوباره اجرا کنید، حالا آرایه Fruits بر اساس تعداد به صورت صعودی مرتب شده است:

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

مرتب (sort) کردن آبجکت با Comparator در جاوا

در نظر بگیرید که بخواهیم مرتب سازی Fruit را هم با "Quantity" و هم با "ّfruitName" انجام دهیم! اینترفیس Comparable تنها برای مرتب سازی بر اساس یک خصوصیت می باشد. برای Sort کردن بر اساس چند خصوصیت باید از Comparator استفاده کنیم. نگاهی دوباره به کلاس جدید Fruit بیاندازید:

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(); //ascending order return this.quantity - compareQuantity; //descending order //return 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(); //ascending order return fruitName1.compareTo(fruitName2); //descending order //return fruitName2.compareTo(fruitName1); } }; }

کلاس Fruit حاوی static متد FruitNameComparator برای مقایسه "fruitName" است. حالا آبجکت یا شیء Fruit قادر به مرتب سازی هم با "quantity" و یا هم با "fruitName" می باشد. آن را دوباره اجرا کنید.

1. مرتب سازی آرایه Fruit بر اساس خصوصیت "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. مرتب کردن آرایه Fruit بر اساس خصوصیت "quantity" به صورت ترتیب صعودی.

Arrays.sort(fruits)

خروجی

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