近期在作一个阅读app的时候,碰到了要对中文标题还有数字标题排序问题,经过一番搜索与实践,终于达成了目的。
工具类 StringUtils
package cn.wq.elf.utils;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StringUtils {
/**
* 比较文件名是否相等
*
* @param name1
* @param name2
* @return
*/
public static boolean isEquals(String name1, String name2) {
if (ToolEmpty.isNotEmpty(name1) && ToolEmpty.isNotEmpty(name2)) {
return name1.trim().replaceAll("\t", "").equals(name2.trim().replaceAll("\t", ""));
}
return false;
}
/**
* 截取第一处的中文数字字符串
*
* @param str
* @return
*/
private static String getNumberStr(String str) {
StringBuilder stringBuilder = new StringBuilder();
boolean isFirst = true;
String chineseNumStr = "零一二三四五六七八九十百千万亿";
for (int i = 0; i < str.length(); i++) {
String tempStr = str.substring(i, i + 1);
if (chineseNumStr.contains(tempStr)) {
stringBuilder.append(tempStr);
if (isFirst) {
isFirst = false;
}
} else {
if (!isFirst) {
break;
}
}
}
return stringBuilder.toString();
}
/**
* 将中文数字转换为 阿拉伯数字
*
* @param chineseNumber 中文数字字符串
* @return 转换后的阿拉伯数字
* @author Tuzi294
*/
private static long chineseNumber2Int(String chineseNumber) {
String aval = "零一二三四五六七八九";
String bval = "十百千万亿";
int[] bnum = {10, 100, 1000, 10000, 100000000};
long num = 0;
char[] arr = chineseNumber.toCharArray();
int len = arr.length;
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < len; i++) {
char s = arr[i];
//跳过零
if (s == '零') continue;
//用下标找到对应数字
int index = bval.indexOf(s);
//如果不在bval中,即当前字符为数字,直接入栈
if (index == -1) {
stack.push(aval.indexOf(s));
} else { //当前字符为单位。
int tempsum = 0;
int val = bnum[index];
//如果栈为空则直接入栈
if (stack.isEmpty()) {
stack.push(val);
continue;
}
//如果栈中有比val小的元素则出栈,累加,乘N,再入栈
while (!stack.isEmpty() && stack.peek() < val) {
tempsum += stack.pop();
}
//判断是否经过乘法处理
if (tempsum == 0) {
stack.push(val);
} else {
stack.push(tempsum * val);
}
}
}
//计算最终的和
while (!stack.isEmpty()) {
num += stack.pop();
}
return num;
}
/**
* 将汉字转数字
*
* @param strTitle
* @return
*/
public static long getLongTitle(String strTitle) {
String pattern = "\\d+";
Pattern p = Pattern.compile(pattern);
Matcher matcher = p.matcher(strTitle);
long num = 0;
String numStr = "";
if (matcher.find()) {
numStr = matcher.group();
if (numStr.startsWith("0")) {
numStr = splitZero(numStr);
}
num = Long.parseLong(numStr);
} else {
numStr = getNumberStr(strTitle);
num = chineseNumber2Int(numStr);
}
return num;
}
/**
* 去除类似第001章前面的0
* @param zeroNum
* @return
*/
private static String splitZero(String zeroNum) {
String pattern = "[1-9]+\\d*";
Pattern p = Pattern.compile(pattern);
Matcher matcher = p.matcher(zeroNum);
String numStr = "";
if (matcher.find()) {
numStr = matcher.group();
}
return numStr;
}
}
方法介绍:getNumberStr()此方法用于把字符中的中文数字检取出来,chineseNumber2Int()用于将中文转为数字。
对外提供的方法是 getLongTitle(String strTitle),这个方法是先判断标题是中文还是数字序号。是数字序号则直接提取数字。中文的话则交由上述二个方法采用。
实体类的使用
package cn.wq.elf.entity;
import android.os.Parcel;
import android.os.Parcelable;
import cn.wq.elf.utils.StringUtils;
public class BaseBookEntity implements Comparable<BaseBookEntity> {
private long numTitle;
public BaseBookEntity() {
}
public long getNumTitle() {
return numTitle;
}
public void setNumTitle(long numTitle) {
this.numTitle = numTitle;
}
@Override
public int compareTo(BaseBookEntity otheBook) {
this.setNumTitle(StringUtils.getLongTitle(this.getBookName()));
otheBook.setNumTitle(StringUtils.getLongTitle(otheBook.getBookName()));
return (int) (this.getNumTitle() - otheBook.getNumTitle());
}
}
对外使用:list.add(obj1),list.add(obj2)……最后调用Collections.sort(list);即可!就是如此简单。