---
# System prepended metadata

title: 'List在Java中做sort : Collection.sort()'
tags: [Sort, java]

---

List在Java中做sort : Collection.sort()
===

## Discription 

將資料收集進List後，常常會使用到sort，而此動作不需要自己去實作，在java.util.Collections提供sort的方法，Ex:

``Ex 1:``
```java=
import java.util.*;
public class Main
{
	public static void main(String[] args) {
	   List<Integer> count = new ArrayList<>();
	   count.add(500);
	   count.add(50);
	   count.add(5000);
	   count.add(5);
	   
	   Collections.sort(count);
	   
	   for(int k: count)
	        System.out.println(k);
            
            //Output:
            //5
            //50
            //500
            //5000
	}
}
```
會是以升序排序

---

但如果List中存放的是自定義物件呢?
``Ex2``
```java=
import java.util.*;
public class Main
{
	public static void main(String[] args) {
	    
	    List P = Arrays.asList(
                new Person("Justin",  1000,false),
                new Person("Monica",  500,true),
                new Person("Irene",  200,false)
        );
	   
	    Collections.sort(P);
	   
	}
}
class Person 
{
    private String name ;
    private int money;
    private boolean marry;
    public Person(String name ,int money,boolean marry)
    {
        this.name = name;
        this.money = money;
        this.marry = marry;
    }
}
```
執行結果會跳出:==ClassCastException==
Why??
因為==Collection並不知道要sort自定義物件的哪一個property==(i.e **name?** or **monry?** or **marry?**)，也沒加以說明

---

## Comparable

Collections的sort()方法要求被排序的物件，必須實作java.lang.Comparable介面，這個介面有個compareTo()方法必須傳回大於0、等於0或小於0的數，

Collections的sort()方法在取得a物件跟b物件進行比較時，會先a物件扮演（Cast）為Comparable（也因此若物件沒實作Comparable，將會拋出ClassCastException，若使用了泛型宣告，編譯器會檢查出型態不符），然後呼叫a.compareTo(b)，如果a物件==順序上小於==b物件，必須==傳回小於0==，若==順序上相等==則==傳回0==，若==順序上a大於b==則==傳回大於0==的值。

**所以只要在物件上實作Comparable的compareTo(比較方法):**

``Ex3``
```java=
import java.util.*;
public class Main
{
	public static void main(String[] args) {
	    List<Person> P = new ArrayList<>();
	    P.add( new Person("Justin",  1000,false));
	    P.add(new Person("Monica",  500,true));
	    P.add( new Person("Irene",  200,false));
	    
	   
	    Collections.sort(P);
	   for(Person s :P)
	       System.out.println(s.money);
        
       //Output
       //200
       //500
       //1000
	   
	}
}
class Person  implements Comparable<Person> 
{
    private String name ;
    public int money;
    private boolean marry;
    public Person(String name ,int money,boolean marry)
    {
        this.name = name;
        this.money = money;
        this.marry = marry;
    }
    @Override
    public int compareTo(Person other)
    {
        /*
        if(this.money > other.money)
            return 1;
        if(this.money < other.money)
            return -1;
        return 0;
        */
        
        //simplify
        return this.money - other.money;
    }
}
```


---

## Problem

**若在實際情況中無法修改物件或無法取的原始碼**，而==無法實作Comparable==呢？(e.g String為final物件無法被繼承)

Collections的sort()方法有另一個重載版本，可接受java.util.Comparator介面的實作物件，如果你使用這個版本，排序方式將根據Comparator的==compare()定義==來決定。

``Ex4``

```java=
import java.util.*;
public class Main
{
	public static void main(String[] args) {
	    List<Person> P = new ArrayList<>();
	    P.add( new Person("Justin",  1000,false));
	    P.add(new Person("Monica",  500,true));
	    P.add( new Person("Irene",  200,false));
	    
	   
	  //  Collections.sort(P,(a,b) -> (a.money - b.money));
	    Collections.sort(P,new Comparator<Person>(){
	        @Override
	        public int compare(Person a,Person b)
	        {
	            return a.money - b.money;
	        }
	    });
	    for(Person s :P)
	        System.out.println(s.money);
            
         //Output
       //200
       //500
       //1000
            
	   
	}
}
class Person  
{
    private String name ;
    public int money;
    private boolean marry;
    public Person(String name ,int money,boolean marry)
    {
        this.name = name;
        this.money = money;
        this.marry = marry;
    }
    
    
}
```

或是使用lambda表示式簡化:

``Ex5``

```java=
import java.util.*;
public class Main
{
	public static void main(String[] args) {
	    List<Person> P = new ArrayList<>();
	    P.add( new Person("Justin",  1000,false));
	    P.add(new Person("Monica",  500,true));
	    P.add( new Person("Irene",  200,false));
	    
	   
	    Collections.sort(P,(a,b) -> (a.money - b.money));
	   
	    for(Person s :P)
	        System.out.println(s.money);
            
         //Output
       //200
       //500
       //1000
	   
	}
}
class Person  
{
    private String name ;
    public int money;
    private boolean marry;
    public Person(String name ,int money,boolean marry)
    {
        this.name = name;
        this.money = money;
        this.marry = marry;
    }
    
    
}
```

`` Collections.sort(P,(a,b) -> (a.money - b.money)); ``

第二個Input Argument 已知為Compartor型態因而不必再給,input argument,(a,b)自行判斷其形態也省略,輸出為a.money - b.money



## Conclusion

當要對List進行sort,若為一般型態(e.g Integer,String...)則可以直接使用,但若型態為自定義class,則要實作comparator來給出誰跟誰比的定義.


## Reference

https://openhome.cc/Gossip/Java/ComparableComparator.html

###### tags: `java` `Sort`