日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实现一个通用的中英文排序工具

發布時間:2024/4/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现一个通用的中英文排序工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

利用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的函數進行排序

其中注意

  • sortByMethodName要保證該類中沒有同名函數,當然也可以加入驗證函數參數簽名來防止同名函數。
  • 如果通過注釋排序,如果類中有多個@SortString注釋,只有第一個有效果。目前這個工具只針對單一維度排序,當然其實完全可以修改成多維度排序,可以增加一個優先級。不過我們需求沒有這么復雜,所以就沒有進行開發。
  • 使用

    總結

    以上是生活随笔為你收集整理的实现一个通用的中英文排序工具的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。