All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.iofairy.top.G Maven / Gradle / Ivy

Go to download

Functional Programming for Java 8+ and compatible with the modular system of Java 9+.

There is a newer version: 0.5.10
Show newest version
/*
 * Copyright (C) 2021 iofairy, 
 *
 * 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.iofairy.top;

import com.iofairy.tcf.Try;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.util.*;

/**
 * Global Variables And Methods. 
* 常用的变量与函数。
* >>>>>>
* 采用简单类名 G (Global) 模拟类似 Kotlin 的 Top-level function(顶级函数、全局函数) * * @since 0.0.1 */ public final class G { /** * Collection Class Name * * @since 0.2.3 */ private static class CollectionCN { /* * Collection */ public final static String ARRAYS$ARRAYLIST = "java.util.Arrays$ArrayList"; public final static String ARRAYLIST$SUBLIST = "java.util.ArrayList$SubList"; public final static String SUBLIST = "java.util.SubList"; public final static String RANDOMACCESSSUBLIST = "java.util.RandomAccessSubList"; // JDK 9+ public final static String ABSTRACTLIST$SUBLIST = "java.util.AbstractList$SubList"; public final static String ABSTRACTLIST$RANDOMACCESSSUBLIST = "java.util.AbstractList$RandomAccessSubList"; } /** * Map Class Name * * @since 0.2.3 */ private static class MapCN { /* * Map */ public final static String COLLECTIONS$SINGLETONMAP = "java.util.Collections$SingletonMap"; public final static String TREEMAP$ASCENDINGSUBMAP = "java.util.TreeMap$AscendingSubMap"; public final static String TREEMAP$DESCENDINGSUBMAP = "java.util.TreeMap$DescendingSubMap"; // JDK 9+ public final static String IMMUTABLECOLLECTIONS$MAP1 = "java.util.ImmutableCollections$Map1"; public final static String IMMUTABLECOLLECTIONS$MAPN = "java.util.ImmutableCollections$MapN"; } /** * DateTime Formatters * * @since 0.2.3 */ private static class DTFormatters { public final static ZoneId DEFAULT_ZONE = Try.tcf(() -> ZoneId.systemDefault(), false); /*############################################ ************* DateTime Formatter ************ ############################################*/ public final static DateTimeFormatter SIMPLE_DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); public final static DateTimeFormatter CONCISE_DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS '['VV xxx']'"); public final static DateTimeFormatter CONCISE_OFFSET_DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS '['xxx']'"); public final static DateTimeFormatter DETAILED_DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS '['E']'"); public final static DateTimeFormatter DETAILED_ZONED_DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS '['VV xxx O E']'"); public final static DateTimeFormatter DETAILED_OFFSET_DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS '['xxx O E']'"); } /** * String used to represent "not a number". */ public static final String NAN = "NaN"; /** * String used to represent infinity. */ public static final String INFINITY = "∞"; /*################################################################################### ************************************************************************************ ------------------------------------------------------------------------------------ ******************************** Global methods ******************************** ******************************* 全局方法 ****************************** ------------------------------------------------------------------------------------ ************************************************************************************ ###################################################################################*/ /** * Whether object array contains {@code null} value or object array is {@code null}.
* 数组中是否包含{@code null}值或数组本身就是{@code null},则返回{@code true} * * @param objects object array * @return {@code true} or {@code false} * @since 0.0.1 */ public static boolean hasNull(Object... objects) { if (objects == null) return true; if (objects.length == 0) return false; boolean hasNull = false; for (Object obj : objects) { if (obj == null) { hasNull = true; break; } } return hasNull; } /** * {@code true} if all array values are {@code null} or object array is {@code null}.
* 数组中所有的值都是{@code null}或数组本身就是{@code null},则返回{@code true} * * @param objects object array * @return {@code true} or {@code false} * @since 0.0.1 */ public static boolean allNull(Object... objects) { if (objects == null) return true; if (objects.length == 0) return false; boolean allNull = true; for (Object obj : objects) { if (obj != null) { allNull = false; break; } } return allNull; } /** * Whether object Collection contains {@code null} value or object Collection is {@code null}.
* Collection中是否包含{@code null}值或Collection本身就是{@code null},则返回{@code true} * * @param objects object Collection * @return {@code true} or {@code false} * @since 0.5.0 */ public static boolean hasNull(Collection objects) { if (objects == null) return true; if (objects.isEmpty()) return false; boolean hasNull = false; for (Object obj : objects) { if (obj == null) { hasNull = true; break; } } return hasNull; } /** * {@code true} if all Collection values are {@code null} or object Collection is {@code null}.
* Collection中所有的值都是{@code null}或Collection本身就是{@code null},则返回{@code true} * * @param objects object Collection * @return {@code true} or {@code false} * @since 0.5.0 */ public static boolean allNull(Collection objects) { if (objects == null) return true; if (objects.isEmpty()) return false; boolean allNull = true; for (Object obj : objects) { if (obj != null) { allNull = false; break; } } return allNull; } /** * Return {@code true} when object is {@code null}
* * @param o object * @return {@code true} or {@code false} * @since 0.5.2 */ public static boolean isNull(Object o) { return o == null; } /** * Return {@code true} when object is {@code null}, or object is a array and this array is empty.
* 如果 object 为{@code null}或object是一个数组且数组中没有一个元素,则返回{@code true} * * @param o object * @return {@code true} or {@code false} * @since 0.2.2 */ @SuppressWarnings("rawtypes") public static boolean isEmpty(Object o) { if (o == null) return true; if (o instanceof CharSequence) return ((CharSequence) o).length() == 0; if (o instanceof Map) return ((Map) o).isEmpty(); if (o instanceof Collection) return ((Collection) o).isEmpty(); if (o instanceof Object[]) return ((Object[]) o).length == 0; if (o instanceof int[]) return ((int[]) o).length == 0; if (o instanceof long[]) return ((long[]) o).length == 0; if (o instanceof float[]) return ((float[]) o).length == 0; if (o instanceof double[]) return ((double[]) o).length == 0; if (o instanceof char[]) return ((char[]) o).length == 0; if (o instanceof byte[]) return ((byte[]) o).length == 0; if (o instanceof short[]) return ((short[]) o).length == 0; if (o instanceof boolean[]) return ((boolean[]) o).length == 0; return false; } /** * Return {@code true} when object is not {@code null}
* * @param o object * @return {@code true} or {@code false} * @since 0.5.2 */ public static boolean isNotNull(Object o) { return !isNull(o); } /** * Return {@code true} when object is not empty.
* * @param o object * @return {@code true} or {@code false} * @since 0.5.2 */ public static boolean isNotEmpty(Object o) { return !isEmpty(o); } /** * Gets the full exception stack trace from {@link Throwable} object.
* 从 {@link Throwable} 对象中获取完整的异常堆栈信息 * @param e Throwable object * @return full exception stack trace * @since 0.0.8 */ public static String stackTrace(Throwable e) { if (e == null) return "null"; StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw, true); e.printStackTrace(pw); return sw.getBuffer().toString(); } /** * Obtain a more concise exception stack trace by filtering through package names.
* 通过包名过滤,获取更简洁的异常堆栈信息 * * @param e Exception object * @param packages Package names to be filtered * @return Exception stack trace information * @since 0.5.0 */ public static String stackTraceSimple(Throwable e, String... packages) { String stackTrace = G.stackTrace(e); if (e == null || G.isEmpty(packages)) return stackTrace; String[] stackTraceList = stackTrace.split("\n"); List stackTraces = new ArrayList<>(); for (String stack : stackTraceList) { if (stack.startsWith("\t")) { for (String pack : packages) { if (pack != null && stack.contains(pack)) { stackTraces.add(stack); break; } } } else { stackTraces.add(stack); } } return String.join("\n", stackTraces) + "\n"; } /** * Obtain a more concise exception stack trace by filtering through package names.
* 通过包名过滤,获取更简洁的异常堆栈信息 * * @param e Exception object * @param packages Package names to be filtered * @return Exception stack trace information * @since 0.5.0 */ public static String stackTraceConcise(Throwable e, String... packages) { if (e == null || G.isEmpty(packages)) return G.stackTrace(e); List throwables = O.causeTrace(e); List stackTraces = new ArrayList<>(); for (int i = 0; i < throwables.size(); i++) { Throwable throwable = throwables.get(i); if (throwable == null) { stackTraces.add(i == 0 ? "null" : "Caused by: null"); continue; } stackTraces.add(i == 0 ? throwable.toString() : "Caused by: " + throwable); StackTraceElement[] stackTraceElements = throwable.getStackTrace(); for (StackTraceElement stackTraceElement : stackTraceElements) { if (stackTraceElement == null) continue; String traceElementString = stackTraceElement.toString(); for (String pack : packages) { if (pack != null && traceElementString.contains(pack)) { stackTraces.add("\tat " + traceElementString); break; } } } } return String.join("\n", stackTraces) + "\n"; } /** * Formatting DateTime use simple pattern ({@code yyyy-MM-dd HH:mm:ss.SSS}). * * @param date date * @return Time formatting String * @since 0.2.3 */ public static String dtSimple(Date date) { if (date == null) return "null"; String className = date.getClass().getName(); if (Objects.equals(className, "java.sql.Date") || Objects.equals(className, "java.sql.Time")) return date.toString(); return dtSimple(date.toInstant()); } /** * Formatting DateTime use simple pattern ({@code yyyy-MM-dd HH:mm:ss.SSS}). * * @param calendar calendar * @return Time formatting String * @since 0.2.3 */ public static String dtSimple(Calendar calendar) { if (calendar == null) return "null"; return dtSimple(ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId())); } /** * Formatting DateTime (only {@link LocalDateTime}, {@link Instant}, {@link OffsetDateTime}, {@link ZonedDateTime}) * use simple pattern ({@code yyyy-MM-dd HH:mm:ss.SSS}). * * @param temporal temporal * @return Time formatting String * @since 0.2.3 */ public static String dtSimple(Temporal temporal) { if (temporal == null) return "null"; if (temporal instanceof LocalDateTime) return ((LocalDateTime) temporal).format(DTFormatters.SIMPLE_DTF); if (temporal instanceof OffsetDateTime) { Integer defaultOffsetSeconds = Try.tcf(() -> OffsetDateTime.now().getOffset().getTotalSeconds(), false); OffsetDateTime offsetDT = (OffsetDateTime) temporal; int totalSeconds = offsetDT.getOffset().getTotalSeconds(); return Objects.equals(totalSeconds, defaultOffsetSeconds) ? offsetDT.format(DTFormatters.SIMPLE_DTF) : offsetDT.format(DTFormatters.CONCISE_OFFSET_DTF); } ZonedDateTime zonedDT = temporalToZonedDT(temporal); if (zonedDT != null) { return Objects.equals(zonedDT.getZone(), DTFormatters.DEFAULT_ZONE) ? zonedDT.format(DTFormatters.SIMPLE_DTF) : zonedDT.format(DTFormatters.CONCISE_DTF); } return temporal.toString(); } /** * Formatting DateTime use detailed pattern ({@code yyyy-MM-dd HH:mm:ss.SSSSSSSSS '['VV xxx O E']'}). * * @param date date * @return Time formatting String * @since 0.2.3 */ public static String dtDetail(Date date) { if (date == null) return "null"; String className = date.getClass().getName(); if (Objects.equals(className, "java.sql.Date") || Objects.equals(className, "java.sql.Time")) return date.toString(); return dtDetail(date.toInstant()); } /** * Formatting DateTime use detailed pattern ({@code yyyy-MM-dd HH:mm:ss.SSSSSSSSS '['VV xxx O E']'}). * * @param calendar calendar * @return Time formatting String * @since 0.2.3 */ public static String dtDetail(Calendar calendar) { if (calendar == null) return "null"; return dtDetail(ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId())); } /** * Formatting DateTime (only {@link LocalDateTime}, {@link Instant}, {@link OffsetDateTime}, {@link ZonedDateTime}) * use detailed pattern ({@code yyyy-MM-dd HH:mm:ss.SSSSSSSSS '['VV xxx O E']'}). * * @param temporal temporal * @return Time formatting String * @since 0.2.3 */ public static String dtDetail(Temporal temporal) { if (temporal == null) return "null"; if (temporal instanceof LocalDateTime) return ((LocalDateTime) temporal).format(DTFormatters.DETAILED_DTF); ZonedDateTime zonedDT = temporalToZonedDT(temporal); return temporal instanceof OffsetDateTime ? ((OffsetDateTime) temporal).format(DTFormatters.DETAILED_OFFSET_DTF) : (zonedDT != null ? zonedDT.format(DTFormatters.DETAILED_ZONED_DTF) : temporal.toString()); } /** * Convert temporal to ZonedDateTime if temporal {@code instanceof} LocalDateTime or * {@code instanceof} Instant or {@code instanceof} ZonedDateTime, otherwise, * return {@code null}. * * @param temporal temporal * @return ZonedDateTime or null * @since 0.2.3 */ private static ZonedDateTime temporalToZonedDT(Temporal temporal) { return temporal instanceof Instant ? ZonedDateTime.ofInstant((Instant) temporal, DTFormatters.DEFAULT_ZONE) : (temporal instanceof ZonedDateTime ? (ZonedDateTime) temporal : null); } /** * To string for any object
* NOTE:
* When {@code object instanceof Character}, result will be enclosed in single quotes({@code ''});
* When {@code object instanceof CharSequence}, result will be enclosed in double quotes({@code ""}).
* * @param o object * @return string * @since 0.2.2 */ public static String toString(Object o) { // 如果 o == null,那么无论 o 是什么类型,`o instanceof Object` 都为 false if (o == null) return "null"; if (o instanceof Character) return "'" + o + "'"; if (o instanceof CharSequence) return '"' + o.toString() + '"'; if (o instanceof Map.Entry) return toString((Map.Entry) o); if (o instanceof Collection) return toString((Collection) o); if (o instanceof Map) return toString((Map) o); if (o instanceof Character[]) return toString((Character[]) o); if (o instanceof CharSequence[]) return toString((CharSequence[]) o); if (o instanceof int[]) return Arrays.toString((int[]) o); if (o instanceof long[]) return Arrays.toString((long[]) o); if (o instanceof float[]) return toString((float[]) o); if (o instanceof double[]) return toString((double[]) o); if (o instanceof char[]) return toString((char[]) o); if (o instanceof byte[]) return Arrays.toString((byte[]) o); if (o instanceof short[]) return Arrays.toString((short[]) o); if (o instanceof boolean[]) return Arrays.toString((boolean[]) o); if (o instanceof Number) return toString((Number) o); if (o instanceof Number[]) return toString((Number[]) o); if (o instanceof Object[]) return toString((Object[]) o); if (o instanceof Date) return dtSimple((Date) o); if (o instanceof Calendar) return dtSimple((Calendar) o); if (o instanceof Temporal) return dtSimple((Temporal) o); if (o instanceof Throwable) return stackTrace((Throwable) o); return o.toString(); } /** * To string for Object array * * @param os Object array * @return string * @since 0.2.2 */ public static String toString(Object[] os) { if (os == null) return "null"; int maxIndex = os.length - 1; if (maxIndex == -1) return "[]"; StringBuilder b = new StringBuilder("["); for (int i = 0; ; i++) { b.append(toString(os[i])); if (i == maxIndex) return b.append("]").toString(); b.append(", "); } } /** * To string for char array * * @param cs char array * @return string * @since 0.2.2 */ public static String toString(char[] cs) { if (cs == null) return "null"; int maxIndex = cs.length - 1; if (maxIndex == -1) return "[]"; StringBuilder b = new StringBuilder("["); for (int i = 0; ; i++) { b.append("'").append(cs[i]).append("'"); if (i == maxIndex) return b.append("]").toString(); b.append(", "); } } /** * To string for Character array * * @param cs Character array * @return string * @since 0.2.2 */ public static String toString(Character[] cs) { if (cs == null) return "null"; int maxIndex = cs.length - 1; if (maxIndex == -1) return "[]"; StringBuilder b = new StringBuilder("["); for (int i = 0; ; i++) { Character c = cs[i]; b.append(c == null ? c : "'" + c + "'"); if (i == maxIndex) return b.append("]").toString(); b.append(", "); } } /** * To string for CharSequence array * * @param ss CharSequence array * @return string * @since 0.2.2 */ public static String toString(CharSequence[] ss) { if (ss == null) return "null"; int maxIndex = ss.length - 1; if (maxIndex == -1) return "[]"; StringBuilder b = new StringBuilder("["); for (int i = 0; ; i++) { CharSequence s = ss[i]; b.append(s == null ? s : '"' + s.toString() + '"'); if (i == maxIndex) return b.append("]").toString(); b.append(", "); } } /** * To string for Collection * * @param collection Collection * @return string * @since 0.2.2 */ public static String toString(Collection collection) { if (collection == null) return "null"; String className = collection.getClass().getName(); if (collection instanceof ArrayList || collection instanceof LinkedList || collection instanceof HashSet || collection instanceof TreeSet || className.equals(CollectionCN.ARRAYS$ARRAYLIST) || className.equals(CollectionCN.ARRAYLIST$SUBLIST) || className.equals(CollectionCN.SUBLIST) || className.equals(CollectionCN.RANDOMACCESSSUBLIST) || className.equals(CollectionCN.ABSTRACTLIST$SUBLIST) || className.equals(CollectionCN.ABSTRACTLIST$RANDOMACCESSSUBLIST) ) { Iterator it = collection.iterator(); if (!it.hasNext()) return "[]"; StringBuilder b = new StringBuilder("["); for (; ; ) { Object o = it.next(); b.append(o == collection ? "(this Collection)" : toString(o)); if (!it.hasNext()) return b.append(']').toString(); b.append(", "); } } return collection.toString(); } /** * To string for Entry * * @param entry Map.Entry * @return string * @since 0.2.2 */ public static String toString(Map.Entry entry) { if (entry == null) return "null"; Object key = entry.getKey(); Object value = entry.getValue(); return (key == entry ? "(this Entry)" : toString(key)) + "=" + (value == entry ? "(this Entry)" : toString(value)); } /** * To string for Map * * @param map Map * @return string * @since 0.2.2 */ public static String toString(Map map) { if (map == null) return "null"; String className = map.getClass().getName(); if (map instanceof HashMap || map instanceof WeakHashMap || map instanceof TreeMap || className.equals(MapCN.COLLECTIONS$SINGLETONMAP) || className.equals(MapCN.TREEMAP$ASCENDINGSUBMAP) || className.equals(MapCN.TREEMAP$DESCENDINGSUBMAP) || className.equals(MapCN.IMMUTABLECOLLECTIONS$MAP1) || className.equals(MapCN.IMMUTABLECOLLECTIONS$MAPN) ) { Iterator> it = map.entrySet().iterator(); if (!it.hasNext()) return "{}"; StringBuilder b = new StringBuilder("{"); for (; ; ) { Map.Entry entry = it.next(); Object key = entry.getKey(); Object value = entry.getValue(); b.append(key == entry ? "(this Entry)" : (key == map ? "(this Map)" : toString(key))); b.append('='); b.append(value == entry ? "(this Entry)" : (value == map ? "(this Map)" : toString(value))); if (!it.hasNext()) return b.append('}').toString(); b.append(", "); } } return map.toString(); } /** * To string for {@code float[]} * * @param floats float array * @return string * @since 0.3.4 */ public static String toString(float[] floats) { return toString(floats, 6, RoundingMode.HALF_UP, true); } /** * To string for {@code double[]} * * @param doubles double array * @return string * @since 0.3.4 */ public static String toString(double[] doubles) { return toString(doubles, 6, RoundingMode.HALF_UP, true); } /** * To string for {@code Number[]} * * @param numbers Number array * @return string * @since 0.3.4 */ public static String toString(Number[] numbers) { return toString(numbers, 6, RoundingMode.HALF_UP, true); } /** * To string for {@code Number} * * @param number Number * @return string * @since 0.3.4 */ public static String toString(Number number) { return toString(number, 6, RoundingMode.HALF_UP, true); } /** * To string for {@code float[]} * * @param floats float array * @param newScale newScale * @return string * @since 0.3.4 */ public static String toString(float[] floats, int newScale) { return toString(floats, newScale, RoundingMode.HALF_UP, true); } /** * To string for {@code double[]} * * @param doubles double array * @param newScale newScale * @return string * @since 0.3.4 */ public static String toString(double[] doubles, int newScale) { return toString(doubles, newScale, RoundingMode.HALF_UP, true); } /** * To string for {@code Number[]} * * @param numbers Number array * @param newScale newScale * @return string * @since 0.3.4 */ public static String toString(Number[] numbers, int newScale) { return toString(numbers, newScale, RoundingMode.HALF_UP, true); } /** * To string for {@code Number} * * @param number Number * @param newScale newScale * @return string * @since 0.3.4 */ public static String toString(Number number, int newScale) { return toString(number, newScale, RoundingMode.HALF_UP, true); } /** * To string for {@code float[]} * * @param floats float array * @param newScale newScale * @param roundingMode roundingMode * @return string * @since 0.3.4 */ public static String toString(float[] floats, int newScale, RoundingMode roundingMode) { return toString(floats, newScale, roundingMode, true); } /** * To string for {@code double[]} * * @param doubles double array * @param newScale newScale * @param roundingMode roundingMode * @return string * @since 0.3.4 */ public static String toString(double[] doubles, int newScale, RoundingMode roundingMode) { return toString(doubles, newScale, roundingMode, true); } /** * To string for {@code Number[]} * * @param numbers Number array * @param newScale newScale * @param roundingMode roundingMode * @return string * @since 0.3.4 */ public static String toString(Number[] numbers, int newScale, RoundingMode roundingMode) { return toString(numbers, newScale, roundingMode, true); } /** * To string for {@code Number} * * @param number Number * @param newScale newScale * @param roundingMode roundingMode * @return string * @since 0.3.4 */ public static String toString(Number number, int newScale, RoundingMode roundingMode) { return toString(number, newScale, roundingMode, true); } /** * To string for {@code float[]} * * @param floats float array * @param newScale newScale * @param roundingMode roundingMode * @param isStripTrailingZeros isStripTrailingZeros * @return string * @since 0.3.4 */ public static String toString(float[] floats, int newScale, RoundingMode roundingMode, boolean isStripTrailingZeros) { if (floats == null) return "null"; int maxIndex = floats.length - 1; if (maxIndex == -1) return "[]"; StringBuilder b = new StringBuilder("["); for (int i = 0; ; i++) { b.append(toString(floats[i], newScale, roundingMode, isStripTrailingZeros)); if (i == maxIndex) return b.append("]").toString(); b.append(", "); } } /** * To string for {@code double[]} * * @param doubles double array * @param newScale newScale * @param roundingMode roundingMode * @param isStripTrailingZeros isStripTrailingZeros * @return string * @since 0.3.4 */ public static String toString(double[] doubles, int newScale, RoundingMode roundingMode, boolean isStripTrailingZeros) { if (doubles == null) return "null"; int maxIndex = doubles.length - 1; if (maxIndex == -1) return "[]"; StringBuilder b = new StringBuilder("["); for (int i = 0; ; i++) { b.append(toString(doubles[i], newScale, roundingMode, isStripTrailingZeros)); if (i == maxIndex) return b.append("]").toString(); b.append(", "); } } /** * To string for {@code Number[]} * * @param numbers Number array * @param newScale newScale * @param roundingMode roundingMode * @param isStripTrailingZeros isStripTrailingZeros * @return string * @since 0.3.4 */ public static String toString(Number[] numbers, int newScale, RoundingMode roundingMode, boolean isStripTrailingZeros) { if (numbers == null) return "null"; int maxIndex = numbers.length - 1; if (maxIndex == -1) return "[]"; StringBuilder b = new StringBuilder("["); for (int i = 0; ; i++) { b.append(toString(numbers[i], newScale, roundingMode, isStripTrailingZeros)); if (i == maxIndex) return b.append("]").toString(); b.append(", "); } } /** * To string for {@code Number} * * @param number Number * @param newScale newScale * @param roundingMode roundingMode * @param isStripTrailingZeros isStripTrailingZeros * @return string * @since 0.3.4 */ public static String toString(Number number, int newScale, RoundingMode roundingMode, boolean isStripTrailingZeros) { if (number == null) return "null"; if (O.isInfinityOrNaN(number)) { double d = number.doubleValue(); return Double.isNaN(d) ? NAN : (d == Double.POSITIVE_INFINITY ? INFINITY : "-" + INFINITY); } if (O.isFloat(number) || number instanceof BigDecimal) { String numberStr = toString(O.toBigDecimal(number), newScale, roundingMode, isStripTrailingZeros); return numberStr.contains(".") ? numberStr : numberStr + ".0"; } else { return newScale < 0 ? toString(O.toBigDecimal(number), newScale, roundingMode, isStripTrailingZeros) : number.toString(); } } /** * To string for {@link BigDecimal} * * @param bigDecimal bigDecimal * @param newScale newScale * @param roundingMode roundingMode * @param isStripTrailingZeros isStripTrailingZeros * @return string * @since 0.3.4 */ public static String toString(BigDecimal bigDecimal, int newScale, RoundingMode roundingMode, boolean isStripTrailingZeros) { if (bigDecimal == null) return "null"; if (roundingMode == null) roundingMode = RoundingMode.HALF_UP; BigDecimal bd = bigDecimal.setScale(newScale, roundingMode); return isStripTrailingZeros ? bd.stripTrailingZeros().toPlainString() : bd.toPlainString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy