fix equlas

This commit is contained in:
Looly 2019-12-30 07:15:07 +08:00
parent d7316b3f90
commit 5e7b9012ec
17 changed files with 441 additions and 382 deletions

View File

@ -10,6 +10,8 @@
* 【core 】 增加Convert.toPrimitiveByteArray方法Convert支持对象序列化和反序列化
* 【core 】 DateUtil增加isExpired(Date startDate, Date endDate, Date checkDate)issue#687@Github
* 【core 】 增加Alias注解
* 【core 】 修正NumberChineseFormatter和NumberWordFormatter类名拼写错误
* 【all 】 修正equals避免可能存在的空指针问题pr#692@Github
### Bug修复

View File

@ -922,7 +922,7 @@ public class Convert {
* @since 3.0.9
*/
public static String numberToWord(Number number) {
return NumberWordFormater.format(number);
return NumberWordFormatter.format(number);
}
/**
@ -934,7 +934,7 @@ public class Convert {
* @since 3.2.3
*/
public static String numberToChinese(double number, boolean isUseTraditonal) {
return NumberChineseFormater.format(number, isUseTraditonal);
return NumberChineseFormatter.format(number, isUseTraditonal);
}
/**
@ -948,7 +948,7 @@ public class Convert {
if(null == n) {
return "";
}
return NumberChineseFormater.format(n.doubleValue(), true, true);
return NumberChineseFormatter.format(n.doubleValue(), true, true);
}
// -------------------------------------------------------------------------- 数字转换

View File

@ -1,7 +1,5 @@
package cn.hutool.core.convert;
import cn.hutool.core.util.StrUtil;
/**
* 数字转中文类<br>
* 包括
@ -11,162 +9,9 @@ import cn.hutool.core.util.StrUtil;
* 3. 转金额形式比如壹佰贰拾壹整
* </pre>
*
* @author fanqun,looly
* @author fanqun, looly
* @deprecated 请使用 {@link NumberChineseFormatter}
**/
public class NumberChineseFormater {
/** 简体中文形式 **/
private static final String[] simpleDigits = { "", "", "", "", "", "", "", "", "", "" };
/** 繁体中文形式 **/
private static final String[] traditionalDigits = { "", "", "", "", "", "", "", "", "", "" };
/** 简体中文单位 **/
private static final String[] simpleUnits = { "", "", "", "" };
/** 繁体中文单位 **/
private static final String[] traditionalUnits = { "", "", "", "" };
/**
* 阿拉伯数字转换成中文,小数点后四舍五入保留两位. 使用于整数小数的转换.
*
* @param amount 数字
* @param isUseTraditional 是否使用繁体
* @return 中文
*/
public static String format(double amount, boolean isUseTraditional) {
return format(amount, isUseTraditional, false);
}
/**
* 阿拉伯数字转换成中文,小数点后四舍五入保留两位. 使用于整数小数的转换.
*
* @param amount 数字
* @param isUseTraditional 是否使用繁体
* @param isMoneyMode 是否为金额模式
* @return 中文
*/
public static String format(double amount, boolean isUseTraditional, boolean isMoneyMode) {
final String[] numArray = isUseTraditional ? traditionalDigits : simpleDigits;
if (amount > 99999999999999.99 || amount < -99999999999999.99) {
throw new IllegalArgumentException("Number support only: (-99999999999999.99 99999999999999.99)");
}
boolean negative = false;
if (amount < 0) {
negative = true;
amount = - amount;
}
long temp = Math.round(amount * 100);
int numFen = (int) (temp % 10);
temp = temp / 10;
int numJiao = (int) (temp % 10);
temp = temp / 10;
//将数字以万为单位分为多份
int[] parts = new int[20];
int numParts = 0;
for (int i = 0; temp != 0; i++) {
int part = (int) (temp % 10000);
parts[i] = part;
numParts++;
temp = temp / 10000;
}
boolean beforeWanIsZero = true; // 标志下面一级是不是 0
String chineseStr = StrUtil.EMPTY;
for (int i = 0; i < numParts; i++) {
String partChinese = toChinese(parts[i], isUseTraditional);
if (i % 2 == 0) {
beforeWanIsZero = StrUtil.isEmpty(partChinese);
}
if (i != 0) {
if (i % 2 == 0) {
chineseStr = "亿" + chineseStr;
} else {
if ("".equals(partChinese) && false == beforeWanIsZero) {
// 如果对应的 part 0下面一级不为 0则不加而加
chineseStr = "" + chineseStr;
} else {
if (parts[i - 1] < 1000 && parts[i - 1] > 0) {
// 如果""的部分不为 0, ""前面的部分小于 1000 大于 0 则万后面应该跟
chineseStr = "" + chineseStr;
}
chineseStr = "" + chineseStr;
}
}
}
chineseStr = partChinese + chineseStr;
}
// 整数部分为 0, 则表达为""
if (StrUtil.EMPTY.equals(chineseStr)) {
chineseStr = numArray[0];
}
//负数
if (negative) { // 整数部分不为 0
chineseStr = "" + chineseStr;
}
// 小数部分
if (numFen != 0 || numJiao != 0) {
if (numFen == 0) {
chineseStr += (isMoneyMode ? "" : "") + numArray[numJiao] + (isMoneyMode ? "" : "");
} else { // 数不为 0
if (numJiao == 0) {
chineseStr += (isMoneyMode ? "元零" : "点零") + numArray[numFen] + (isMoneyMode ? "" : "");
} else {
chineseStr += (isMoneyMode ? "" : "") + numArray[numJiao] + (isMoneyMode ? "" : "") + numArray[numFen] + (isMoneyMode ? "" : "");
}
}
}else if(isMoneyMode) {
//无小数部分的金额结尾
chineseStr += "元整";
}
return chineseStr;
}
/**
* 把一个 0~9999 之间的整数转换为汉字的字符串如果是 0 则返回 ""
*
* @param amountPart 数字部分
* @param isUseTraditional 是否使用繁体单位
* @return 转换后的汉字
*/
private static String toChinese(int amountPart, boolean isUseTraditional) {
// if (amountPart < 0 || amountPart > 10000) {
// throw new IllegalArgumentException("Number must 0 < num < 10000");
// }
String[] numArray = isUseTraditional ? traditionalDigits : simpleDigits;
String[] units = isUseTraditional ? traditionalUnits : simpleUnits;
int temp = amountPart;
String chineseStr = "";
boolean lastIsZero = true; // 在从低位往高位循环时记录上一位数字是不是 0
for (int i = 0; temp > 0; i++) {
if (temp == 0) {
// 高位已无数据
break;
}
int digit = temp % 10;
if (digit == 0) { // 取到的数字为 0
if (false == lastIsZero) {
// 前一个数字不是 0则在当前汉字串前加;
chineseStr = "" + chineseStr;
}
lastIsZero = true;
} else { // 取到的数字不是 0
chineseStr = numArray[digit] + units[i] + chineseStr;
lastIsZero = false;
}
temp = temp / 10;
}
return chineseStr;
}
@Deprecated
public class NumberChineseFormater extends NumberChineseFormatter{
}

View File

@ -0,0 +1,176 @@
package cn.hutool.core.convert;
import cn.hutool.core.util.StrUtil;
/**
* 数字转中文类<br>
* 包括
* <pre>
* 1. 数字转中文大写形式比如一百二十一
* 2. 数字转金额用的大写形式比如壹佰贰拾壹
* 3. 转金额形式比如壹佰贰拾壹整
* </pre>
*
* @author fanqun, looly
**/
public class NumberChineseFormatter {
/**
* 简体中文形式
**/
private static final String[] simpleDigits = {"", "", "", "", "", "", "", "", "", ""};
/**
* 繁体中文形式
**/
private static final String[] traditionalDigits = {"", "", "", "", "", "", "", "", "", ""};
/**
* 简体中文单位
**/
private static final String[] simpleUnits = {"", "", "", ""};
/**
* 繁体中文单位
**/
private static final String[] traditionalUnits = {"", "", "", ""};
/**
* 阿拉伯数字转换成中文,小数点后四舍五入保留两位. 使用于整数小数的转换.
*
* @param amount 数字
* @param isUseTraditional 是否使用繁体
* @return 中文
*/
public static String format(double amount, boolean isUseTraditional) {
return format(amount, isUseTraditional, false);
}
/**
* 阿拉伯数字转换成中文,小数点后四舍五入保留两位. 使用于整数小数的转换.
*
* @param amount 数字
* @param isUseTraditional 是否使用繁体
* @param isMoneyMode 是否为金额模式
* @return 中文
*/
public static String format(double amount, boolean isUseTraditional, boolean isMoneyMode) {
final String[] numArray = isUseTraditional ? traditionalDigits : simpleDigits;
if (amount > 99999999999999.99 || amount < -99999999999999.99) {
throw new IllegalArgumentException("Number support only: (-99999999999999.99 99999999999999.99)");
}
boolean negative = false;
if (amount < 0) {
negative = true;
amount = -amount;
}
long temp = Math.round(amount * 100);
int numFen = (int) (temp % 10);
temp = temp / 10;
int numJiao = (int) (temp % 10);
temp = temp / 10;
//将数字以万为单位分为多份
int[] parts = new int[20];
int numParts = 0;
for (int i = 0; temp != 0; i++) {
int part = (int) (temp % 10000);
parts[i] = part;
numParts++;
temp = temp / 10000;
}
boolean beforeWanIsZero = true; // 标志下面一级是不是 0
StringBuilder chineseStr = new StringBuilder();
for (int i = 0; i < numParts; i++) {
String partChinese = toChinese(parts[i], isUseTraditional);
if (i % 2 == 0) {
beforeWanIsZero = StrUtil.isEmpty(partChinese);
}
if (i != 0) {
if (i % 2 == 0) {
chineseStr.insert(0, "亿");
} else {
if ("".equals(partChinese) && false == beforeWanIsZero) {
// 如果对应的 part 0下面一级不为 0则不加而加
chineseStr.insert(0, "");
} else {
if (parts[i - 1] < 1000 && parts[i - 1] > 0) {
// 如果""的部分不为 0, ""前面的部分小于 1000 大于 0 则万后面应该跟
chineseStr.insert(0, "");
}
chineseStr.insert(0, "");
}
}
}
chineseStr.insert(0, partChinese);
}
// 整数部分为 0, 则表达为""
if (StrUtil.EMPTY.equals(chineseStr.toString())) {
chineseStr = new StringBuilder(numArray[0]);
}
//负数
if (negative) { // 整数部分不为 0
chineseStr.insert(0, "");
}
// 小数部分
if (numFen != 0 || numJiao != 0) {
if (numFen == 0) {
chineseStr.append(isMoneyMode ? "" : "").append(numArray[numJiao]).append(isMoneyMode ? "" : "");
} else { // 数不为 0
if (numJiao == 0) {
chineseStr.append(isMoneyMode ? "元零" : "点零").append(numArray[numFen]).append(isMoneyMode ? "" : "");
} else {
chineseStr.append(isMoneyMode ? "" : "").append(numArray[numJiao]).append(isMoneyMode ? "" : "").append(numArray[numFen]).append(isMoneyMode ? "" : "");
}
}
} else if (isMoneyMode) {
//无小数部分的金额结尾
chineseStr.append("元整");
}
return chineseStr.toString();
}
/**
* 把一个 0~9999 之间的整数转换为汉字的字符串如果是 0 则返回 ""
*
* @param amountPart 数字部分
* @param isUseTraditional 是否使用繁体单位
* @return 转换后的汉字
*/
private static String toChinese(int amountPart, boolean isUseTraditional) {
// if (amountPart < 0 || amountPart > 10000) {
// throw new IllegalArgumentException("Number must 0 < num < 10000");
// }
String[] numArray = isUseTraditional ? traditionalDigits : simpleDigits;
String[] units = isUseTraditional ? traditionalUnits : simpleUnits;
int temp = amountPart;
StringBuilder chineseStr = new StringBuilder();
boolean lastIsZero = true; // 在从低位往高位循环时记录上一位数字是不是 0
for (int i = 0; temp > 0; i++) {
int digit = temp % 10;
if (digit == 0) { // 取到的数字为 0
if (false == lastIsZero) {
// 前一个数字不是 0则在当前汉字串前加;
chineseStr.insert(0, "");
}
lastIsZero = true;
} else { // 取到的数字不是 0
chineseStr.insert(0, numArray[digit] + units[i]);
lastIsZero = false;
}
temp = temp / 10;
}
return chineseStr.toString();
}
}

View File

@ -1,146 +1,14 @@
package cn.hutool.core.convert;
import cn.hutool.core.util.StrUtil;
import java.util.Objects;
/**
* 将浮点数类型的number转换成英语的表达方式 <br>
* 参考博客http://blog.csdn.net/eric_sunah/article/details/8713226
*
* @author Looly
* @since 3.0.9
* @see <a href=
* "http://blog.csdn.net/eric_sunah/article/details/8713226">http://blog.csdn.net/eric_sunah/article/details/8713226</a>
* @deprecated 请使用 {@link NumberWordFormatter}
*/
public class NumberWordFormater {
@Deprecated
public class NumberWordFormater extends NumberWordFormatter{
private static final String[] NUMBER = new String[] { "", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
"EIGHT", "NINE" };
private static final String[] NUMBER_TEEN = new String[] { "TEN", "ELEVEN", "TWELEVE", "THIRTEEN", "FOURTEEN",
"FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN" };
private static final String[] NUMBER_TEN = new String[] { "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY",
"SEVENTY", "EIGHTY", "NINETY" };
private static final String[] NUMBER_MORE = new String[] { "", "THOUSAND", "MILLION", "BILLION" };
/**
* 将阿拉伯数字转为英文表达式
*
* @param x
* 阿拉伯数字可以为{@link Number}对象也可以是普通对象最后会使用字符串方式处理
* @return 英文表达式
*/
public static String format(Object x) {
if (x != null) {
return format(x.toString());
} else {
return "";
}
}
/**
* 将阿拉伯数字转为英文表达式
*
* @param x
* 阿拉伯数字字符串
* @return 英文表达式
*/
private static String format(String x) {
int z = x.indexOf("."); // 取小数点位置
String lstr, rstr = "";
if (z > -1) { // 看是否有小数如果有则分别取左边和右边
lstr = x.substring(0, z);
rstr = x.substring(z + 1);
} else {
// 否则就是全部
lstr = x;
}
String lstrrev = StrUtil.reverse(lstr); // 对左边的字串取反
String[] a = new String[5]; // 定义5个字串变量来存放解析出来的叁位一组的字串
switch (lstrrev.length() % 3) {
case 1:
lstrrev += "00";
break;
case 2:
lstrrev += "0";
break;
}
StringBuilder lm = new StringBuilder(); // 用来存放转换後的整数部分
for (int i = 0; i < lstrrev.length() / 3; i++) {
a[i] = StrUtil.reverse(lstrrev.substring(3 * i, 3 * i + 3)); // 截取第一个叁位
if (!Objects.equals(a[i],"000")) { // 用来避免这种情况1000000 = one million
// thousand only
if (i != 0) {
lm.insert(0, transThree(a[i]) + " " + parseMore(i) + " "); // :
// thousandmillionbillion
} else {
// 防止i=0时 在多加两个空格.
lm = new StringBuilder(transThree(a[i]));
}
} else {
lm.append(transThree(a[i]));
}
}
String xs = ""; // 用来存放转换後小数部分
if (z > -1) {
xs = "AND CENTS " + transTwo(rstr) + " "; // 小数部分存在时转换小数
}
return lm.toString().trim() + " " + xs + "ONLY";
}
private static String parseFirst(String s) {
return NUMBER[Integer.parseInt(s.substring(s.length() - 1))];
}
private static String parseTeen(String s) {
return NUMBER_TEEN[Integer.parseInt(s) - 10];
}
private static String parseTen(String s) {
return NUMBER_TEN[Integer.parseInt(s.substring(0, 1)) - 1];
}
private static String parseMore(int i) {
return NUMBER_MORE[i];
}
// 两位
private static String transTwo(String s) {
String value;
// 判断位数
if (s.length() > 2) {
s = s.substring(0, 2);
} else if (s.length() < 2) {
s = "0" + s;
}
if (s.startsWith("0")) {// 07 - seven 是否小於10
value = parseFirst(s);
} else if (s.startsWith("1")) {// 17 seventeen 是否在10和20之间
value = parseTeen(s);
} else if (s.endsWith("0")) {// 是否在10与100之间的能被10整除的数
value = parseTen(s);
} else {
value = parseTen(s) + " " + parseFirst(s);
}
return value;
}
// 制作叁位的数
// s.length = 3
private static String transThree(String s) {
String value;
if (s.startsWith("0")) {// 是否小於100
value = transTwo(s.substring(1));
} else if (Objects.equals(s.substring(1),"00")) {// 是否被100整除
value = parseFirst(s.substring(0, 1)) + " HUNDRED";
} else {
value = parseFirst(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1));
}
return value;
}
}

View File

@ -0,0 +1,140 @@
package cn.hutool.core.convert;
import cn.hutool.core.util.StrUtil;
/**
* 将浮点数类型的number转换成英语的表达方式 <br>
* 参考博客http://blog.csdn.net/eric_sunah/article/details/8713226
*
* @author Looly
* @since 3.0.9
*/
public class NumberWordFormatter {
private static final String[] NUMBER = new String[]{"", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
"EIGHT", "NINE"};
private static final String[] NUMBER_TEEN = new String[]{"TEN", "ELEVEN", "TWELEVE", "THIRTEEN", "FOURTEEN",
"FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"};
private static final String[] NUMBER_TEN = new String[]{"TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY",
"SEVENTY", "EIGHTY", "NINETY"};
private static final String[] NUMBER_MORE = new String[]{"", "THOUSAND", "MILLION", "BILLION"};
/**
* 将阿拉伯数字转为英文表达式
*
* @param x 阿拉伯数字可以为{@link Number}对象也可以是普通对象最后会使用字符串方式处理
* @return 英文表达式
*/
public static String format(Object x) {
if (x != null) {
return format(x.toString());
} else {
return "";
}
}
/**
* 将阿拉伯数字转为英文表达式
*
* @param x 阿拉伯数字字符串
* @return 英文表达式
*/
private static String format(String x) {
int z = x.indexOf("."); // 取小数点位置
String lstr, rstr = "";
if (z > -1) { // 看是否有小数如果有则分别取左边和右边
lstr = x.substring(0, z);
rstr = x.substring(z + 1);
} else {
// 否则就是全部
lstr = x;
}
String lstrrev = StrUtil.reverse(lstr); // 对左边的字串取反
String[] a = new String[5]; // 定义5个字串变量来存放解析出来的叁位一组的字串
switch (lstrrev.length() % 3) {
case 1:
lstrrev += "00";
break;
case 2:
lstrrev += "0";
break;
}
StringBuilder lm = new StringBuilder(); // 用来存放转换后的整数部分
for (int i = 0; i < lstrrev.length() / 3; i++) {
a[i] = StrUtil.reverse(lstrrev.substring(3 * i, 3 * i + 3)); // 截取第一个三位
if (false == "000".equals(a[i])) { // 用来避免这种情况1000000 = one million
// thousand only
if (i != 0) {
lm.insert(0, transThree(a[i]) + " " + parseMore(i) + " "); // :
// thousandmillionbillion
} else {
// 防止i=0时 在多加两个空格.
lm = new StringBuilder(transThree(a[i]));
}
} else {
lm.append(transThree(a[i]));
}
}
String xs = ""; // 用来存放转换后小数部分
if (z > -1) {
xs = "AND CENTS " + transTwo(rstr) + " "; // 小数部分存在时转换小数
}
return lm.toString().trim() + " " + xs + "ONLY";
}
private static String parseFirst(String s) {
return NUMBER[Integer.parseInt(s.substring(s.length() - 1))];
}
private static String parseTeen(String s) {
return NUMBER_TEEN[Integer.parseInt(s) - 10];
}
private static String parseTen(String s) {
return NUMBER_TEN[Integer.parseInt(s.substring(0, 1)) - 1];
}
private static String parseMore(int i) {
return NUMBER_MORE[i];
}
// 两位
private static String transTwo(String s) {
String value;
// 判断位数
if (s.length() > 2) {
s = s.substring(0, 2);
} else if (s.length() < 2) {
s = "0" + s;
}
if (s.startsWith("0")) {// 07 - seven 是否小於10
value = parseFirst(s);
} else if (s.startsWith("1")) {// 17 seventeen 是否在10和20之间
value = parseTeen(s);
} else if (s.endsWith("0")) {// 是否在10与100之间的能被10整除的数
value = parseTen(s);
} else {
value = parseTen(s) + " " + parseFirst(s);
}
return value;
}
// 制作叁位的数
// s.length = 3
private static String transThree(String s) {
String value;
if (s.startsWith("0")) {// 是否小於100
value = transTwo(s.substring(1));
} else if ("00".equals(s.substring(1))) {// 是否被100整除
value = parseFirst(s.substring(0, 1)) + " HUNDRED";
} else {
value = parseFirst(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1));
}
return value;
}
}

View File

@ -5,7 +5,19 @@ import java.io.ObjectInputStream;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
@ -15,15 +27,17 @@ import java.util.regex.Pattern;
* {@link java.text.SimpleDateFormat} 的线程安全版本用于解析日期字符串并转换为 {@link Date} 对象<br>
* Thanks to Apache Commons Lang 3.5
*
* @since 2.16.2
* @see FastDatePrinter
* @since 2.16.2
*/
class FastDateParser extends AbstractDateBasic implements DateParser {
private static final long serialVersionUID = -3199383897950947498L;
static final Locale JAPANESE_IMPERIAL = new Locale("ja", "JP", "JP");
/** 世纪2000年前为19 之后为20 */
/**
* 世纪2000年前为19 之后为20
*/
private final int century;
private final int startYear;
@ -33,18 +47,18 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
// comparator used to sort regex alternatives
// alternatives should be ordered longer first, and shorter last. ('february' before 'feb')
// all entries must be lowercase by locale.
private static final Comparator<String> LONGER_FIRST_LOWERCASE = (left, right) -> right.compareTo(left);
private static final Comparator<String> LONGER_FIRST_LOWERCASE = Comparator.reverseOrder();
/**
* <p>
* Constructs a new FastDateParser.
* </p>
*
* <p>
* Use {@link FastDateFormat#getInstance(String, TimeZone, Locale)} or another variation of the factory methods of {@link FastDateFormat} to get a cached FastDateParser instance.
*
* @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern
* @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern
* @param timeZone non-null time zone to use
* @param locale non-null locale
* @param locale non-null locale
*/
protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale) {
this(pattern, timeZone, locale, null);
@ -55,9 +69,9 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
* Constructs a new FastDateParser.
* </p>
*
* @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern
* @param timeZone non-null time zone to use
* @param locale non-null locale
* @param pattern non-null {@link java.text.SimpleDateFormat} compatible pattern
* @param timeZone non-null time zone to use
* @param locale non-null locale
* @param centuryStart The start of the century for 2 digit year parsing
*/
protected FastDateParser(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) {
@ -90,7 +104,7 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
patterns = new ArrayList<>();
final StrategyParser fm = new StrategyParser(definingCalendar);
for (;;) {
for (; ; ) {
final StrategyAndWidth field = fm.getNextStrategy();
if (field == null) {
break;
@ -190,11 +204,12 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
// Serializing
// -----------------------------------------------------------------------
/**
* Create the object after serialization. This implementation reinitializes the transient properties.
*
* @param in ObjectInputStream from which the object is being deserialized.
* @throws IOException if there is an IO issue.
* @throws IOException if there is an IO issue.
* @throws ClassNotFoundException if a class cannot be found.
*/
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
@ -280,10 +295,10 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
/**
* Get the short and long values displayed for a field
*
* @param cal The calendar to obtain the short and long values
* @param cal The calendar to obtain the short and long values
* @param locale The locale of display names
* @param field The field of interest
* @param regex The regular expression to build
* @param field The field of interest
* @param regex The regular expression to build
* @return The map of string display names to field values
*/
private static Map<String, Integer> appendDisplayNames(final Calendar cal, final Locale locale, final int field, final StringBuilder regex) {
@ -373,8 +388,8 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
/**
* Obtain a Strategy given a field from a SimpleDateFormat pattern
*
* @param f 格式
* @param width 长度
* @param f 格式
* @param width 长度
* @param definingCalendar The calendar to obtain the short and long values
* @return The Strategy that will handle parsing for the field
*/
@ -452,7 +467,7 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
/**
* Construct a Strategy that parses a Text field
*
* @param field The Calendar field
* @param field The Calendar field
* @param definingCalendar The calendar to obtain the short and long values
* @return a TextStrategy for the field and Locale
*/
@ -522,9 +537,9 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
/**
* Construct a Strategy that parses a Text field
*
* @param field The Calendar field
* @param field The Calendar field
* @param definingCalendar The Calendar to use
* @param locale The Locale to use
* @param locale The Locale to use
*/
CaseInsensitiveTextStrategy(final int field, final Calendar definingCalendar, final Locale locale) {
this.field = field;
@ -538,13 +553,10 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
createPattern(regex);
}
/**
* {@inheritDoc}
*/
@Override
void setCalendar(final FastDateParser parser, final Calendar cal, final String value) {
final Integer iVal = lKeyValues.get(value.toLowerCase(locale));
cal.set(field, iVal.intValue());
cal.set(field, iVal);
}
}
@ -624,7 +636,7 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
}
private static final Strategy ABBREVIATED_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR){
private static final Strategy ABBREVIATED_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR) {
/**
* {@inheritDoc}
*/
@ -688,7 +700,7 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
for (int i = 1; i < zoneNames.length; ++i) {
switch (i) {
case 3: // offset 3 is long daylight savings (or summertime) name
// offset 4 is the short summertime name
// offset 4 is the short summertime name
tzInfo = new TzInfo(tz, true);
break;
case 5: // offset 5 starts additional names, probably standard time
@ -750,7 +762,7 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
*/
@Override
void setCalendar(final FastDateParser parser, final Calendar cal, final String value) {
if (Objects.equals(value,"Z")) {
if (Objects.equals(value, "Z")) {
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
} else {
cal.setTimeZone(TimeZone.getTimeZone("GMT" + value));
@ -781,7 +793,7 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
}
}
private static final Strategy NUMBER_MONTH_STRATEGY = new NumberStrategy(Calendar.MONTH){
private static final Strategy NUMBER_MONTH_STRATEGY = new NumberStrategy(Calendar.MONTH) {
@Override
int modify(final FastDateParser parser, final int iValue) {
return iValue - 1;
@ -792,7 +804,7 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
private static final Strategy WEEK_OF_MONTH_STRATEGY = new NumberStrategy(Calendar.WEEK_OF_MONTH);
private static final Strategy DAY_OF_YEAR_STRATEGY = new NumberStrategy(Calendar.DAY_OF_YEAR);
private static final Strategy DAY_OF_MONTH_STRATEGY = new NumberStrategy(Calendar.DAY_OF_MONTH);
private static final Strategy DAY_OF_WEEK_STRATEGY = new NumberStrategy(Calendar.DAY_OF_WEEK){
private static final Strategy DAY_OF_WEEK_STRATEGY = new NumberStrategy(Calendar.DAY_OF_WEEK) {
@Override
int modify(final FastDateParser parser, final int iValue) {
return iValue != 7 ? iValue + 1 : Calendar.SUNDAY;
@ -800,13 +812,13 @@ class FastDateParser extends AbstractDateBasic implements DateParser {
};
private static final Strategy DAY_OF_WEEK_IN_MONTH_STRATEGY = new NumberStrategy(Calendar.DAY_OF_WEEK_IN_MONTH);
private static final Strategy HOUR_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY);
private static final Strategy HOUR24_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY){
private static final Strategy HOUR24_OF_DAY_STRATEGY = new NumberStrategy(Calendar.HOUR_OF_DAY) {
@Override
int modify(final FastDateParser parser, final int iValue) {
return iValue == 24 ? 0 : iValue;
}
};
private static final Strategy HOUR12_STRATEGY = new NumberStrategy(Calendar.HOUR){
private static final Strategy HOUR12_STRATEGY = new NumberStrategy(Calendar.HOUR) {
@Override
int modify(final FastDateParser parser, final int iValue) {
return iValue == 12 ? 0 : iValue;

View File

@ -174,8 +174,8 @@ public class IdcardUtil {
case 15:// 15位身份证
return isValidCard15(idCard);
case 10: {// 10位身份证港澳台地区
String[] cardval = isValidCard10(idCard);
return null != cardval && Objects.equals(cardval[2],"true");
String[] cardVal = isValidCard10(idCard);
return null != cardVal && "true".equals(cardVal[2]);
}
default:
return false;
@ -279,10 +279,10 @@ public class IdcardUtil {
}
if (idCard.matches("^[a-zA-Z][0-9]{9}$")) { // 台湾
info[0] = "台湾";
String char2 = idCard.substring(1, 2);
if (Objects.equals(char2,"1")) {
char char2 = idCard.charAt(1);
if ('1' == char2) {
info[1] = "M";
} else if (Objects.equals(char2,"2")) {
} else if ('2' == char2) {
info[1] = "F";
} else {
info[1] = "N";

View File

@ -48,7 +48,7 @@ public class ReferenceUtil {
case WEAK:
return new WeakReference<>(referent);
case PHANTOM:
return new PhantomReference<T>(referent, queue);
return new PhantomReference<>(referent, queue);
default:
return null;
}

View File

@ -12,7 +12,12 @@ import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 反射工具类
@ -138,7 +143,7 @@ public class ReflectUtil {
* @return 字段名和字段对应的Map
* @since 5.0.7
*/
public static Map<String, Field> getFieldMap(Class<?> beanClass){
public static Map<String, Field> getFieldMap(Class<?> beanClass) {
final Field[] fields = getFields(beanClass);
final HashMap<String, Field> map = MapUtil.newHashMap(fields.length);
for (Field field : fields) {
@ -203,7 +208,7 @@ public class ReflectUtil {
if (null == obj || StrUtil.isBlank(fieldName)) {
return null;
}
return getFieldValue(obj, getField(obj instanceof Class ? (Class<?>)obj : obj.getClass(), fieldName));
return getFieldValue(obj, getField(obj instanceof Class ? (Class<?>) obj : obj.getClass(), fieldName));
}
/**
@ -230,7 +235,7 @@ public class ReflectUtil {
if (null == field) {
return null;
}
if(obj instanceof Class){
if (obj instanceof Class) {
// 静态字段获取时对象为null
obj = null;
}
@ -254,7 +259,7 @@ public class ReflectUtil {
*/
public static Object[] getFieldsValue(Object obj) {
if (null != obj) {
final Field[] fields = getFields(obj instanceof Class ? (Class<?>)obj : obj.getClass());
final Field[] fields = getFields(obj instanceof Class ? (Class<?>) obj : obj.getClass());
if (null != fields) {
final Object[] values = new Object[fields.length];
for (int i = 0; i < fields.length; i++) {
@ -647,7 +652,7 @@ public class ReflectUtil {
* @return 是否为equals方法
*/
public static boolean isEqualsMethod(Method method) {
if (method == null || false == Objects.equals(method.getName(),"equals")) {
if (method == null || false == "equals".equals(method.getName())) {
return false;
}
final Class<?>[] paramTypes = method.getParameterTypes();
@ -661,7 +666,9 @@ public class ReflectUtil {
* @return 是否为hashCode方法
*/
public static boolean isHashCodeMethod(Method method) {
return (method != null && Objects.equals(method.getName(),"hashCode") && method.getParameterTypes().length == 0);
return method != null//
&& "hashCode".equals(method.getName())//
&& isEmptyParam(method);
}
/**
@ -671,7 +678,20 @@ public class ReflectUtil {
* @return 是否为toString方法
*/
public static boolean isToStringMethod(Method method) {
return (method != null && Objects.equals(method.getName(),"toString") && method.getParameterTypes().length == 0);
return method != null//
&& "toString".equals(method.getName())//
&& isEmptyParam(method);
}
/**
* 是否为无参数方法
*
* @param method 方法
* @return 是否为无参数方法
* @since 5.1.1
*/
public static boolean isEmptyParam(Method method) {
return method.getParameterTypes().length == 0;
}
// --------------------------------------------------------------------------------------------------------- newInstance

View File

@ -2,8 +2,6 @@ package cn.hutool.cron.pattern.parser;
import cn.hutool.cron.CronException;
import java.util.Objects;
/**
* 每月的几号值处理<br>
* 每月最多31天32和L都表示最后一天
@ -19,7 +17,7 @@ public class DayOfMonthValueParser extends SimpleValueParser {
@Override
public int parse(String value) throws CronException {
if ("L".equalsIgnoreCase(value) || Objects.equals("32",value)) {// 每月最后一天
if ("L".equalsIgnoreCase(value) || "32".equals(value)) {// 每月最后一天
return 32;
} else {
return super.parse(value);

View File

@ -9,7 +9,7 @@ import cn.hutool.cron.CronException;
* @author Looly
*
*/
public class DayOfWeekValueParser extends SimpleValueParser {
public class DayOfWeekValueParser extends SimpleValueParser {
/** Weeks aliases. */
private static final String[] ALIASES = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" };

View File

@ -176,6 +176,7 @@ public class Db extends AbstractDb {
final int level = transactionLevel.getLevel();
if (conn.getTransactionIsolation() < level) {
// 用户定义的事务级别如果比默认级别更严格则按照严格的级别进行
//noinspection MagicConstant
conn.setTransactionIsolation(level);
}
}

View File

@ -126,7 +126,7 @@ public class SqlFormatter {
values();
} else if ("on".equals(this.lcToken)) {
on();
} else if ((this.afterBetween) && (Objects.equals(this.lcToken,"and"))) {
} else if ((this.afterBetween) && ("and".equals(this.lcToken))) {
misc();
this.afterBetween = false;
} else if (LOGICAL.contains(this.lcToken)) {
@ -213,8 +213,8 @@ public class SqlFormatter {
out();
this.indent += 1;
newline();
this.parenCounts.addLast(new Integer(this.parensSinceSelect));
this.afterByOrFromOrSelects.addLast(Boolean.valueOf(this.afterByOrSetOrFromOrSelect));
this.parenCounts.addLast(this.parensSinceSelect);
this.afterByOrFromOrSelects.addLast(this.afterByOrSetOrFromOrSelect);
this.parensSinceSelect = 0;
this.afterByOrSetOrFromOrSelect = true;
}
@ -268,8 +268,8 @@ public class SqlFormatter {
this.parensSinceSelect -= 1;
if (this.parensSinceSelect < 0) {
this.indent -= 1;
this.parensSinceSelect = ((Integer) this.parenCounts.removeLast()).intValue();
this.afterByOrSetOrFromOrSelect = ((Boolean) this.afterByOrFromOrSelects.removeLast()).booleanValue();
this.parensSinceSelect = this.parenCounts.removeLast();
this.afterByOrSetOrFromOrSelect = this.afterByOrFromOrSelects.removeLast();
}
if (this.inFunction > 0) {
this.inFunction -= 1;

View File

@ -1,5 +1,14 @@
package cn.hutool.extra.ftp;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@ -7,17 +16,6 @@ import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
/**
* FTP客户端封装<br>
@ -340,7 +338,7 @@ public class Ftp extends AbstractFtp {
childPath = StrUtil.format("{}/{}", dirPath, name);
if (ftpFile.isDirectory()) {
// 上级和本级目录除外
if (false == Objects.equals(name,".") && false == Objects.equals(name,"..")) {
if (false == ".".equals(name) && false == "..".equals(name)) {
delDir(childPath);
}
} else {

View File

@ -15,7 +15,6 @@ import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Vector;
/**
@ -312,7 +311,7 @@ public class Sftp extends AbstractFtp {
String fileName;
for (LsEntry entry : list) {
fileName = entry.getFilename();
if (false == Objects.equals(fileName,".") && false == Objects.equals(fileName,"..")) {
if (false == ".".equals(fileName) && false == "..".equals(fileName)) {
if (entry.getAttrs().isDir()) {
delDir(fileName);
} else {

View File

@ -381,7 +381,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
return !httpVersion.equalsIgnoreCase(HTTP_1_0);
}
return !"close".equalsIgnoreCase(connection);
return false == "close".equalsIgnoreCase(connection);
}
/**