实现一个通用的中英文排序工具
Posted BennuCTech
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现一个通用的中英文排序工具相关的知识,希望对你有一定的参考价值。
前言
利用Collator类可以轻松实现排序,但是我们可能有各种model都需要进行排序,这样就会有一个问题,如果单独为每个model写一段排序代码,代码重复量很大。
所以我打算写一个通用的工具,使用泛型+注解+反射的方式来解决。
注解
首先创建注解类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD, ElementType.METHOD)
@Documented
public @interface SortString
这个注解的作用就是标识哪个字段或函数是用来排序。
工具类
然后是排序工具类,在我这个工具中排序规则是:中文 > 数字 > 英文,这是我们app的需求,大家可以根据自己的需求进行修改。
完整代码如下
public class SimplifiedChineseSorter
private static final String SORTINGREGEX = "[^\\\\pL\\\\pN]+|^(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>()
@Override
public 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>()
@Override
public 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>()
@Override
public 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以上是关于实现一个通用的中英文排序工具的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向Android 逆向通用工具开发 ( Android 平台运行的 cmd 程序类型 | Android 平台运行的 cmd 程序编译选项 | 编译 cmd 可执行程序 )(代码片段