Requirement scenario description:
You need to sort a Collection in some way. For example, we need to sort a collection of User objects by company and name. The User object is as follows:
The code is as follows: |
Copy code |
Package com. guoweiwei. test. comparator; Public class User { Private String name; Private String sex; Private String company; User (){}; User (String name, String sex, String company ){ This. name = name; This. sex = sex; This. company = company; } Public String getName (){ Return name; } Public void setName (String name ){ This. name = name; } Public String getSex (){ Return sex; } Public void setSex (String sex ){ This. sex = sex; } Public void setCompany (String company ){ This. company = company; } Public String getCompany (){ Return company; } } |
Solution:
In general, we can solve the problem by using the existing sorting algorithm. However, complex sorting, such as sorting by company name, position, and employee ID, is often not enough. This requires us to implement the Comparator interface and compare it through this interface. The Comparator interface defines only one compare method. This method compares two objects based on a certain policy and returns an integer. The interface is defined as follows:
The code is as follows: |
Copy code |
Int compare (T o1, T o2 ); |
If o1 is less than o2,-1 is returned; if o1 is equal to o2, 0 is returned; if o1 is greater than o2, 1 is returned.
Based on this principle, we implement the following Comparator interface code:
The code is as follows: |
Copy code |
Package com. guoweiwei. test. comparator; Import java. util. Comparator; Public class UserComparator implements Comparator <User> { @ Override Public int compare (User user1, User user2 ){ Int comparison =-1; String company1 = user1.getCompany (); String company2 = user2.getCompany (); String name1 = user1.getName (); String name2 = user2.getName (); If (company1.length ()! = 0 & company2.length ()! = 0 ){ Comparison = company1.compareTo (company2 ); } /* If the company name is the same, compare it by name */ If (comparison = 0 & name1.length ()! = 0 & name2.length ()! = 0 ){ Comparison = name1.compareTo (name2 ); } Return comparison; } } |
With this comparator, we can sort the User List based on this comparator. The returned value is an Array or List object sorted by company name and User name. Let's take a look at our comparison code:
The code is as follows: |
Copy code |
@ SuppressWarnings ("unchecked ") Public static void startCompare (){ User user1 = new User ("A", "male", "AA "); User user2 = new User ("A", "male", "BB "); User user3 = new User ("B", "female", "AA "); User user4 = new User ("B", "male", "BB "); User user5 = new User ("C", "male", "BB "); User [] users = new User [] {user1, user2, user3, user4, user5 }; Comparator userComparator = new UserComparator (); Arrays. sort (users, userComparator ); For (User user: users ){ System. out. println (user. getCompany () + "" + user. getName () + "" + user. getSex ()); } } |
Run the program and we will get the following results:
Aa a male
Aa B female
Bb a male
Bb B male
Bb c male
Is there a simpler implementation method? The answer is yes, that is, ComparatorChain. ComparatorChain connects several Comparator objects to form a Comparator chain. When comparing two objects, compare them with each Comparator in the Comparator chain until a Comparator returns a non-zero value, and end the comparison, continue to use the next Comparator in the chain for comparison. The following code is used:
The code is as follows: |
Copy code |
@ SuppressWarnings ("unchecked ") Public static void start (){ User user1 = new User ("A", "male", "AA "); User user2 = new User ("A", "male", "BB "); User user3 = new User ("B", "female", "AA "); User user4 = new User ("B", "male", "BB "); User user5 = new User ("C", "male", "BB "); User [] users = new User [] {user1, user2, user3, user4, user5 }; ComparatorChain comparatorChain = new ComparatorChain (); ComparatorChain. addComparator (new BeanComparator ("name ")); ComparatorChain. addComparator (new BeanComparator ("sex"), true ); ComparatorChain. addComparator (new BeanComparator ("company ")); Arrays. sort (users, comparatorChain ); For (User user: users ){ System. out. println (user. getName () + "" + user. getSex () + "" + user. getCompany ()); } } |
Run the program and we will get the following results:
A male AA
A male BB
B male BB
B female AA
C male BB
The following two points should be noted: ① ComparatorChain comes from the commons. collections package. BeanComparator comes from the commons. beanutils package, so you must reference these two packages. ② For the second parameter in the comparatorChain. addComparator () method, the meaning is whether to reverse (that is, if it is true, it is reverse, and the default value is ascending ).
Requirement upgrade:
Further, you may have questions. It seems that Company B's AA and BB are not correct. What sort of Chinese is this based on? The gender should be female or male. At this point, I cannot say it, because I don't know what the Chinese here is based on. What should we do in the face of Chinese?
Fortunately, there are a lot of Chinese tools that can help us implement them. The common ones are Collator and pinyin4j. Collator is a built-in JDK localization tool, and pinyin4j is an open-source project on google. Comparator is sorted in Chinese by Collator as follows:
The code is as follows: |
Copy code |
Public class ChineseComparator implements Comparator <String> { Private final static Collator collator = Collator. getInstance (Locale. CHINESE ); @ Override Public int compare (String str1, String str2 ){ Int comparison =-1; If (str1 = null & str2 = null ){ Comparison = 0; } Elseif (str1 = null ){ Comparison =-1; } Elseif (str2 = null ){ Comparison = 1; } Else { CollationKey key1 = collator. getCollationKey (str1 ); CollationKey key2 = collator. getCollationKey (str2 ); Comparison = key1.compareTo (key2 ); } Return comparison; } } |
Replace the User array and Comparator to be sorted as follows:
The code is as follows: |
Copy code |
@ SuppressWarnings ("unchecked ") Public static void start (){ User user1 = new User ("Ma Jiajue", "male", "China Merchants "); User user2 = new User ("Li Gang", "male", "Public Security Bureau "); User user3 = new User ("Ma Jiajue", "female", "China Merchants "); User user4 = new User ("Li Ying", "male", "Public Security Bureau "); User user5 = new User ("Ma Jiajue", "male", "Public Security Bureau "); User [] users = new User [] {user1, user2, user3, user4, user5 }; Comparator chineseComparator = new ChineseComparator (); ComparatorChain comparatorChain = new ComparatorChain (); ComparatorChain. addComparator (new BeanComparator ("company", chineseComparator )); ComparatorChain. addComparator (new BeanComparator ("name", chineseComparator )); ComparatorChain. addComparator (new BeanComparator ("sex", chineseComparator )); Arrays. sort (users, comparatorChain ); For (User user: users ){ System. out. println (user. getCompany () + "" + user. getName () + "" + user. getSex ()); } } } |
Run the code and get the following results:
Public Security Bureau Li Gangnan
Public Security Bureau Li Yingnan
Ma Jiajue, male, public security bureau
Ma Jiajue, male, China Merchants
Ma Jiajue, female from China Merchants
Additional reading:
Comparison of null:
The code is as follows: |
Copy code |
Comparator userComparator = new UserComparator (); Comparator nullComparator = new NullComparator (userComparator, true ); |
Comparison of fixed sequence:
The code is as follows: |
Copy code |
String [] weeks = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday "}; Comparator fixedComparator = new FixedOrderComparator (weeks ); Comparator weeksComparator = new BeanComparator ("week", fixedComparator );
|