總網頁瀏覽量

2015年9月29日 星期二

[Java] Java object sorting example (Comparable and Comparator)

因為上次練習Ex_PriorityQueue_1用到了 Comparator,
但是書裡看到的
PriorityQueue<String> pq = new PriorityQueue<String> (3,c);
拿Comparator c 來和3 做大於, 等於, 小於的比較座排序.
所以啥一下資料看到了之前也貼過的連結

http://give.pixnet.net/blog/post/11346747-how-to-sort-objects-in-java-%28%E6%8E%92%E5%BA%8Fjava%E7%89%A9%E4%BB%B6%29

又查了一下看到外國網站的範例

http://www.mkyong.com/java/java-object-sorting-example-comparable-and-comparator/

現在在把這個外國按歷練習一下

Sort_an_Array

import java.util.*;

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

        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
----------------------- 
可以看出 Arrays.sort 所作的排列是以字母開頭唯排序標準, 由大到小.

Sort_an_ArrayList
import java.util.*;

public class Sort_an_ArrayList{
 public static void main(String args[]){
  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
----------------------- 
Collections.sort(fruits); 好像也是一字母排列




Sort_an_Object_with_Comparable

import java.util.Arrays;


public class Sort_an_Object_with_Comparable{
 
 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());
  }
 } 
}


(NO: 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;
 }
}


卡關(1)
Sort_an_Object_with_Comparable.java:31: error: class Fruit is public, 
should be declared in a file named Fruit.java
public class Fruit{
       ^
以上這個例外是因為多了public.
 
改完之後就可以執行了,
卡關(2)
但是又會出現
Exception in thread "main" java.lang.ClassCastException: Fruit cannot be cast to java.lang
.Comparable
        at java.util.ComparableTimSort.countRunAndMakeAscending(Unknown Source)
        at java.util.ComparableTimSort.sort(Unknown Source)
        at java.util.Arrays.sort(Unknown Source)
        at Sort_an_Object_with_Comparable.main(Sort_an_Object_with_Comparable.java:53)
 
在 class Fruit{ 理面加上這些還是不行, 跟之前Ex_PriorityQueue_1的寫好好像不同
 >< 這裡有夠怪異的

 public int compareTo(Fruit compareFruit) {
 
  int compareQuantity = ((Fruit) compareFruit).getQuantity(); 
  
  //ascending order
  return this.quantity - compareQuantity;
  
  //descending order
  //return compareQuantity - this.quantity;
  
 }  
 
歐歐歐歐歐
由錯誤訊息最後一個知道說, 錯誤出現在65行, 也就是 Arrays.sort(fruits);
網路上也說
Nice try, but, what you expect the Arrays.sort() will do? 
You didn’t even mention what to sort in the Fruit class. 
 
把他刪掉就可以執行了 

The new Fruit class implemented the Comparable interface, and overrided the compareTo() method to compare its quantity property in ascending order.
The compareTo() method is hard to explain, in integer sorting, just remember
  1. this.quantity – compareQuantity is ascending order.
  2. compareQuantity – this.quantity is descending order.
To understand more about compareTo() method, read this Comparable documentation.

 現在理解是說, 可以用Comparable的interface, Comparable會複寫compareTo()方法,
用quantity來比叫座排序, 而 ascending 是漸升的; descending 漸減

改完之後就可以執行了. ^.<

完整程式碼
Sort_an_Object_with_Comparable
 import java.util.*;

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;
    }
   
    public int compareTo(Fruit compareFruit) {
   
        int compareQuantity = ((Fruit) compareFruit).getQuantity();
       
        //ascending order
        return this.quantity - compareQuantity;
       
        //descending order
        //return compareQuantity - this.quantity;
       
    }   
}


public class Sort_an_Object_with_Comparable{
   
    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;
       
        int i=0;
        for(Fruit temp: fruits){
           System.out.println("fruits " + ++i + " : " + temp.getFruitName() +
            ", Quantity : " + temp.getQuantity());
        }
    }   
}


----------------------------------------------
fruits 1 : Pineapple, Quantity : 70
fruits 2 : Apple, Quantity : 100
fruits 3 : Orange, Quantity : 80
fruits 4 : Banana, Quantity : 90
----------------------------------------------
 
Sort_an_Object_with_Comparator 
import java.util.Comparator;

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

 };  有" ; "注意
}

以下程式碼相同
public class Sort_an_Object_with_Comparator{
 
 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, Fruit.FruitNameComparator);
 
  int i=0;
  for(Fruit temp: fruits){
     System.out.println("fruits " + ++i + " : " + temp.getFruitName() + 
   ", Quantity : " + temp.getQuantity());
  }
 } 
}
 ----------------------------------------------
fruits 1 : Pineapple, Quantity : 70
fruits 2 : Apple, Quantity : 100
fruits 3 : Orange, Quantity : 80
fruits 4 : Banana, Quantity : 90
---------------------------------------------- 

ㄟ 奇怪, 哪有排, 原來, 少了
Arrays.sort(fruits, Fruit.FruitNameComparator);
在Sort_an_Object_with_Comparator類別上加上去, 但是卻又卡關了
Sort_an_Object_with_Comparator.java:82: error: cannot find symbol
                Arrays.sort(fruits, Fruit.FruitNameComparator);
                ^
  symbol:   variable Arrays
  location: class Sort_an_Object_with_Comparator 1 error

崩潰了 QQ
 
幹, 別崩潰, 由錯誤代碼中知道, 現在complier不知道 Arrays 是三小叮噹,
拉到上面看一下發現  import java.util.Comparator; 只import了Comparator,
所以加上            import java.util.Arrays;  就可以跑囉~

 
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
---------------------------------------------- 
 
Arrays.sort(fruits);

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



Comparator 就像是多加限制, 不用原本的排列方法.

但是問題是為啥原本字母的時候, 昰以 A->Z 來排列,
數字的時候, 昰由小到大, 這樣推論可能是以 A 的ASCII比較小, 所以排前面.



網站抵下有些東西可以看一下:
I think it's not this     Arrays.sort(fruits, Fruit.FruitNameComparator);
but this     Collections.sort(fruits, Fruit.FruitNameComparator);
 為啥不能用 Collections


fruits is an Array, not a List.


沒有留言:

張貼留言