Looly 5 年 前
コミット
48f43dc34a

+ 6 - 2
CHANGELOG.md

@@ -3,10 +3,14 @@
 
 -------------------------------------------------------------------------------------------------------------
 
-# 5.4.7 (2020-10-31)
+# 5.4.8 (2020-11-03)
 
 ### 新特性
+* 【core   】     NumberUtil.parseInt等支持123,2.00这类数字(issue#I23ORQ@Gitee)
+* 【core   】     增加ArrayUtil.isSub、indexOfSub、lastIndexOfSub方法(issue#I23O1K@Gitee)
+
 ### Bug修复
+* 【core   】     修复DateUtil.current使用System.nanoTime的问题(issue#1198@Github)
 
 -------------------------------------------------------------------------------------------------------------
 
@@ -19,7 +23,7 @@
 * 【core   】     CollUtil.map忽略空值改规则为原数组中的元素和处理后的元素都会忽略空值(issue#I22N08@Gitee)
 * 【http   】     增加SoapClient增加addSOAPHeader重载
 * 【http   】     ArrayUtil增加containsAll方法
-* 【http   】     增加CharsetDetector
+* 【core   】     增加CharsetDetector
 * 【cron   】     增加CronTask,监听支持获取id(issue#I23315@Gitee)
 
 ### Bug修复

+ 2 - 3
hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java

@@ -123,11 +123,10 @@ public class DateUtil extends CalendarUtil {
 	/**
 	 * 当前时间的时间戳
 	 *
-	 * @param isNano 是否为高精度时间
 	 * @return 时间
 	 */
-	public static long current(boolean isNano) {
-		return isNano ? System.nanoTime() : System.currentTimeMillis();
+	public static long current() {
+		return System.currentTimeMillis();
 	}
 
 	/**

+ 14 - 5
hutool-core/src/main/java/cn/hutool/core/date/TimeInterval.java

@@ -4,7 +4,7 @@ import java.io.Serializable;
 
 /**
  * 计时器<br>
- * 计算某个过程花费的时间,精确到毫秒
+ * 计算某个过程花费的时间,精确到毫秒或纳秒
  *
  * @author Looly
  */
@@ -34,7 +34,7 @@ public class TimeInterval implements Serializable {
 	 * @return 开始计时并返回当前时间
 	 */
 	public long start() {
-		time = DateUtil.current(isNano);
+		time = getTime(isNano);
 		return time;
 	}
 
@@ -42,7 +42,7 @@ public class TimeInterval implements Serializable {
 	 * @return 重新计时并返回从开始到当前的持续时间
 	 */
 	public long intervalRestart() {
-		long now = DateUtil.current(isNano);
+		long now = getTime(isNano);
 		long d = now - time;
 		time = now;
 		return d;
@@ -55,7 +55,7 @@ public class TimeInterval implements Serializable {
 	 * @since 3.0.1
 	 */
 	public TimeInterval restart() {
-		time = DateUtil.current(isNano);
+		time = getTime(isNano);
 		return this;
 	}
 
@@ -68,7 +68,7 @@ public class TimeInterval implements Serializable {
 	 * @return 从开始到当前的间隔时间(毫秒数)
 	 */
 	public long interval() {
-		return DateUtil.current(isNano) - time;
+		return getTime(isNano) - time;
 	}
 
 	/**
@@ -135,4 +135,13 @@ public class TimeInterval implements Serializable {
 		return intervalMs() / DateUnit.WEEK.getMillis();
 	}
 
+	/**
+	 * 获取时间的毫秒或纳秒数,纳秒非时间戳
+	 *
+	 * @param isNano 是否为高精度时间
+	 * @return 时间
+	 */
+	private static long getTime(boolean isNano) {
+		return isNano ? System.nanoTime() : System.currentTimeMillis();
+	}
 }

+ 82 - 13
hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java

@@ -317,9 +317,9 @@ public class ArrayUtil {
 	/**
 	 * 返回数组中第一个匹配规则的值
 	 *
-	 * @param <T>   数组元素类型
+	 * @param <T>     数组元素类型
 	 * @param matcher 匹配接口,实现此接口自定义匹配规则
-	 * @param array 数组
+	 * @param array   数组
 	 * @return 非空元素,如果不存在非空元素或数组为空,返回{@code null}
 	 * @since 3.0.7
 	 */
@@ -327,7 +327,7 @@ public class ArrayUtil {
 	public static <T> T firstMatch(Matcher<T> matcher, T... array) {
 		if (isNotEmpty(array)) {
 			for (final T val : array) {
-				if(matcher.match(val)){
+				if (matcher.match(val)) {
 					return val;
 				}
 			}
@@ -4308,17 +4308,17 @@ public class ArrayUtil {
 	/**
 	 * 按照指定规则,将一种类型的数组转换为另一种类型
 	 *
-	 * @param array 被转换的数组
+	 * @param array               被转换的数组
 	 * @param targetComponentType 目标的元素类型
-	 * @param func 转换规则函数
-	 * @param <T> 原数组类型
-	 * @param <R> 目标数组类型
+	 * @param func                转换规则函数
+	 * @param <T>                 原数组类型
+	 * @param <R>                 目标数组类型
 	 * @return 转换后的数组
 	 * @since 5.4.2
 	 */
-	public static <T, R> R[] map(T[] array, Class<R> targetComponentType, Function<? super T, ? extends R> func){
+	public static <T, R> R[] map(T[] array, Class<R> targetComponentType, Function<? super T, ? extends R> func) {
 		final R[] result = newArray(targetComponentType, array.length);
-		for(int i=0; i< array.length; i++){
+		for (int i = 0; i < array.length; i++) {
 			result[i] = func.apply(array[i]);
 		}
 		return result;
@@ -4326,16 +4326,17 @@ public class ArrayUtil {
 
 	/**
 	 * 判断两个数组是否相等,判断依据包括数组长度和每个元素都相等。
+	 *
 	 * @param array1 数组1
 	 * @param array2 数组2
 	 * @return 是否相等
 	 * @since 5.4.2
 	 */
-	public static boolean equals(Object array1, Object array2){
-		if(array1 == array2){
+	public static boolean equals(Object array1, Object array2) {
+		if (array1 == array2) {
 			return true;
 		}
-		if(hasNull(array1, array2)){
+		if (hasNull(array1, array2)) {
 			return false;
 		}
 
@@ -4343,7 +4344,7 @@ public class ArrayUtil {
 		Assert.isTrue(isArray(array2), "Second is not a Array !");
 
 		// 数组类型一致性判断
-		if(array1.getClass() != array2.getClass()){
+		if (array1.getClass() != array2.getClass()) {
 			return false;
 		}
 
@@ -4368,4 +4369,72 @@ public class ArrayUtil {
 			return Arrays.deepEquals((Object[]) array1, (Object[]) array2);
 		}
 	}
+
+	/**
+	 * 查找子数组的位置
+	 *
+	 * @param array    数组
+	 * @param subArray 子数组
+	 * @param <T>      数组元素类型
+	 * @return 子数组的开始位置,即子数字第一个元素在数组中的位置
+	 * @since 5.4.8
+	 */
+	public static <T> boolean isSub(T[] array, T[] subArray) {
+		return indexOfSub(array, subArray) > INDEX_NOT_FOUND;
+	}
+
+	/**
+	 * 查找子数组的位置
+	 *
+	 * @param array    数组
+	 * @param subArray 子数组
+	 * @param <T>      数组元素类型
+	 * @return 子数组的开始位置,即子数字第一个元素在数组中的位置
+	 * @since 5.4.8
+	 */
+	public static <T> int indexOfSub(T[] array, T[] subArray) {
+		if (isEmpty(array) || isEmpty(subArray) || subArray.length > array.length) {
+			return INDEX_NOT_FOUND;
+		}
+		int firstIndex = indexOf(array, subArray[0]);
+		if (firstIndex < 0 || firstIndex + subArray.length > array.length) {
+			return INDEX_NOT_FOUND;
+		}
+
+		for (int i = 0; i < subArray.length; i++) {
+			if (false == ObjectUtil.equal(array[i + firstIndex], subArray[i])) {
+				return INDEX_NOT_FOUND;
+			}
+		}
+
+		return firstIndex;
+	}
+
+	/**
+	 * 查找最后一个子数组的开始位置
+	 *
+	 * @param array    数组
+	 * @param subArray 子数组
+	 * @param <T>      数组元素类型
+	 * @return 最后一个子数组的开始位置,即子数字第一个元素在数组中的位置
+	 * @since 5.4.8
+	 */
+	public static <T> int lastIndexOfSub(T[] array, T[] subArray) {
+		if (isEmpty(array) || isEmpty(subArray) || subArray.length > array.length) {
+			return INDEX_NOT_FOUND;
+		}
+
+		int firstIndex = lastIndexOf(array, subArray[0]);
+		if (firstIndex < 0 || firstIndex + subArray.length > array.length) {
+			return INDEX_NOT_FOUND;
+		}
+
+		for (int i = 0; i < subArray.length; i++) {
+			if (false == ObjectUtil.equal(array[i + firstIndex], subArray[i])) {
+				return INDEX_NOT_FOUND;
+			}
+		}
+
+		return firstIndex;
+	}
 }

+ 4 - 0
hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java

@@ -2511,6 +2511,10 @@ public class NumberUtil {
 	 * @return 去掉标识的字符串
 	 */
 	private static String removeNumberFlag(String number) {
+		// 去掉千位分隔符
+		if(StrUtil.contains(number, CharUtil.COMMA)){
+			number = StrUtil.removeAll(number, CharUtil.COMMA);
+		}
 		// 去掉类型标识的结尾
 		final int lastPos = number.length() - 1;
 		final char lastCharUpper = Character.toUpperCase(number.charAt(lastPos));

+ 2 - 2
hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java

@@ -265,11 +265,11 @@ public class DateUtilTest {
 
 	@Test
 	public void currentTest() {
-		long current = DateUtil.current(false);
+		long current = DateUtil.current();
 		String currentStr = String.valueOf(current);
 		Assert.assertEquals(13, currentStr.length());
 
-		long currentNano = DateUtil.current(true);
+		long currentNano = DateUtil.current();
 		String currentNanoStr = String.valueOf(currentNano);
 		Assert.assertNotNull(currentNanoStr);
 	}

+ 60 - 0
hutool-core/src/test/java/cn/hutool/core/util/ArrayUtilTest.java

@@ -317,4 +317,64 @@ public class ArrayUtilTest {
 		String[] hasNull = {"aa", "bb", "cc", null, "bb", "dd"};
 		Assert.assertFalse(ArrayUtil.isAllNotNull(hasNull));
 	}
+
+	@Test
+	public void indexOfSubTest() {
+		Integer[] a = {0x12, 0x34, 0x56, 0x78, 0x9A};
+		Integer[] b = {0x56, 0x78};
+		Integer[] c = {0x12, 0x56};
+		Integer[] d = {0x78, 0x9A};
+		Integer[] e = {0x78, 0x9A, 0x10};
+
+		int i = ArrayUtil.indexOfSub(a, b);
+		Assert.assertEquals(2, i);
+
+		i = ArrayUtil.indexOfSub(a, c);
+		Assert.assertEquals(-1, i);
+
+		i = ArrayUtil.indexOfSub(a, d);
+		Assert.assertEquals(3, i);
+
+		i = ArrayUtil.indexOfSub(a, e);
+		Assert.assertEquals(-1, i);
+
+		i = ArrayUtil.indexOfSub(a, null);
+		Assert.assertEquals(-1, i);
+
+		i = ArrayUtil.indexOfSub(null, null);
+		Assert.assertEquals(-1, i);
+
+		i = ArrayUtil.indexOfSub(null, b);
+		Assert.assertEquals(-1, i);
+	}
+
+	@Test
+	public void lastIndexOfSubTest() {
+		Integer[] a = {0x12, 0x34, 0x56, 0x78, 0x9A};
+		Integer[] b = {0x56, 0x78};
+		Integer[] c = {0x12, 0x56};
+		Integer[] d = {0x78, 0x9A};
+		Integer[] e = {0x78, 0x9A, 0x10};
+
+		int i = ArrayUtil.lastIndexOfSub(a, b);
+		Assert.assertEquals(2, i);
+
+		i = ArrayUtil.lastIndexOfSub(a, c);
+		Assert.assertEquals(-1, i);
+
+		i = ArrayUtil.lastIndexOfSub(a, d);
+		Assert.assertEquals(3, i);
+
+		i = ArrayUtil.lastIndexOfSub(a, e);
+		Assert.assertEquals(-1, i);
+
+		i = ArrayUtil.lastIndexOfSub(a, null);
+		Assert.assertEquals(-1, i);
+
+		i = ArrayUtil.lastIndexOfSub(null, null);
+		Assert.assertEquals(-1, i);
+
+		i = ArrayUtil.lastIndexOfSub(null, b);
+		Assert.assertEquals(-1, i);
+	}
 }

+ 16 - 0
hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java

@@ -221,6 +221,22 @@ public class NumberUtilTest {
 		int v7 = NumberUtil.parseInt("0");
 		Assert.assertEquals(0, v7);
 	}
+
+	@Test
+	public void parseIntTest2() {
+		// from 5.4.8 issue#I23ORQ@Gitee
+		// 千位分隔符去掉
+		int v1 = NumberUtil.parseInt("1,482.00");
+		Assert.assertEquals(1482, v1);
+	}
+
+	@Test
+	public void parseNumberTest() {
+		// from 5.4.8 issue#I23ORQ@Gitee
+		// 千位分隔符去掉
+		int v1 = NumberUtil.parseNumber("1,482.00").intValue();
+		Assert.assertEquals(1482, v1);
+	}
 	
 	@Test
 	public void parseLongTest() {

+ 3 - 3
hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java

@@ -18,8 +18,8 @@ public class CronPatternTest {
 		CronPattern pattern;
 		// 任何时间匹配
 		pattern = new CronPattern("* * * * * *");
-		Assert.assertTrue(pattern.match(DateUtil.current(false), true));
-		Assert.assertTrue(pattern.match(DateUtil.current(false), false));
+		Assert.assertTrue(pattern.match(DateUtil.current(), true));
+		Assert.assertTrue(pattern.match(DateUtil.current(), false));
 	}
 	
 	@Test
@@ -30,7 +30,7 @@ public class CronPatternTest {
 		// 任何时间匹配
 		pattern = new CronPattern("* * * * *");
 		for(int i = 0; i < 1; i++) {
-			Assert.assertTrue(pattern.match(DateUtil.current(false), false));
+			Assert.assertTrue(pattern.match(DateUtil.current(), false));
 		}
 	}