mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-05-23 10:25:33 +00:00
ref[move]: move NumberUtils
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
package com.zfoo.protocol.collection;
|
||||
|
||||
|
||||
import com.zfoo.protocol.collection.model.NaturalComparator;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.util.AssertionUtils;
|
||||
import com.zfoo.protocol.util.IOUtils;
|
||||
@@ -131,11 +130,11 @@ public abstract class CollectionUtils {
|
||||
* @return a new sorted List, containing the elements of Collection a and b
|
||||
*/
|
||||
public static <T extends Comparable<? super T>> List<T> collate(List<? extends T> aList, List<? extends T> bList) {
|
||||
return collate(aList, bList, NaturalComparator.getInstance(), true);
|
||||
return collate(aList, bList, Comparator.naturalOrder(), true);
|
||||
}
|
||||
|
||||
public static <T extends Comparable<? super T>> List<T> collate(List<? extends T> aList, List<? extends T> bList, boolean includeDuplicates) {
|
||||
return collate(aList, bList, NaturalComparator.getInstance(), includeDuplicates);
|
||||
return collate(aList, bList, Comparator.naturalOrder(), includeDuplicates);
|
||||
}
|
||||
|
||||
public static <T> List<T> collate(List<T> aList, List<T> bList, Comparator<T> comparator) {
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.collection.model;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class NaturalComparator<E extends Comparable<? super E>> implements Comparator<E> {
|
||||
|
||||
|
||||
/**
|
||||
* The singleton instance.
|
||||
*/
|
||||
private static final NaturalComparator<?> INSTANCE = new NaturalComparator<>();
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructor whose use should be avoided.
|
||||
* <p>
|
||||
* Please use the {@link #getInstance()} method whenever possible.
|
||||
*/
|
||||
public NaturalComparator() {
|
||||
super();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the singleton instance of a ComparableComparator.
|
||||
* <p>
|
||||
* Developers are encouraged to use the comparator returned from this method
|
||||
* instead of constructing a new instance to reduce allocation and GC overhead
|
||||
* when multiple comparable comparators may be used in the same VM.
|
||||
*
|
||||
* @param <E> the element type
|
||||
* @return the singleton ComparableComparator
|
||||
*/
|
||||
public static <E extends Comparable<? super E>> NaturalComparator<E> getInstance() {
|
||||
return (NaturalComparator<E>) INSTANCE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Compare the two {@link Comparable Comparable} arguments.
|
||||
* This method is equivalent to:
|
||||
* <pre>((Comparable)obj1).compareTo(obj2)</pre>
|
||||
*
|
||||
* @param a the first object to compare
|
||||
* @param b the second object to compare
|
||||
* @return negative if obj1 is less, positive if greater, zero if equal
|
||||
* @throws NullPointerException if <i>obj1</i> is <code>null</code>,
|
||||
* or when <code>((Comparable)obj1).compareTo(obj2)</code> does
|
||||
* @throws ClassCastException if <i>obj1</i> is not a <code>Comparable</code>,
|
||||
* or when <code>((Comparable)obj1).compareTo(obj2)</code> does
|
||||
*/
|
||||
@Override
|
||||
public int compare(final E a, final E b) {
|
||||
return a.compareTo(b);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,992 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.util;
|
||||
|
||||
import com.zfoo.protocol.collection.ArrayUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 数字工具类<br>
|
||||
* BigDecimal(double val)构造方法的结果有一定的不可预知性,例如:
|
||||
*
|
||||
* <pre>
|
||||
* new BigDecimal(0.1)
|
||||
* </pre>
|
||||
* <p>
|
||||
* 表示的不是0.1而是0.1000000000000000055511151231257827021181583404541015625
|
||||
* <p>
|
||||
* 这是因为0.1无法准确的表示为double。因此应该使用new BigDecimal(String)。
|
||||
*
|
||||
* @author godotg
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class NumberUtils {
|
||||
|
||||
/**
|
||||
* 默认除法运算精度
|
||||
*/
|
||||
private static final int DEFAULT_DIV_SCALE = 10;
|
||||
|
||||
|
||||
/**
|
||||
* 提供精确的加法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被加值
|
||||
* @return 和
|
||||
*/
|
||||
public static BigDecimal add(Number... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
Number value = values[0];
|
||||
BigDecimal result = new BigDecimal(null == value ? "0" : value.toString());
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.add(new BigDecimal(value.toString()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的加法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被加值
|
||||
* @return 求和
|
||||
*/
|
||||
public static BigDecimal add(String... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
String value = values[0];
|
||||
BigDecimal result = new BigDecimal(null == value ? "0" : value);
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.add(new BigDecimal(value));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的加法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被加值
|
||||
* @return 求和
|
||||
*/
|
||||
public static BigDecimal add(BigDecimal... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
BigDecimal value = values[0];
|
||||
BigDecimal result = null == value ? BigDecimal.ZERO : value;
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.add(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提供精确的减法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被减值
|
||||
* @return 差
|
||||
*/
|
||||
public static BigDecimal sub(Number... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
Number value = values[0];
|
||||
BigDecimal result = new BigDecimal(null == value ? "0" : value.toString());
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.subtract(new BigDecimal(value.toString()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的减法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被减值
|
||||
* @return 差
|
||||
*/
|
||||
public static BigDecimal sub(String... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
String value = values[0];
|
||||
BigDecimal result = new BigDecimal(null == value ? "0" : value);
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.subtract(new BigDecimal(value));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的减法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被减值
|
||||
* @return 差
|
||||
*/
|
||||
public static BigDecimal sub(BigDecimal... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
BigDecimal value = values[0];
|
||||
BigDecimal result = null == value ? BigDecimal.ZERO : value;
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.subtract(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提供精确的乘法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被乘值
|
||||
* @return 积
|
||||
*/
|
||||
public static BigDecimal mul(Number... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
Number value = values[0];
|
||||
BigDecimal result = new BigDecimal(null == value ? "0" : value.toString());
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.multiply(new BigDecimal(value.toString()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的乘法运算
|
||||
*
|
||||
* @param a 被乘数
|
||||
* @param b 乘数
|
||||
* @return 积
|
||||
*/
|
||||
public static BigDecimal mul(String a, String b) {
|
||||
return mul(new BigDecimal(a), new BigDecimal(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的乘法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被乘值
|
||||
* @return 积
|
||||
*/
|
||||
public static BigDecimal mul(String... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
String value = values[0];
|
||||
BigDecimal result = new BigDecimal(null == value ? "0" : value);
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.multiply(new BigDecimal(value));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的乘法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被乘值
|
||||
* @return 积
|
||||
*/
|
||||
public static BigDecimal mul(BigDecimal... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
BigDecimal value = values[0];
|
||||
BigDecimal result = null == value ? BigDecimal.ZERO : value;
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.multiply(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算,当发生除不尽的情况的时候,精确到小数点后10位,后面的四舍五入
|
||||
*
|
||||
* @param a 被除数
|
||||
* @param b 除数
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static BigDecimal div(Number a, Number b) {
|
||||
return div(a, b, DEFAULT_DIV_SCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算,当发生除不尽的情况的时候,精确到小数点后10位,后面的四舍五入
|
||||
*
|
||||
* @param a 被除数
|
||||
* @param b 除数
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static BigDecimal div(String a, String b) {
|
||||
return div(a, b, DEFAULT_DIV_SCALE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度,后面的四舍五入
|
||||
*
|
||||
* @param a 被除数
|
||||
* @param b 除数
|
||||
* @param scale 精确度,如果为负值,取绝对值
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static BigDecimal div(Number a, Number b, int scale) {
|
||||
return div(a, b, scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度,后面的四舍五入
|
||||
*
|
||||
* @param a 被除数
|
||||
* @param b 除数
|
||||
* @param scale 精确度,如果为负值,取绝对值
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static BigDecimal div(String a, String b, int scale) {
|
||||
return div(a, b, scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度
|
||||
*
|
||||
* @param a 被除数
|
||||
* @param b 除数
|
||||
* @param scale 精确度,如果为负值,取绝对值
|
||||
* @param roundingMode 保留小数的模式 {@link RoundingMode}
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static BigDecimal div(Number a, Number b, int scale, RoundingMode roundingMode) {
|
||||
return div(a.toString(), b.toString(), scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度
|
||||
*
|
||||
* @param a 被除数
|
||||
* @param b 除数
|
||||
* @param scale 精确度,如果为负值,取绝对值
|
||||
* @param roundingMode 保留小数的模式 {@link RoundingMode}
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static BigDecimal div(String a, String b, int scale, RoundingMode roundingMode) {
|
||||
return div(new BigDecimal(a), new BigDecimal(b), scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度
|
||||
*
|
||||
* @param a 被除数
|
||||
* @param b 除数
|
||||
* @param scale 精确度,如果为负值,取绝对值
|
||||
* @param roundingMode 保留小数的模式 {@link RoundingMode}
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static BigDecimal div(BigDecimal a, BigDecimal b, int scale, RoundingMode roundingMode) {
|
||||
AssertionUtils.notNull(b, "Divisor must be not null !");
|
||||
if (null == a) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
if (scale < 0) {
|
||||
scale = -scale;
|
||||
}
|
||||
return a.divide(b, scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的乘法运算<br>
|
||||
* 如果传入多个值为null或者空,则返回0
|
||||
*
|
||||
* @param values 多个被乘值
|
||||
* @return 积
|
||||
*/
|
||||
public static BigDecimal div(BigDecimal... values) {
|
||||
if (ArrayUtils.isEmpty(values)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
BigDecimal value = values[0];
|
||||
BigDecimal result = null == value ? BigDecimal.ZERO : value;
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (null != value) {
|
||||
result = result.divide(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- round
|
||||
|
||||
/**
|
||||
* 保留固定位数小数<br>
|
||||
* 采用四舍五入策略 {@link RoundingMode#HALF_UP}<br>
|
||||
* 例如保留2位小数:123.456789 =》 123.46
|
||||
*
|
||||
* @param v 值
|
||||
* @param scale 保留小数位数
|
||||
* @return 新值
|
||||
*/
|
||||
public static BigDecimal round(double v, int scale) {
|
||||
return round(v, scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保留固定位数小数<br>
|
||||
* 采用四舍五入策略 {@link RoundingMode#HALF_UP}<br>
|
||||
* 例如保留2位小数:123.456789 =》 123.46
|
||||
*
|
||||
* @param numberStr 数字值的字符串表现形式
|
||||
* @param scale 保留小数位数
|
||||
* @return 新值
|
||||
*/
|
||||
public static BigDecimal round(String numberStr, int scale) {
|
||||
return round(numberStr, scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留固定位数小数<br>
|
||||
* 采用四舍五入策略 {@link RoundingMode#HALF_UP}<br>
|
||||
* 例如保留2位小数:123.456789 =》 123.46
|
||||
*
|
||||
* @param number 数字值
|
||||
* @param scale 保留小数位数
|
||||
* @return 新值
|
||||
*/
|
||||
public static BigDecimal round(BigDecimal number, int scale) {
|
||||
return round(number, scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留固定位数小数<br>
|
||||
* 例如保留四位小数:123.456789 =》 123.4567
|
||||
*
|
||||
* @param v 值
|
||||
* @param scale 保留小数位数
|
||||
* @param roundingMode 保留小数的模式 {@link RoundingMode}
|
||||
* @return 新值
|
||||
*/
|
||||
public static BigDecimal round(double v, int scale, RoundingMode roundingMode) {
|
||||
return round(Double.toString(v), scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留固定位数小数<br>
|
||||
* 例如保留四位小数:123.456789 =》 123.4567
|
||||
*
|
||||
* @param numberStr 数字值的字符串表现形式
|
||||
* @param scale 保留小数位数,如果传入小于0,则默认0
|
||||
* @param roundingMode 保留小数的模式 {@link RoundingMode},如果传入null则默认四舍五入
|
||||
* @return 新值
|
||||
*/
|
||||
public static BigDecimal round(String numberStr, int scale, RoundingMode roundingMode) {
|
||||
AssertionUtils.isTrue(StringUtils.isNotBlank(numberStr));
|
||||
if (scale < 0) {
|
||||
scale = 0;
|
||||
}
|
||||
return round(toBigDecimal(numberStr), scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留固定位数小数<br>
|
||||
* 例如保留四位小数:123.456789 =》 123.4567
|
||||
*
|
||||
* @param number 数字值
|
||||
* @param scale 保留小数位数,如果传入小于0,则默认0
|
||||
* @param roundingMode 保留小数的模式 {@link RoundingMode},如果传入null则默认四舍五入
|
||||
* @return 新值
|
||||
*/
|
||||
public static BigDecimal round(BigDecimal number, int scale, RoundingMode roundingMode) {
|
||||
if (null == number) {
|
||||
number = BigDecimal.ZERO;
|
||||
}
|
||||
if (scale < 0) {
|
||||
scale = 0;
|
||||
}
|
||||
if (null == roundingMode) {
|
||||
roundingMode = RoundingMode.HALF_UP;
|
||||
}
|
||||
|
||||
return number.setScale(scale, roundingMode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 四舍六入五成双计算法
|
||||
* <p>
|
||||
* 四舍六入五成双是一种比较精确比较科学的计数保留法,是一种数字修约规则。
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* 算法规则:
|
||||
* 四舍六入五考虑,
|
||||
* 五后非零就进一,
|
||||
* 五后皆零看奇偶,
|
||||
* 五前为偶应舍去,
|
||||
* 五前为奇要进一。
|
||||
* </pre>
|
||||
*
|
||||
* @param number 需要科学计算的数据
|
||||
* @param scale 保留的小数位
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal roundHalfEven(Number number, int scale) {
|
||||
return roundHalfEven(toBigDecimal(number), scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 四舍六入五成双计算法
|
||||
* <p>
|
||||
* 四舍六入五成双是一种比较精确比较科学的计数保留法,是一种数字修约规则。
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* 算法规则:
|
||||
* 四舍六入五考虑,
|
||||
* 五后非零就进一,
|
||||
* 五后皆零看奇偶,
|
||||
* 五前为偶应舍去,
|
||||
* 五前为奇要进一。
|
||||
* </pre>
|
||||
*
|
||||
* @param value 需要科学计算的数据
|
||||
* @param scale 保留的小数位
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal roundHalfEven(BigDecimal value, int scale) {
|
||||
return round(value, scale, RoundingMode.HALF_EVEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留固定小数位数,舍去多余位数
|
||||
*
|
||||
* @param number 需要科学计算的数据
|
||||
* @param scale 保留的小数位
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal roundDown(Number number, int scale) {
|
||||
return roundDown(toBigDecimal(number), scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留固定小数位数,舍去多余位数
|
||||
*
|
||||
* @param value 需要科学计算的数据
|
||||
* @param scale 保留的小数位
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal roundDown(BigDecimal value, int scale) {
|
||||
return round(value, scale, RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- decimalFormat
|
||||
|
||||
/**
|
||||
* 格式化double<br>
|
||||
* 对 {@link DecimalFormat} 做封装<br>
|
||||
*
|
||||
* @param pattern 格式 格式中主要以 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充,# 表示只要有可能就把数字拉上这个位置。<br>
|
||||
* <ul>
|
||||
* <li>0 =》 取一位整数</li>
|
||||
* <li>0.00 =》 取一位整数和两位小数</li>
|
||||
* <li>00.000 =》 取两位整数和三位小数</li>
|
||||
* <li># =》 取所有整数部分</li>
|
||||
* <li>#.##% =》 以百分比方式计数,并取两位小数</li>
|
||||
* <li>#.#####E0 =》 显示为科学计数法,并取五位小数</li>
|
||||
* <li>,### =》 每三位以逗号进行分隔,例如:299,792,458</li>
|
||||
* <li>光速大小为每秒,###米 =》 将格式嵌入文本</li>
|
||||
* </ul>
|
||||
* @param value 值
|
||||
* @return 格式化后的值
|
||||
*/
|
||||
public static String decimalFormat(String pattern, double value) {
|
||||
return new DecimalFormat(pattern).format(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化double<br>
|
||||
* 对 {@link DecimalFormat} 做封装<br>
|
||||
*
|
||||
* @param pattern 格式 格式中主要以 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充,# 表示只要有可能就把数字拉上这个位置。<br>
|
||||
* <ul>
|
||||
* <li>0 =》 取一位整数</li>
|
||||
* <li>0.00 =》 取一位整数和两位小数</li>
|
||||
* <li>00.000 =》 取两位整数和三位小数</li>
|
||||
* <li># =》 取所有整数部分</li>
|
||||
* <li>#.##% =》 以百分比方式计数,并取两位小数</li>
|
||||
* <li>#.#####E0 =》 显示为科学计数法,并取五位小数</li>
|
||||
* <li>,### =》 每三位以逗号进行分隔,例如:299,792,458</li>
|
||||
* <li>光速大小为每秒,###米 =》 将格式嵌入文本</li>
|
||||
* </ul>
|
||||
* @param value 值
|
||||
* @return 格式化后的值
|
||||
*/
|
||||
public static String decimalFormat(String pattern, long value) {
|
||||
return new DecimalFormat(pattern).format(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化金额输出,每三位用逗号分隔
|
||||
*
|
||||
* @param value 金额
|
||||
* @return 格式化后的值
|
||||
*/
|
||||
public static String decimalFormatMoney(double value) {
|
||||
return decimalFormat(",##0.00", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化百分比,小数采用四舍五入方式
|
||||
*
|
||||
* @param number 值
|
||||
* @param scale 保留小数位数
|
||||
* @return 百分比
|
||||
*/
|
||||
public static String formatPercent(double number, int scale) {
|
||||
final NumberFormat format = NumberFormat.getPercentInstance();
|
||||
format.setMaximumFractionDigits(scale);
|
||||
return format.format(number);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- isXXX
|
||||
|
||||
/**
|
||||
* 判断String是否是整数<br>
|
||||
* 支持8、10、16进制
|
||||
*
|
||||
* @param s String
|
||||
* @return 是否为整数
|
||||
*/
|
||||
public static boolean isInteger(String s) {
|
||||
try {
|
||||
Integer.parseInt(s);
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否是Long类型<br>
|
||||
* 支持8、10、16进制
|
||||
*
|
||||
* @param s String
|
||||
* @return 是否为{@link Long}类型
|
||||
*/
|
||||
public static boolean isLong(String s) {
|
||||
try {
|
||||
Long.parseLong(s);
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否是浮点数
|
||||
*
|
||||
* @param s String
|
||||
* @return 是否为{@link Double}类型
|
||||
*/
|
||||
public static boolean isDouble(String s) {
|
||||
try {
|
||||
Double.parseDouble(s);
|
||||
return s.contains(".");
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否全部都为数字
|
||||
* <pre>
|
||||
* StringUtils.isNumeric(null) = false
|
||||
* StringUtils.isNumeric("") = false
|
||||
* StringUtils.isNumeric(" ") = false
|
||||
* StringUtils.isNumeric("123") = true
|
||||
* StringUtils.isNumeric("\u0967\u0968\u0969") = true
|
||||
* StringUtils.isNumeric("12 3") = false
|
||||
* StringUtils.isNumeric("ab2c") = false
|
||||
* StringUtils.isNumeric("12-3") = false
|
||||
* StringUtils.isNumeric("12.3") = false
|
||||
* StringUtils.isNumeric("-123") = false
|
||||
* StringUtils.isNumeric("+123") = false
|
||||
* </pre>
|
||||
*
|
||||
* @param cs the CharSequence to check, may be null
|
||||
* @return {@code true} if only contains digits, and is non-null
|
||||
*/
|
||||
public static boolean isNumeric(final CharSequence cs) {
|
||||
if (StringUtils.isEmpty(cs)) {
|
||||
return false;
|
||||
}
|
||||
return cs.chars().allMatch(it -> Character.isDigit(it));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是质数(素数)<br>
|
||||
* 质数表的质数又称素数。指整数在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。
|
||||
*
|
||||
* @param n 数字
|
||||
* @return 是否是质数
|
||||
*/
|
||||
public static boolean isPrimes(int n) {
|
||||
AssertionUtils.isTrue(n > 1, "The number must be > 1");
|
||||
for (int i = 2; i <= Math.sqrt(n); i++) {
|
||||
if (n % i == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------- range
|
||||
|
||||
/**
|
||||
* 从0开始给定范围内的整数列表,步进为1
|
||||
*
|
||||
* @param stop 结束(包含)
|
||||
* @return 整数列表
|
||||
*/
|
||||
public static int[] range(int stop) {
|
||||
return range(0, stop);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定范围内的整数列表,步进为1
|
||||
*
|
||||
* @param start 开始(包含)
|
||||
* @param stop 结束(包含)
|
||||
* @return 整数列表
|
||||
*/
|
||||
public static int[] range(int start, int stop) {
|
||||
return range(start, stop, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定范围内的整数列表
|
||||
*
|
||||
* @param start 开始(包含)
|
||||
* @param stop 结束(包含)
|
||||
* @param step 步进
|
||||
* @return 整数列表
|
||||
*/
|
||||
public static int[] range(int start, int stop, int step) {
|
||||
if (start < stop) {
|
||||
step = Math.abs(step);
|
||||
} else if (start > stop) {
|
||||
step = -Math.abs(step);
|
||||
} else {// start == end
|
||||
return new int[]{start};
|
||||
}
|
||||
|
||||
int size = Math.abs((stop - start) / step) + 1;
|
||||
int[] values = new int[size];
|
||||
int index = 0;
|
||||
for (int i = start; (step > 0) ? i <= stop : i >= stop; i += step) {
|
||||
values[index] = i;
|
||||
index++;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将给定范围内的整数添加到已有集合中,步进为1
|
||||
*
|
||||
* @param start 开始(包含)
|
||||
* @param stop 结束(包含)
|
||||
* @param values 集合
|
||||
* @return 集合
|
||||
*/
|
||||
public static Collection<Integer> appendRange(int start, int stop, Collection<Integer> values) {
|
||||
return appendRange(start, stop, 1, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将给定范围内的整数添加到已有集合中
|
||||
*
|
||||
* @param start 开始(包含)
|
||||
* @param stop 结束(包含)
|
||||
* @param step 步进
|
||||
* @param values 集合
|
||||
* @return 集合
|
||||
*/
|
||||
public static Collection<Integer> appendRange(int start, int stop, int step, Collection<Integer> values) {
|
||||
if (start < stop) {
|
||||
step = Math.abs(step);
|
||||
} else if (start > stop) {
|
||||
step = -Math.abs(step);
|
||||
} else {// start == end
|
||||
values.add(start);
|
||||
return values;
|
||||
}
|
||||
|
||||
for (int i = start; (step > 0) ? i <= stop : i >= stop; i += step) {
|
||||
values.add(i);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- others
|
||||
|
||||
/**
|
||||
* 计算阶乘
|
||||
* <p>
|
||||
* n! = n * (n-1) * ... * end
|
||||
* </p>
|
||||
*
|
||||
* @param start 阶乘起始
|
||||
* @param end 阶乘结束
|
||||
* @return 结果
|
||||
*/
|
||||
public static long factorial(long start, long end) {
|
||||
if (start < end) {
|
||||
return 0L;
|
||||
}
|
||||
if (start == end) {
|
||||
return 1L;
|
||||
}
|
||||
return start * factorial(start - 1, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算阶乘
|
||||
* <p>
|
||||
* n! = n * (n-1) * ... * 2 * 1
|
||||
* </p>
|
||||
*
|
||||
* @param n 阶乘起始
|
||||
* @return 结果
|
||||
*/
|
||||
public static long factorial(long n) {
|
||||
return factorial(n, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 平方根算法<br>
|
||||
* 推荐使用 {@link Math#sqrt(double)}
|
||||
*
|
||||
* @param x 值
|
||||
* @return 平方根
|
||||
*/
|
||||
public static long sqrt(long x) {
|
||||
long y = 0;
|
||||
long b = (~Long.MAX_VALUE) >>> 1;
|
||||
while (b > 0) {
|
||||
if (x >= y + b) {
|
||||
x -= y + b;
|
||||
y >>= 1;
|
||||
y += b;
|
||||
} else {
|
||||
y >>= 1;
|
||||
}
|
||||
b >>= 2;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最大公约数
|
||||
*
|
||||
* @param m 第一个值
|
||||
* @param n 第二个值
|
||||
* @return 最大公约数
|
||||
*/
|
||||
public static int divisor(int m, int n) {
|
||||
while (m % n != 0) {
|
||||
int temp = m % n;
|
||||
m = n;
|
||||
n = temp;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最小公倍数
|
||||
*
|
||||
* @param m 第一个值
|
||||
* @param n 第二个值
|
||||
* @return 最小公倍数
|
||||
*/
|
||||
public static int multiple(int m, int n) {
|
||||
return m * n / divisor(m, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得数字对应的二进制字符串
|
||||
*
|
||||
* @param number 数字
|
||||
* @return 二进制字符串
|
||||
*/
|
||||
public static String getBinaryStr(Number number) {
|
||||
if (number instanceof Long) {
|
||||
return Long.toBinaryString((Long) number);
|
||||
} else if (number instanceof Integer) {
|
||||
return Integer.toBinaryString((Integer) number);
|
||||
} else {
|
||||
return Long.toBinaryString(number.longValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 二进制转int
|
||||
*
|
||||
* @param binaryStr 二进制字符串
|
||||
* @return int
|
||||
*/
|
||||
public static int binaryToInt(String binaryStr) {
|
||||
return Integer.parseInt(binaryStr, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 二进制转long
|
||||
*
|
||||
* @param binaryStr 二进制字符串
|
||||
* @return long
|
||||
*/
|
||||
public static long binaryToLong(String binaryStr) {
|
||||
return Long.parseLong(binaryStr, 2);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- compare
|
||||
|
||||
|
||||
/**
|
||||
* 数字转{@link BigDecimal}
|
||||
*
|
||||
* @param number 数字
|
||||
* @return {@link BigDecimal}
|
||||
*/
|
||||
public static BigDecimal toBigDecimal(Number number) {
|
||||
if (null == number) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return toBigDecimal(number.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字转{@link BigDecimal}
|
||||
*
|
||||
* @param number 数字
|
||||
* @return {@link BigDecimal}
|
||||
*/
|
||||
public static BigDecimal toBigDecimal(String number) {
|
||||
return (null == number) ? BigDecimal.ZERO : new BigDecimal(number);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断两个数字是否相邻,例如1和2相邻,1和3不相邻<br>
|
||||
* 判断方法为做差取绝对值判断是否为1
|
||||
*
|
||||
* @param number1 数字1
|
||||
* @param number2 数字2
|
||||
* @return 是否相邻
|
||||
*/
|
||||
public static boolean isBeside(long number1, long number2) {
|
||||
return Math.abs(number1 - number2) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断两个数字是否相邻,例如1和2相邻,1和3不相邻<br>
|
||||
* 判断方法为做差取绝对值判断是否为1
|
||||
*
|
||||
* @param number1 数字1
|
||||
* @param number2 数字2
|
||||
* @return 是否相邻
|
||||
*/
|
||||
public static boolean isBeside(int number1, int number2) {
|
||||
return Math.abs(number1 - number2) == 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提供精确的幂运算
|
||||
*
|
||||
* @param number 底数
|
||||
* @param n 指数
|
||||
* @return 幂的积
|
||||
*/
|
||||
public static BigDecimal pow(Number number, int n) {
|
||||
return pow(toBigDecimal(number), n);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的幂运算
|
||||
*
|
||||
* @param number 底数
|
||||
* @param n 指数
|
||||
* @return 幂的积
|
||||
*/
|
||||
public static BigDecimal pow(BigDecimal number, int n) {
|
||||
return number.pow(n);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user