Java对List多个排序、查询条件的处理
?
import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Type;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.Comparator;import java.util.List;import com.google.common.base.Predicate;import com.google.common.collect.Collections2;import com.google.common.collect.ComparisonChain;/** * Filter and Sort <code>List</code> by multiple conditions.<br> * It's like SQL 'Where' and 'Order by' clause. Input multiple <code>Comparator</code> * * @author zheng.wen http://www.oschina.net/question/12_21127 * @param <T> */public class GroupFilterSortUtils<T> implements Comparator<T> {/**排序方式**/interface Sort {public static final String DESC = "DESC";public static final String ASC = "ASC";/**数组下标0,排序条件名称**/public static final int NAME = 0;/**数组下标1,排序方式**/public static final int TYPE = 1;}/**过滤条件**/interface Filter {/**过滤模式**/public static final String LIKE = "0";public static final String START_WITH = "1";public static final String EQUAL = "2";public static final String LESS_THAN = "3";public static final String MORE_THAN = "4";/**大小写**/public static final String DIFF_CASE_TRUE = "TRUE";public static final String DIFF_CASE_FALSE = "FALSE";/**数组下标0,过滤条件名称**/public static final int NAME = 0;/**数组下标1,过滤条件值**/public static final int VALUE = 1;/**数组下标2,过滤模式**/public static final int MODE = 2;/**是否区分大小写**/public static final int IS_DIFF_CASE = 3;}public GroupFilterSortUtils() { }/**存储比较器: 此处不能使用static**/private List<Comparator<Object>> comparators = new ArrayList<Comparator<Object>>();public int compare(T t1, T t2) {if (t1 == null || t2 == null) return 0;for (Comparator<Object> comparator : comparators) {int returnValue = comparator.compare(t1, t2);if (returnValue != 0) return returnValue;}return 0;}public static <T> List<T> filterList(final List<T> list, final String[] ... filterChain) {if (list == null || list.size() <= 0 || filterChain == null || filterChain.length <=0) return list;if (list.contains(null)) list.remove(null);List<T> tempList = new ArrayList<T>();boolean flag;for (T t : list) {if (t == null) continue;flag = true;for (String[] filter : filterChain) {if (!flag) break;flag = false;String filterName = filter[Filter.NAME];String filterValue = filter[Filter.VALUE];String filterMode = filter[Filter.MODE];String isDiffUpperLowerCase = filter[Filter.IS_DIFF_CASE];boolean isDiffCase = Boolean.parseBoolean(isDiffUpperLowerCase);try {String methodName = "get" + firstLetterToUpper(filterName);Method method = t.getClass().getDeclaredMethod(methodName, null);Object o = method.invoke(t, null);String realValue = o != null ? o.toString() : "";String filterValue2 = isDiffCase ? filterValue : filterValue.toLowerCase();String realValue2 = isDiffCase ? realValue : realValue.toLowerCase();if ((Filter.START_WITH.equals(filterMode) && realValue2.startsWith(filterValue2)) ||(Filter.LIKE.equals(filterMode) && realValue2.indexOf(filterValue2) != -1) ||(Filter.EQUAL.equals(filterMode) && realValue2.equals(filterValue2)) ||(Filter.MORE_THAN.equals(filterMode) && Double.parseDouble(realValue2) > Double.parseDouble(filterValue2)) ||(Filter.LESS_THAN.equals(filterMode) && Double.parseDouble(realValue2) < Double.parseDouble(filterValue2))) flag = true;} catch (Exception e) {e.printStackTrace();}}if (flag) tempList.add(t);}return tempList;}public <T> List<T> sortList(final List<T> list, final String[]... sortChain) {if (list == null || list.size() <= 0 || sortChain == null || sortChain.length <=0) return list;if (list.contains(null)) list.remove(null);this.setComparator(sortChain);List<T> tempList = new ArrayList<T>();tempList.addAll(list);Collections.sort(tempList, (GroupFilterSortUtils<T>) this);return tempList;}public <T> List<T> filterSortList(final List<T> list, final String[][] filterChain, final String[][] sortChain) {if (list == null || list.size() <= 0 || filterChain == null || filterChain.length <= 0 || sortChain == null || sortChain.length <=0) return list;if (list.contains(null)) list.remove(null);List<T> tempList = filterList(list, filterChain);this.setComparator(sortChain);Collections.sort(tempList, (GroupFilterSortUtils<T>) this);return tempList;}public static String firstLetterToUpper(String str){if (str == null || "".equals(str)) return str; char[] array = str.toCharArray(); array[0] -= 32; return String.valueOf(array); }private <T> void setComparator(final String[][] sortCriteria) {if (sortCriteria == null || sortCriteria.length <= 0) return;for (final String[] criteria : sortCriteria) {Comparator<T> sortComparator = new Comparator<T> () {public int compare(T t1, T t2) {if (t1 == null || t2 == null) return 0;int result = 0;try {String name = criteria[Sort.NAME];String type = criteria[Sort.TYPE];Field field = t1.getClass().getDeclaredField(name);Type fieldType = field.getType();String methodName = "get" + firstLetterToUpper(name);Method method = t1.getClass().getDeclaredMethod(methodName, null);Object o1 = method.invoke(t1, null);Object o2 = method.invoke(t2, null);if (fieldType == Integer.TYPE || fieldType == Long.TYPE || fieldType == Double.TYPE || fieldType == Float.TYPE || fieldType == Short.TYPE || fieldType == Byte.TYPE) {result = type.equals(GroupComparator.DESC) ? (Integer) o2 - (Integer) o1 : (Integer) o1 - (Integer) o2;} else if (fieldType == String.class || fieldType == Character.class) {String str1 = o1 == null ? "" : o1.toString();String str2 = o2 == null ? "" : o2.toString();result = type.equals(GroupFilterSortUtils.Sort.DESC) ? str2.compareTo(str1) : str1.compareTo(str2);}} catch (Exception e) {e.printStackTrace();}return result;}};comparators.add((Comparator<Object>) sortComparator);}}public static void main(String[] args) {List<User> userList = new ArrayList<User>() {{add(new User(1, "aaa", 10, 5, 4004, 1));add(new User(2, "aac", 22, 5, 5300, 1));add(new User(3, "aab", 10, 4, 4800, 1));add(new User(4, "ccc", 33, 5, 5000, 3));add(new User(5, "yyy", 55, 1, 4000, 1));add(new User(6, "bbb", 77, 1, 5800, 4));add(new User(7, "qqq", 56, 2, 4000, 7));add(new User(8, "ece", 18, 3, 5500, 1));add(new User(9, "ggg", 30, 4, 7050, 3));add(new User(10, "vcv", 9, 2, 4560, 1));add(new User(11, "vcv", 9, 5, 8560, 1));}};for(int i = 0; i < 1000000; i++) {userList.add(new User(i+12, "kkk" + i, 40, 7, 9000, i));}String[][] filterChain = {{User.Filter.NAME, "k", GroupFilterSortUtils.Filter.LIKE, GroupFilterSortUtils.Filter.DIFF_CASE_FALSE}, {User.Filter.SALARY, "00", GroupFilterSortUtils.Filter.LIKE, GroupFilterSortUtils.Filter.DIFF_CASE_FALSE}, {User.Filter.YEAR, "30", GroupFilterSortUtils.Filter.MORE_THAN, GroupFilterSortUtils.Filter.DIFF_CASE_FALSE} };String[][] sortChain = {{ User.Sort.NAME, GroupFilterSortUtils.Sort.ASC },{ User.Sort.LEVEL, GroupFilterSortUtils.Sort.DESC },{ User.Sort.SALARY, GroupFilterSortUtils.Sort.DESC },{ User.Sort.YEAR, GroupFilterSortUtils.Sort.DESC } };long start = System.currentTimeMillis();GroupFilterSortUtils<User> groupFilterSort = new GroupFilterSortUtils<User>();List<User> tempList = groupFilterSort.filterList(userList, filterChain);long start2 = System.currentTimeMillis();tempList = groupFilterSort.sortList(tempList, sortChain);long end = System.currentTimeMillis();System.out.println("1:" + (start2 - start) + " 2:" + (end - start2) + " 3:" + (end - start));System.out.println(tempList.size());//for (User user : tempList) {//System.out.println(user.getName() + " : " + user.getSalary() + " : " + user.getYear());//}}}class User {private int id;private String name;private int age;private int level;private int salary;private int year;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getLevel() {return level;}public void setLevel(int level) {this.level = level;}public int getSalary() {return salary;}public void setSalary(int salary) {this.salary = salary;}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public User(int id, String name, int age, int level, int salary, int year) {super();this.id = id;this.name = name;this.age = age;this.level = level;this.salary = salary;this.year = year;}interface Filter {public static final String NAME = "name";public static final String LEVEL = "level";public static final String SALARY = "salary";public static final String YEAR = "year";}interface Sort {public static final String NAME = "name";public static final String LEVEL = "level";public static final String SALARY = "salary";public static final String YEAR = "year";}public static void main(String[] args) {List<User> userList = new ArrayList<User>() {{add(new User(1, "aaa", 10, 5, 4004, 1));add(new User(2, "aac", 22, 5, 5300, 1));add(new User(3, "aab", 10, 4, 4800, 1));add(new User(4, "ccc", 33, 5, 5000, 3));add(new User(5, "yyy", 55, 1, 4000, 1));add(new User(6, "bbb", 77, 1, 5800, 4));add(new User(7, "qqq", 56, 2, 4000, 7));add(new User(8, "ece", 18, 3, 5500, 1));add(new User(9, "ggg", 30, 4, 7050, 3));add(new User(10, "vcv", 9, 2, 4560, 1));add(new User(11, "vcv", 9, 5, 8560, 1));}};for(int i = 0; i < 1000000; i++) {userList.add(new User(i+12, "kkk" + i, 40, 7, 9000, i));}long start = System.currentTimeMillis();Collection<User> filterCollection = Collections2.filter(userList, new Predicate<User>(){public boolean apply(User user) {if (user == null) return false;String name = user.getName() + "";String salary = user.getSalary() + "";int year = user.getYear();if (name.indexOf("k") != -1 && salary.indexOf("00") != -1 && year > 30) {return true;}return false;}});long start2 = System.currentTimeMillis();User[] userArray = new User[filterCollection.size()];List<User> tempList = Arrays.asList(filterCollection.toArray(userArray));long start3 = System.currentTimeMillis();Collections.sort(tempList, new Comparator<User>(){public int compare(User o1, User o2) {if (o1 == null || o2 == null) return 0;return ComparisonChain.start() .compare(o1.getName(), o2.getName()) .compare(o1.getLevel(), o2.getLevel()) .compare(o2.getSalary(), o1.getSalary()) .compare(o1.getYear(), o2.getYear()).result(); }});long end = System.currentTimeMillis();System.out.println("1:" + (start2 - start) + " 2:" + (start3 - start2) + " 3:" + (end - start3) + " all:" + (end - start));System.out.println(tempList.size());//for (User user : tempList) {//System.out.println(user.getName() + " : " + user.getSalary() + " : " + user.getYear());//}}}