实现一个通用的中英文排序工具
生活随笔
收集整理的這篇文章主要介紹了
实现一个通用的中英文排序工具
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
利用Collator類可以輕松實現排序,但是我們可能有各種model都需要進行排序,這樣就會有一個問題,如果單獨為每個model寫一段排序代碼,代碼重復量很大。
所以我打算寫一個通用的工具,使用泛型+注解+反射的方式來解決。
注解
首先創建注解類
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD}) @Documented public @interface SortString { }這個注解的作用就是標識哪個字段或函數是用來排序。
工具類
然后是排序工具類,在我這個工具中排序規則是:中文 > 數字 > 英文,這是我們app的需求,大家可以根據自己的需求進行修改。
完整代碼如下
public class SimplifiedChineseSorter {private static final String SORTINGREGEX = "[^\\p{L}\\p{N}]+|^(The|A|An)\\b";private static final Collator stringComparator = Collator.getInstance(Locale.SIMPLIFIED_CHINESE);public static <T> List<T> sortByProvider(List<T> items, SortStringProvider<T> provider, boolean isIgnoreCase) {if (items == null || items.size() <= 0) {return null;}return sortList(items, provider, isIgnoreCase);}public static <T> List<T> sortByFieldName(List<T> items, String fieldName, boolean isIgnoreCase) {if (items == null || items.size() <= 0) {return null;}Field field = getSortStringField(items.get(0).getClass(), fieldName);DefualtSortStringProvider<T> provider = new DefualtSortStringProvider<T>(field);return sortList(items, provider, isIgnoreCase);}public static <T> List<T> sortByFieldAnnotation(List<T> items, boolean isIgnoreCase) {if (items == null || items.size() <= 0) {return null;}Field field = getSortStringField(items.get(0).getClass());DefualtSortStringProvider<T> provider = new DefualtSortStringProvider<T>(field);return sortList(items, provider, isIgnoreCase);}public static <T> List<T> sortByMethodName(List<T> items, String methodName, boolean isIgnoreCase) {if (items == null || items.size() <= 0) {return null;}Method method = getSortStringMethod(items.get(0).getClass(), methodName);DefualtSortStringProvider<T> provider = new DefualtSortStringProvider<T>(method);return sortList(items, provider, isIgnoreCase);}public static <T> List<T> sortByMethodAnnotation(List<T> items, boolean isIgnoreCase) {if (items == null || items.size() <= 0) {return null;}Method method = getSortStringMethod(items.get(0).getClass());DefualtSortStringProvider<T> provider = new DefualtSortStringProvider<T>(method);return sortList(items, provider, isIgnoreCase);}private static <T> List<T> sortList(List<T> items, final SortStringProvider<T> provider, final boolean isIgnoreCase) {if(provider == null){return items;}final List<T> chinieseList = new ArrayList<T>();final List<T> nonChineseList = new ArrayList<T>();for (T item : items) {if (isChineseCharStart(format(provider.getSortString(item), isIgnoreCase))) {chinieseList.add(item);} else {nonChineseList.add(item);}}List<T> sortedChineseList = Ordering.from(new Comparator<T>() {@Overridepublic int compare(T lhs, T rhs) {return stringComparator.compare(format(provider.getSortString(lhs), isIgnoreCase), format(provider.getSortString(rhs), isIgnoreCase));}}).sortedCopy(chinieseList);List<T> sortedNonChineseList = Ordering.from(new Comparator<T>() {@Overridepublic int compare(T lhs, T rhs) {return format(provider.getSortString(lhs), isIgnoreCase).compareTo(format(provider.getSortString(rhs), isIgnoreCase));}}).sortedCopy(nonChineseList);sortedChineseList.addAll(sortedNonChineseList);return sortedChineseList;}public static <T> Comparator<T> getSortComparatorByProvider(final Class clazz, SortStringProvider<T> provider, boolean isIgnoreCase) {return getSortComparator(provider, isIgnoreCase);}public static <T> Comparator<T> getSortComparatorByFieldName(final Class clazz, final String fieldName, boolean isIgnoreCase) {Field field = getSortStringField(clazz, fieldName);DefualtSortStringProvider<T> provider = new DefualtSortStringProvider<T>(field);return getSortComparator(provider, isIgnoreCase);}public static <T> Comparator<T> getSortComparatorByFieldAnnotation(final Class clazz, boolean isIgnoreCase) {Field field = getSortStringField(clazz);DefualtSortStringProvider<T> provider = new DefualtSortStringProvider<T>(field);return getSortComparator(provider, isIgnoreCase);}public static <T> Comparator<T> getSortComparatorByMethodName(final Class clazz, final String methodName, boolean isIgnoreCase) {Method method = getSortStringMethod(clazz, methodName);DefualtSortStringProvider<T> provider = new DefualtSortStringProvider<T>(method);return getSortComparator(provider, isIgnoreCase);}public static <T> Comparator<T> getSortComparatorByMethodAnnotation(final Class clazz, boolean isIgnoreCase) {Method method = getSortStringMethod(clazz);DefualtSortStringProvider<T> provider = new DefualtSortStringProvider<T>(method);return getSortComparator(provider, isIgnoreCase);}private static <T> Comparator<T> getSortComparator(final SortStringProvider<T> provider, final boolean isIgnoreCase) {return new Comparator<T>() {@Overridepublic int compare(final T left, final T right) {String leftStr = format(provider.getSortString(left), isIgnoreCase);String rightStr = format(provider.getSortString(right), isIgnoreCase);if (SimplifiedChineseSorter.isChineseCharStart(leftStr) &&SimplifiedChineseSorter.isChineseCharStart(rightStr)) {return stringComparator.compare(leftStr, rightStr);} else {return ComparisonChain.start().compareTrueFirst(SimplifiedChineseSorter.isChineseCharStart(leftStr),SimplifiedChineseSorter.isChineseCharStart(rightStr)).compare(leftStr, rightStr, Ordering.natural().nullsFirst()).result();}}};}public static boolean isChineseCharStart(String str) {return !str.matches("[A-Za-z0-9\"“”]+.*");}private static <T> Field getSortStringField(Class<T> tClass) {Field[] fields = tClass.getDeclaredFields();if (fields != null) {for (Field field : fields) {if (field.isAnnotationPresent(SortString.class) && field.getType() == String.class) {field.setAccessible(true);return field;}}}Class superClass = tClass.getSuperclass();if(superClass != null && !superClass.equals(Object.class)){return getSortStringField(superClass);}throw new RuntimeException("The model doesn't have a @SortString field or the type of @SortString field is not a String");}private static <T> Field getSortStringField(Class<T> tClass, String sortFieldName) {Field field = null;try {field = tClass.getDeclaredField(sortFieldName);} catch (NoSuchFieldException e) {}finally {if (field != null && field.getType() == String.class) {field.setAccessible(true);return field;}Class superClass = tClass.getSuperclass();if(superClass != null && !superClass.equals(Object.class)){return getSortStringField(superClass, sortFieldName);}throw new RuntimeException("The model doesn't have a field named " + sortFieldName);}}private static <T> Method getSortStringMethod(Class<T> tClass) {Method[] methods = tClass.getDeclaredMethods();if (methods != null) {for (Method method : methods) {if (method.isAnnotationPresent(SortString.class) && method.getReturnType() == String.class) {method.setAccessible(true);return method;}}}Class superClass = tClass.getSuperclass();if(superClass != null && !superClass.equals(Object.class)){return getSortStringMethod(superClass);}throw new RuntimeException("The model doesn't have a @SortString method or the returnning type of @SortString method is not a String");}private static <T> Method getSortStringMethod(Class<T> tClass, String sortMethodName) {Method method = null;try {method = tClass.getDeclaredMethod(sortMethodName);} catch (NoSuchMethodException e) {}finally {if (method != null && method.getReturnType() == String.class) {method.setAccessible(true);return method;}Class superClass = tClass.getSuperclass();if(superClass != null && !superClass.equals(Object.class)){return getSortStringMethod(superClass, sortMethodName);}throw new RuntimeException("The model doesn't have a method named " + sortMethodName);}}private static String format(String data, boolean isIgnoreCase) {Pattern pattern = Pattern.compile(SORTINGREGEX, Pattern.CASE_INSENSITIVE);if(data == null){return "";}else if(isIgnoreCase){return pattern.matcher(data.trim()).replaceAll("").toLowerCase();}else{return pattern.matcher(data.trim()).replaceAll("");}}static class DefualtSortStringProvider<T> implements SortStringProvider<T>{private Object orderBy;DefualtSortStringProvider(Object orderBy){this.orderBy = orderBy;}public String getSortString(T obj){try {if (orderBy instanceof Field) {return (String) ((Field) orderBy).get(obj);} else if (orderBy instanceof Method) {return (String) ((Method)orderBy).invoke(obj);}}catch (Exception e){Log.e("SimplifiedChineseSorter", "getSortString", e);}return "";}}public interface SortStringProvider<T>{String getSortString(T obj);} }這個類比較大而全,提供了很多方法來進行排序,其中主要四個函數:
- sortByFieldName:通過給定的字段名對應的字段進行排序
- sortByFieldAnnotation:通過帶有@SortString的字段進行排序
- sortByMethodName:通過給定的函數名對應的函數進行排序
- sortByMethodAnnotation:通過帶有@SortString的函數進行排序
其中注意
使用
總結
以上是生活随笔為你收集整理的实现一个通用的中英文排序工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android中的资源复用小技巧
- 下一篇: 如何向前一个Fragment回传信息?