JAVA實現根據對象的屬性排序--BeanComparator,FixedOrderComparator,ComparatorChain

最近看到這樣一段排序的代碼。java

public  static List<?> getBrandOrderList(List<?> list, String Field) {
        String[] brandArr = {"7天", "7天優品", "IU", "", "麗楓", "喆啡", "希岸", "歡朋", "潮漫", "ZMAX", "非繁&城品"};
        Comparator typeComparator = new FixedOrderComparator(brandArr);
        Comparator indexTypeComparator = new BeanComparator(Field, typeComparator);
        Collections.sort(list, indexTypeComparator);
        return list;
    }

後來瞭解到,這段代碼是爲了實現:對傳入的列表list按照對象的屬性Field排序,而順序要和數組brandArr一致。數組

首先,咱們經常會遇到須要對javaBean排序的狀況,若是是對javaBean的單一屬性排序,能夠直接使用BeanComparator實現天然排序(根據ASCII碼排序)spa

代碼入下:code

1 List<Student> list = new ArrayList<>();
2         list.add(new Student("張三",1));
3         list.add(new Student("王五",1));
4         list.add(new Student("李四",1));
5         list.add(new Student("趙六",1));
6         System.out.println(list);
7         BeanComparator beanComparator = new BeanComparator("name");
8         Collections.sort(list,beanComparator);
9         System.out.println(list);

運行結果以下:對象

[Student(name=張三, age=1), Student(name=王五, age=1), Student(name=李四, age=1), Student(name=趙六, age=1)]blog

排序後:排序

[Student(name=張三, age=1), Student(name=李四, age=1), Student(name=王五, age=1), Student(name=趙六, age=1)]get

這裏有一個很是巧合的事情,就是根據ASCII排序,張 李 王 趙是順序排列的。io

 

可是這裏有必定的限制,傳入的排序字段必須存在,而且要提供get方法。還有就是隻能對單個屬性排序,若是要對多個屬性排序,僅僅使用BeanComparator是不能完成的。具體的解決方案後邊會提到。class

而工做中每每會有定製化的需求,那若是要對對象按照指定的順序排序,就須要FixedOrderComparator實現定製化的排序規則。

 1 List<Student> list = new ArrayList<Student>(){
 2             {
 3                 add(new Student("張三",28));
 4                 add(new Student("王五",23));
 5                 add(new Student("李四",26));
 6                 add(new Student("趙六",17));
 7             }
 8         };
 9         //指定排序規則,參數可使集合,數組或可變參數
10         FixedOrderComparator fixedOrderComparator = new FixedOrderComparator("張三","李四","王五","趙六");
11         //將要排序的屬性,和自定義排序規則傳入
12         BeanComparator beanComparator = new BeanComparator("name",fixedOrderComparator);
13         //排序操做
14         Collections.sort(list,beanComparator);
15         System.out.println(list);

輸出:

[Student(name=張三, age=28), Student(name=李四, age=26), Student(name=王五, age=23), Student(name=趙六, age=17)]

 這也就是開頭提到的例子實現的功能。

 

另外,若是要實現多元素排序,須要用到ComparatorChain

 1 List<Student> list = new ArrayList<Student>(){
 2             {
 3                 add(new Student("張三",28));
 4                 add(new Student("王五",23));
 5                 add(new Student("李四",26));
 6                 add(new Student("李四",23));
 7                 add(new Student("趙六",17));
 8             }
 9         };
10         ComparatorChain comparatorChain = new ComparatorChain();
11         //按照名稱排序
12         FixedOrderComparator nameComparator = new FixedOrderComparator("張三","李四","王五","趙六");
13         BeanComparator nameBeanComparator = new BeanComparator("name",nameComparator);
14         //按照年齡排序
15         FixedOrderComparator ageComparator = new FixedOrderComparator(28,26,23,17);
16         BeanComparator ageBeanComparator = new BeanComparator("age",ageComparator);
17         //加入排序規則
18         comparatorChain.addComparator(nameBeanComparator);
19         comparatorChain.addComparator(ageBeanComparator);
20         //排序操做
21         Collections.sort(list,comparatorChain);
22         System.out.println(list);

輸出:

[Student(name=張三, age=28), Student(name=李四, age=26), Student(name=李四, age=23), Student(name=王五, age=23), Student(name=趙六, age=17)]

能夠看到,在名稱排序相同的狀況下,李四是按照26在前,23在後的順序排列的

 

 

其中的坑:

  1.對象屬性提供get方法

  2.若是要實現定製化排序,定製化的排序規則中,必需要包含全部排序列可能出現的值(好比說:集合中出現的全部age值,在new FixedOrderComparator(28,26,23,17)中必須所有出現,不然會出現java.lang.IllegalArgumentException: Attempting to compare unknown object xx這樣的報錯。

總之,經過這三個對象,能夠實現Bean對象的定製化多規則排序,具體實現根據需求來決定。

相關文章
相關標籤/搜索