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


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

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碼排序)

代碼入下:

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)]

排序后:

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

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

 

但是這里有一定的限制,傳入的排序字段必須存在,並且要提供get方法。還有就是只能對單個屬性排序,如果要對多個屬性排序,僅僅使用BeanComparator是不能完成的。具體的解決方案后邊會提到。

而工作中往往會有定制化的需求,那如果要對對象按照指定的順序排序,就需要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對象的定制化多規則排序,具體實現根據需求來決定。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM