在 Collections 有許多排序比較等等的方法已經寫好,基本類型的比較可以直接使用,如
1: ArrayList al = new ArrayList();
2:
3: for(int i=0; i<10; i++){
4:
5: Random r = new Random();
6: al.add(r.nextInt(1000));
7: }
8:
9: Collections.sort(al);
在 al 中的元素將會由小到大排好,但是如果 al 中的元素並不是基本類型,而是自創類別,而想比較的是自創類別中的某個屬性值,那麼可以實作 Comparable 介面,再覆寫 compareTo 方法,如下
AccountDetail.java
1: package com.example.helloworld;
2:
3: import java.util.Comparator;
4:
5: public class AccountDetail implements Comparable<Object>{
6:
7: static int dataCount;
8: public String time;
9: public String money;
10: public String remark;
11:
12: public AccountDetail(){
13: dataCount++;
14: time = "0000/00/00";
15: money = "0";
16: remark = "0";
17: }
18:
19: public AccountDetail(String time,String money,String type){
20: dataCount++;
21: this.time = time;
22: this.money = money;
23: this.remark = type;
24: }
25:
26: @Override
27: public int compareTo(Object another) {
28: // TODO Auto-generated method stub
29:
30: AccountDetail adAnother = (AccountDetail)another;
31:
32: if(Integer.valueOf(this.money)>Integer.valueOf(adAnother.money))
33: {
34: return 1;// move element back
35: }
36: else if(Integer.valueOf(this.money)<Integer.valueOf(adAnother.money)){
37:
38: return -1;//move element forward
39: }
40: else{
41: return 0;
42: }
43:
44:
45: }
46:
47: }
48:
AccountDetail 裡面有 3 個屬性,分別為 time , money , remark , 在第 5 行實作 Comparable 介面, 接著第 27 行覆寫 compareTo 方法, 方法裡面就寫出自訂的比較規則, 只要注意回傳值,1 代表往前排, -1 代表往後排,這段程式碼就代表比較 money 並由小排到大,最後使用的方式如下
1: ArrayList<AccountDetail> al = new ArrayList<AccountDetail>();
for(int i=0; i<10 ;i++){
2:
3: Random r = new Random();
4:
5: al.add(new AccountDetail("testtime",""+r.nextInt(1000)+i,"testremark"));
6: }
7:
8: Collections.sort(al);
第 1 ~ 6 行建立 ArrayList al, 最後第 8 行排序,就這麼簡單,不過使用 Comparable 介面的缺點是只能使用單種排序,如果還想針對 time , remark 做排序,可以使用 Comparator 介面,好處除了可對多種數值做排序外,也不必綁定在 AccountDetail 類別中,你可以把它封裝出來(不過我還是寫在一起)
AccountDetail.java
1: package com.example.helloworld;
2:
3: import java.util.Comparator;
4:
5: import FoXxLib.FP;
6:
7: public class AccountDetail
8: //implements Comparable<Object>
9: {
10:
11: static int dataCount;
12: public String time;
13: public String money;
14: public String remark;
15:
16: public AccountDetail(){
17: dataCount++;
18: time = "0000/00/00";
19: money = "0";
20: remark = "0";
21: }
22:
23: public AccountDetail(String time,String money,String type){
24: dataCount++;
25: this.time = time;
26: this.money = money;
27: this.remark = type;
28: }
29:
30: // @Override
31: // public int compareTo(Object another) {
32: // // TODO Auto-generated method stub
33: //
34: // AccountDetail adAnother = (AccountDetail)another;
35: //
36: // if(Integer.valueOf(this.money)>Integer.valueOf(adAnother.money))
37: // {
38: // return 1;// back
39: // }
40: // else if(Integer.valueOf(this.money)<Integer.valueOf(adAnother.money)){
41: //
42: // return -1;//forward
43: // }
44: // else{
45: // return 0;
46: // }
47: //
48: //
49: // }
50:
51: public MoneyComparator moneyComp(){
52:
53: MoneyComparator mc = new MoneyComparator();
54:
55: return mc;
56: }
57:
58: public TimeComparator timeComp(){
59:
60: TimeComparator tc = new TimeComparator();
61:
62: return tc;
63: }
64: }
65:
66: class MoneyComparator implements Comparator<Object>{
67:
68: @Override
69: public int compare(Object lhs, Object rhs) {
70: // TODO Auto-generated method stub
71: AccountDetail ad1 = (AccountDetail)lhs;
72: AccountDetail ad2 = (AccountDetail)rhs;
73: if(Integer.valueOf(ad1.money)>Integer.valueOf(ad2.money)){
74: return 1;
75: }
76: else if(Integer.valueOf(ad1.money)<Integer.valueOf(ad2.money)){
77: return -1;
78: }
79: else{
80: return 0;
81: }
82: }
83:
84: }
85:
86: class TimeComparator implements Comparator<Object>{
87:
88: @Override
89: public int compare(Object lhs, Object rhs) {
90: // TODO Auto-generated method stub
91: int tempReturn =0;
92: AccountDetail ad1 = (AccountDetail)lhs;
93: AccountDetail ad2 = (AccountDetail)rhs;
94:
95: String[] tempstr1 = ad1.time.split("[/]");
96: int[] tempint1 = new int[tempstr1.length];
97: for(int i=0; i<tempstr1.length; i++){
98: tempint1[i] = Integer.valueOf(tempstr1[i]);
99: // FP.p(""+tempint1[i]);
100: }
101:
102: String[] tempstr2 = ad2.time.split("[/]");
103: int[] tempint2 = new int[tempstr2.length];
104: for(int i=0; i<tempstr2.length; i++){
105: tempint2[i] = Integer.valueOf(tempstr2[i]);
106: // FP.p(""+tempint2[i]);
107: }
108:
109: for(int i=0; i<tempint1.length; i++){
110:
111: if(tempint1[i]>tempint2[i]){
112: tempReturn = -1;
113: break;
114: }
115: else if(tempint1[i]<tempint2[i]){
116: tempReturn = 1;
117: break;
118: }
119: else if(tempint1[i]==tempint2[i])
120: {
121: tempReturn =0;
122: }
123: }
124:
125: return tempReturn;
126:
127: }
128:
129: }
130:
先把原先使用 Comparator 介面 的部分註解掉(第 8 行, 第 30 ~ 49 行)
第 51 ~ 56 行建立並回傳 money 的比較器
第 58 ~ 63 行建立並回傳 time 的比較器
第 66 ~ 84 行為 money 比較器的定義, 先實作 Comparator 介面
第 69 行覆寫 compare 方法, lhs 和 rhs 各為比較的物件,至於 compare 的內容就自己定義了
第 86 ~ 129 行為 time 比較器的定義,由於 time 包含了年月日,必須先切割字串,再放入陣列中等待比較,第 109 ~ 123 行為比較的方法
最後使用的方式如下
1: Collections.sort(al, al.get(0).timeComp());
第 1 個參數為比較的內容,第 2 個參數為比較器, timeComp 會回傳 time 比較器,當然你也可以改為 al.get(0).moneyComp() , 來比較 money
注意事項:
1.如果使用 Comparator 介面,且和要比較的容器類別綁在一起(就是上述的 AccountDetail.java),必須注意當沒有產生任何元素,還要排序時,會出現錯誤,所以排序類別還是拆開比較好如下
AD_Sort.java
1: package com.example.helloworld;
2:
3: import java.util.Comparator;
4:
5: public abstract class AD_Sort implements Comparator<Object>{
6:
7: }
8:
9: class MoneyComparator extends AD_Sort{
10:
11: @Override
12: public int compare(Object lhs, Object rhs) {
13: // TODO Auto-generated method stub
14: AccountDetail ad1 = (AccountDetail)lhs;
15: AccountDetail ad2 = (AccountDetail)rhs;
16: if(Integer.valueOf(ad1.money)>Integer.valueOf(ad2.money)){
17: return -1;
18: }
19: else if(Integer.valueOf(ad1.money)<Integer.valueOf(ad2.money)){
20: return 1;
21: }
22: else{
23: return 0;
24: }
25: }
26:
27: }
28:
29: class TimeComparator extends AD_Sort{
30:
31: @Override
32: public int compare(Object lhs, Object rhs) {
33: // TODO Auto-generated method stub
34: int tempReturn =0;
35: AccountDetail ad1 = (AccountDetail)lhs;
36: AccountDetail ad2 = (AccountDetail)rhs;
37:
38: String[] tempstr1 = ad1.time.split("[/]");
39: int[] tempint1 = new int[tempstr1.length];
40: for(int i=0; i<tempstr1.length; i++){
41: tempint1[i] = Integer.valueOf(tempstr1[i]);
42: // FP.p(""+tempint1[i]);
43: }
44:
45: String[] tempstr2 = ad2.time.split("[/]");
46: int[] tempint2 = new int[tempstr2.length];
47: for(int i=0; i<tempstr2.length; i++){
48: tempint2[i] = Integer.valueOf(tempstr2[i]);
49: // FP.p(""+tempint2[i]);
50: }
51:
52: for(int i=0; i<tempint1.length; i++){
53:
54: if(tempint1[i]>tempint2[i]){
55: tempReturn = -1;
56: break;
57: }
58: else if(tempint1[i]<tempint2[i]){
59: tempReturn = 1;
60: break;
61: }
62: else if(tempint1[i]==tempint2[i])
63: {
64: tempReturn =0;
65: }
66: }
67:
68: return tempReturn;
69:
70: }
71:
72: }
然後使用的方式為
1: AD_Sort ads;
2: ads = new MoneyComparator();
3: // ads = new TimeComparator();
4: Collections.sort(al, ads);
第 2 ~ 3 為多型的使用