This commit is contained in:
Looly 2022-04-29 01:46:01 +08:00
parent b2f0dc7b0f
commit c753a53173
561 changed files with 1532 additions and 4201 deletions

View File

@ -18,7 +18,7 @@ package cn.hutool;
import cn.hutool.core.lang.ConsoleTable;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.util.Set;

View File

@ -1,7 +1,7 @@
package cn.hutool.core.annotation;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.lang.annotation.Annotation;

View File

@ -2,7 +2,7 @@ package cn.hutool.core.annotation;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.reflect.ReflectUtil;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;

View File

@ -3,9 +3,9 @@ package cn.hutool.core.bean;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.CaseInsensitiveMap;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ModifierUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.reflect.ModifierUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.lang.reflect.Field;

View File

@ -1,7 +1,7 @@
package cn.hutool.core.bean;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* Bean异常

View File

@ -6,7 +6,7 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.util.ArrayList;

View File

@ -10,10 +10,10 @@ import cn.hutool.core.map.CaseInsensitiveMap;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ModifierUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.reflect.ModifierUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.text.StrUtil;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
@ -718,7 +718,7 @@ public class BeanUtil {
* @param copyOptions 拷贝选项 {@link CopyOptions}
*/
public static void copyProperties(Object source, Object target, CopyOptions copyOptions) {
BeanCopier.create(source, target, ObjectUtil.defaultIfNull(copyOptions, CopyOptions::create)).copy();
BeanCopier.create(source, target, ObjUtil.defaultIfNull(copyOptions, CopyOptions::create)).copy();
}
/**

View File

@ -3,7 +3,7 @@ package cn.hutool.core.bean;
import cn.hutool.core.clone.CloneSupport;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.reflect.ReflectUtil;
import java.io.Serializable;
import java.util.Map;

View File

@ -4,8 +4,8 @@ import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.annotation.PropIgnore;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ModifierUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.reflect.ModifierUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.util.TypeUtil;
import java.beans.Transient;

View File

@ -1,7 +1,7 @@
package cn.hutool.core.bean.copier;
import cn.hutool.core.lang.copier.Copier;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
/**
* 抽象的对象拷贝封装提供来源对象目标对象持有
@ -23,6 +23,6 @@ public abstract class AbsCopier<S, T> implements Copier<T> {
public AbsCopier(S source, T target, CopyOptions copyOptions) {
this.source = source;
this.target = target;
this.copyOptions = ObjectUtil.defaultIfNull(copyOptions, CopyOptions::create);
this.copyOptions = ObjUtil.defaultIfNull(copyOptions, CopyOptions::create);
}
}

View File

@ -5,7 +5,7 @@ import cn.hutool.core.bean.PropDesc;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.CaseInsensitiveMap;
import cn.hutool.core.map.MapWrapper;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.TypeUtil;
import java.lang.reflect.Type;

View File

@ -1,975 +0,0 @@
package cn.hutool.core.builder;
import cn.hutool.core.util.ArrayUtil;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Comparator;
/**
* 用于构建 {@link java.lang.Comparable#compareTo(Object)} 方法的辅助工具
*
* <p>
* 在Bean对象中所有相关字段都参与比对继承的字段不参与使用方法如下
*
* <pre>
* public class MyClass {
* String field1;
* int field2;
* boolean field3;
*
* ...
*
* public int compareTo(Object o) {
* MyClass myClass = (MyClass) o;
* return new CompareToBuilder()
* .appendSuper(super.compareTo(o)
* .append(this.field1, myClass.field1)
* .append(this.field2, myClass.field2)
* .append(this.field3, myClass.field3)
* .toComparison();
* }
* }
* </pre>
*
* 字段值按照顺序比较如果某个字段返回非0结果比较终止使用{@code toComparison()}返回结果后续比较忽略
*
* <p>
* 也可以使用{@link #reflectionCompare(Object, Object) reflectionCompare} 方法通过反射比较字段使用方法如下
*
* <pre>
* public int compareTo(Object o) {
* return CompareToBuilder.reflectionCompare(this, o);
* }
* </pre>
*
*TODO 待整理
* 来自于Apache-Commons-Lang3
* @author loolyApache-Commons
* @since 4.2.2
*/
public class CompareToBuilder implements Builder<Integer> {
private static final long serialVersionUID = 1L;
/** 当前比较状态 */
private int comparison;
/**
* 构造构造后调用append方法增加比较项然后调用{@link #toComparison()}获取结果
*/
public CompareToBuilder() {
comparison = 0;
}
//-----------------------------------------------------------------------
/**
* 通过反射比较两个Bean对象对象字段可以为private比较规则如下
*
* <ul>
* <li>static字段不比较</li>
* <li>Transient字段不参与比较</li>
* <li>父类字段参与比较</li>
* </ul>
*
*<p>
*如果被比较的两个对象都为<code>null</code>被认为相同
*
* @param lhs 第一个对象
* @param rhs 第二个对象
* @return a negative integer, zero, or a positive integer as <code>lhs</code>
* is less than, equal to, or greater than <code>rhs</code>
* @throws NullPointerException if either (but not both) parameters are
* <code>null</code>
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
*/
public static int reflectionCompare(final Object lhs, final Object rhs) {
return reflectionCompare(lhs, rhs, false, null);
}
/**
* <p>Compares two <code>Object</code>s via reflection.</p>
*
* <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
* is used to bypass normal access control checks. This will fail under a
* security manager unless the appropriate permissions are set.</p>
*
* <ul>
* <li>Static fields will not be compared</li>
* <li>If <code>compareTransients</code> is <code>true</code>,
* compares transient members. Otherwise ignores them, as they
* are likely derived fields.</li>
* <li>Superclass fields will be compared</li>
* </ul>
*
* <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
* they are considered equal.</p>
*
* @param lhs left-hand object
* @param rhs right-hand object
* @param compareTransients whether to compare transient fields
* @return a negative integer, zero, or a positive integer as <code>lhs</code>
* is less than, equal to, or greater than <code>rhs</code>
* @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
* (but not both) is <code>null</code>
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
*/
public static int reflectionCompare(final Object lhs, final Object rhs, final boolean compareTransients) {
return reflectionCompare(lhs, rhs, compareTransients, null);
}
/**
* <p>Compares two <code>Object</code>s via reflection.</p>
*
* <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
* is used to bypass normal access control checks. This will fail under a
* security manager unless the appropriate permissions are set.</p>
*
* <ul>
* <li>Static fields will not be compared</li>
* <li>If <code>compareTransients</code> is <code>true</code>,
* compares transient members. Otherwise ignores them, as they
* are likely derived fields.</li>
* <li>Superclass fields will be compared</li>
* </ul>
*
* <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
* they are considered equal.</p>
*
* @param lhs left-hand object
* @param rhs right-hand object
* @param excludeFields Collection of String fields to exclude
* @return a negative integer, zero, or a positive integer as <code>lhs</code>
* is less than, equal to, or greater than <code>rhs</code>
* @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
* (but not both) is <code>null</code>
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
* @since 2.2
*/
public static int reflectionCompare(final Object lhs, final Object rhs, final Collection<String> excludeFields) {
return reflectionCompare(lhs, rhs, ArrayUtil.toArray(excludeFields, String.class));
}
/**
* <p>Compares two <code>Object</code>s via reflection.</p>
*
* <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
* is used to bypass normal access control checks. This will fail under a
* security manager unless the appropriate permissions are set.</p>
*
* <ul>
* <li>Static fields will not be compared</li>
* <li>If <code>compareTransients</code> is <code>true</code>,
* compares transient members. Otherwise ignores them, as they
* are likely derived fields.</li>
* <li>Superclass fields will be compared</li>
* </ul>
*
* <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
* they are considered equal.</p>
*
* @param lhs left-hand object
* @param rhs right-hand object
* @param excludeFields array of fields to exclude
* @return a negative integer, zero, or a positive integer as <code>lhs</code>
* is less than, equal to, or greater than <code>rhs</code>
* @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
* (but not both) is <code>null</code>
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
* @since 2.2
*/
public static int reflectionCompare(final Object lhs, final Object rhs, final String... excludeFields) {
return reflectionCompare(lhs, rhs, false, null, excludeFields);
}
/**
* <p>Compares two <code>Object</code>s via reflection.</p>
*
* <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
* is used to bypass normal access control checks. This will fail under a
* security manager unless the appropriate permissions are set.</p>
*
* <ul>
* <li>Static fields will not be compared</li>
* <li>If the <code>compareTransients</code> is <code>true</code>,
* compares transient members. Otherwise ignores them, as they
* are likely derived fields.</li>
* <li>Compares superclass fields up to and including <code>reflectUpToClass</code>.
* If <code>reflectUpToClass</code> is <code>null</code>, compares all superclass fields.</li>
* </ul>
*
* <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
* they are considered equal.</p>
*
* @param lhs left-hand object
* @param rhs right-hand object
* @param compareTransients whether to compare transient fields
* @param reflectUpToClass last superclass for which fields are compared
* @param excludeFields fields to exclude
* @return a negative integer, zero, or a positive integer as <code>lhs</code>
* is less than, equal to, or greater than <code>rhs</code>
* @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
* (but not both) is <code>null</code>
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
* @since 2.2 (2.0 as <code>reflectionCompare(Object, Object, boolean, Class)</code>)
*/
public static int reflectionCompare(
final Object lhs,
final Object rhs,
final boolean compareTransients,
final Class<?> reflectUpToClass,
final String... excludeFields) {
if (lhs == rhs) {
return 0;
}
if (lhs == null || rhs == null) {
throw new NullPointerException();
}
Class<?> lhsClazz = lhs.getClass();
if (!lhsClazz.isInstance(rhs)) {
throw new ClassCastException();
}
final CompareToBuilder compareToBuilder = new CompareToBuilder();
reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass) {
lhsClazz = lhsClazz.getSuperclass();
reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
}
return compareToBuilder.toComparison();
}
/**
* <p>Appends to <code>builder</code> the comparison of <code>lhs</code>
* to <code>rhs</code> using the fields defined in <code>clazz</code>.</p>
*
* @param lhs left-hand object
* @param rhs right-hand object
* @param clazz <code>Class</code> that defines fields to be compared
* @param builder <code>CompareToBuilder</code> to append to
* @param useTransients whether to compare transient fields
* @param excludeFields fields to exclude
*/
private static void reflectionAppend(
final Object lhs,
final Object rhs,
final Class<?> clazz,
final CompareToBuilder builder,
final boolean useTransients,
final String[] excludeFields) {
final Field[] fields = clazz.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
final Field f = fields[i];
if (false == ArrayUtil.contains(excludeFields, f.getName())
&& (f.getName().indexOf('$') == -1)
&& (useTransients || !Modifier.isTransient(f.getModifiers()))
&& (!Modifier.isStatic(f.getModifiers()))) {
try {
builder.append(f.get(lhs), f.get(rhs));
} catch (final IllegalAccessException e) {
// This can't happen. Would get a Security exception instead.
// Throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
}
}
}
}
//-----------------------------------------------------------------------
/**
* <p>Appends to the <code>builder</code> the <code>compareTo(Object)</code>
* result of the superclass.</p>
*
* @param superCompareTo result of calling <code>super.compareTo(Object)</code>
* @return this - used to chain append calls
* @since 2.0
*/
public CompareToBuilder appendSuper(final int superCompareTo) {
if (comparison != 0) {
return this;
}
comparison = superCompareTo;
return this;
}
//-----------------------------------------------------------------------
/**
* <p>Appends to the <code>builder</code> the comparison of
* two <code>Object</code>s.</p>
*
* <ol>
* <li>Check if <code>lhs == rhs</code></li>
* <li>Check if either <code>lhs</code> or <code>rhs</code> is <code>null</code>,
* a <code>null</code> object is less than a non-<code>null</code> object</li>
* <li>Check the object contents</li>
* </ol>
*
* <p><code>lhs</code> must either be an array or implement {@link Comparable}.</p>
*
* @param lhs left-hand object
* @param rhs right-hand object
* @return this - used to chain append calls
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
*/
public CompareToBuilder append(final Object lhs, final Object rhs) {
return append(lhs, rhs, null);
}
/**
* <p>Appends to the <code>builder</code> the comparison of
* two <code>Object</code>s.</p>
*
* <ol>
* <li>Check if <code>lhs == rhs</code></li>
* <li>Check if either <code>lhs</code> or <code>rhs</code> is <code>null</code>,
* a <code>null</code> object is less than a non-<code>null</code> object</li>
* <li>Check the object contents</li>
* </ol>
*
* <p>If <code>lhs</code> is an array, array comparison methods will be used.
* Otherwise <code>comparator</code> will be used to compare the objects.
* If <code>comparator</code> is <code>null</code>, <code>lhs</code> must
* implement {@link Comparable} instead.</p>
*
* @param lhs left-hand object
* @param rhs right-hand object
* @param comparator <code>Comparator</code> used to compare the objects,
* <code>null</code> means treat lhs as <code>Comparable</code>
* @return this - used to chain append calls
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
* @since 2.0
*/
public CompareToBuilder append(final Object lhs, final Object rhs, final Comparator<?> comparator) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.getClass().isArray()) {
// switch on type of array, to dispatch to the correct handler
// handles multi dimensional arrays
// throws a ClassCastException if rhs is not the correct array type
if (lhs instanceof long[]) {
append((long[]) lhs, (long[]) rhs);
} else if (lhs instanceof int[]) {
append((int[]) lhs, (int[]) rhs);
} else if (lhs instanceof short[]) {
append((short[]) lhs, (short[]) rhs);
} else if (lhs instanceof char[]) {
append((char[]) lhs, (char[]) rhs);
} else if (lhs instanceof byte[]) {
append((byte[]) lhs, (byte[]) rhs);
} else if (lhs instanceof double[]) {
append((double[]) lhs, (double[]) rhs);
} else if (lhs instanceof float[]) {
append((float[]) lhs, (float[]) rhs);
} else if (lhs instanceof boolean[]) {
append((boolean[]) lhs, (boolean[]) rhs);
} else {
// not an array of primitives
// throws a ClassCastException if rhs is not an array
append((Object[]) lhs, (Object[]) rhs, comparator);
}
} else {
// the simple case, not an array, just test the element
if (comparator == null) {
@SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
final Comparable<Object> comparable = (Comparable<Object>) lhs;
comparison = comparable.compareTo(rhs);
} else {
@SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
final Comparator<Object> comparator2 = (Comparator<Object>) comparator;
comparison = comparator2.compare(lhs, rhs);
}
}
return this;
}
//-------------------------------------------------------------------------
/**
* Appends to the <code>builder</code> the comparison of
* two <code>long</code>s.
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
*/
public CompareToBuilder append(final long lhs, final long rhs) {
if (comparison != 0) {
return this;
}
comparison = (Long.compare(lhs, rhs));
return this;
}
/**
* Appends to the <code>builder</code> the comparison of
* two <code>int</code>s.
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
*/
public CompareToBuilder append(final int lhs, final int rhs) {
if (comparison != 0) {
return this;
}
comparison = (Integer.compare(lhs, rhs));
return this;
}
/**
* Appends to the <code>builder</code> the comparison of
* two <code>short</code>s.
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
*/
public CompareToBuilder append(final short lhs, final short rhs) {
if (comparison != 0) {
return this;
}
comparison = (Short.compare(lhs, rhs));
return this;
}
/**
* Appends to the <code>builder</code> the comparison of
* two <code>char</code>s.
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
*/
public CompareToBuilder append(final char lhs, final char rhs) {
if (comparison != 0) {
return this;
}
comparison = (Character.compare(lhs, rhs));
return this;
}
/**
* Appends to the <code>builder</code> the comparison of
* two <code>byte</code>s.
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
*/
public CompareToBuilder append(final byte lhs, final byte rhs) {
if (comparison != 0) {
return this;
}
comparison = (Byte.compare(lhs, rhs));
return this;
}
/**
* <p>Appends to the <code>builder</code> the comparison of
* two <code>double</code>s.</p>
*
* <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
*
* <p>It is compatible with the hash code generated by
* <code>HashCodeBuilder</code>.</p>
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
*/
public CompareToBuilder append(final double lhs, final double rhs) {
if (comparison != 0) {
return this;
}
comparison = Double.compare(lhs, rhs);
return this;
}
/**
* <p>Appends to the <code>builder</code> the comparison of
* two <code>float</code>s.</p>
*
* <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
*
* <p>It is compatible with the hash code generated by
* <code>HashCodeBuilder</code>.</p>
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
*/
public CompareToBuilder append(final float lhs, final float rhs) {
if (comparison != 0) {
return this;
}
comparison = Float.compare(lhs, rhs);
return this;
}
/**
* Appends to the <code>builder</code> the comparison of
* two <code>booleans</code>s.
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
*/
public CompareToBuilder append(final boolean lhs, final boolean rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == false) {
comparison = -1;
} else {
comparison = +1;
}
return this;
}
//-----------------------------------------------------------------------
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>Object</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a short length array is less than a long length array</li>
* <li>Check array contents element by element using {@link #append(Object, Object, Comparator)}</li>
* </ol>
*
* <p>This method will also will be called for the top level of multi-dimensional,
* ragged, and multi-typed arrays.</p>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
*/
public CompareToBuilder append(final Object[] lhs, final Object[] rhs) {
return append(lhs, rhs, null);
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>Object</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a short length array is less than a long length array</li>
* <li>Check array contents element by element using {@link #append(Object, Object, Comparator)}</li>
* </ol>
*
* <p>This method will also will be called for the top level of multi-dimensional,
* ragged, and multi-typed arrays.</p>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @param comparator <code>Comparator</code> to use to compare the array elements,
* <code>null</code> means to treat <code>lhs</code> elements as <code>Comparable</code>.
* @return this - used to chain append calls
* @throws ClassCastException if <code>rhs</code> is not assignment-compatible
* with <code>lhs</code>
* @since 2.0
*/
public CompareToBuilder append(final Object[] lhs, final Object[] rhs, final Comparator<?> comparator) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i], comparator);
}
return this;
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>long</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a shorter length array is less than a longer length array</li>
* <li>Check array contents element by element using {@link #append(long, long)}</li>
* </ol>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
*/
public CompareToBuilder append(final long[] lhs, final long[] rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i]);
}
return this;
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>int</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a shorter length array is less than a longer length array</li>
* <li>Check array contents element by element using {@link #append(int, int)}</li>
* </ol>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
*/
public CompareToBuilder append(final int[] lhs, final int[] rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i]);
}
return this;
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>short</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a shorter length array is less than a longer length array</li>
* <li>Check array contents element by element using {@link #append(short, short)}</li>
* </ol>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
*/
public CompareToBuilder append(final short[] lhs, final short[] rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i]);
}
return this;
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>char</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a shorter length array is less than a longer length array</li>
* <li>Check array contents element by element using {@link #append(char, char)}</li>
* </ol>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
*/
public CompareToBuilder append(final char[] lhs, final char[] rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i]);
}
return this;
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>byte</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a shorter length array is less than a longer length array</li>
* <li>Check array contents element by element using {@link #append(byte, byte)}</li>
* </ol>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
*/
public CompareToBuilder append(final byte[] lhs, final byte[] rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i]);
}
return this;
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>double</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a shorter length array is less than a longer length array</li>
* <li>Check array contents element by element using {@link #append(double, double)}</li>
* </ol>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
*/
public CompareToBuilder append(final double[] lhs, final double[] rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i]);
}
return this;
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>float</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a shorter length array is less than a longer length array</li>
* <li>Check array contents element by element using {@link #append(float, float)}</li>
* </ol>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
*/
public CompareToBuilder append(final float[] lhs, final float[] rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i]);
}
return this;
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>boolean</code> arrays.</p>
*
* <ol>
* <li>Check if arrays are the same using <code>==</code></li>
* <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
* <li>Check array length, a shorter length array is less than a longer length array</li>
* <li>Check array contents element by element using {@link #append(boolean, boolean)}</li>
* </ol>
*
* @param lhs left-hand array
* @param rhs right-hand array
* @return this - used to chain append calls
*/
public CompareToBuilder append(final boolean[] lhs, final boolean[] rhs) {
if (comparison != 0) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null) {
comparison = -1;
return this;
}
if (rhs == null) {
comparison = +1;
return this;
}
if (lhs.length != rhs.length) {
comparison = (lhs.length < rhs.length) ? -1 : +1;
return this;
}
for (int i = 0; i < lhs.length && comparison == 0; i++) {
append(lhs[i], rhs[i]);
}
return this;
}
//-----------------------------------------------------------------------
/**
* Returns a negative integer, a positive integer, or zero as
* the <code>builder</code> has judged the "left-hand" side
* as less than, greater than, or equal to the "right-hand"
* side.
*
* @return final comparison result
* @see #build()
*/
public int toComparison() {
return comparison;
}
/**
* Returns a negative Integer, a positive Integer, or zero as
* the <code>builder</code> has judged the "left-hand" side
* as less than, greater than, or equal to the "right-hand"
* side.
*
* @return final comparison result as an Integer
* @see #toComparison()
* @since 3.0
*/
@Override
public Integer build() {
return toComparison();
}
}

View File

@ -1,563 +0,0 @@
package cn.hutool.core.builder;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.ArrayUtil;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* <p>{@link Object#equals(Object)} 方法的构建器</p>
*
* <p>两个对象equals必须保证hashCode值相等hashCode值相等不能保证一定equals</p>
*
* <p>使用方法如下</p>
* <pre>
* public boolean equals(Object obj) {
* if (obj == null) { return false; }
* if (obj == this) { return true; }
* if (obj.getClass() != getClass()) {
* return false;
* }
* MyClass rhs = (MyClass) obj;
* return new EqualsBuilder()
* .appendSuper(super.equals(obj))
* .append(field1, rhs.field1)
* .append(field2, rhs.field2)
* .append(field3, rhs.field3)
* .isEquals();
* }
* </pre>
*
* <p> 我们也可以通过反射判断所有字段是否equals</p>
* <pre>
* public boolean equals(Object obj) {
* return EqualsBuilder.reflectionEquals(this, obj);
* }
* </pre>
* <p>
* 来自Apache Commons Lang改造
*/
public class EqualsBuilder implements Builder<Boolean> {
private static final long serialVersionUID = 1L;
/**
* <p>
* A registry of objects used by reflection methods to detect cyclical object references and avoid infinite loops.
* </p>
*/
private static final ThreadLocal<Set<Pair<IDKey, IDKey>>> REGISTRY = new ThreadLocal<>();
/**
* <p>
* Returns the registry of object pairs being traversed by the reflection
* methods in the current thread.
* </p>
*
* @return Set the registry of objects being traversed
* @since 3.0
*/
static Set<Pair<IDKey, IDKey>> getRegistry() {
return REGISTRY.get();
}
/**
* <p>
* Converters value pair into a register pair.
* </p>
*
* @param lhs {@code this} object
* @param rhs the other object
* @return the pair
*/
static Pair<IDKey, IDKey> getRegisterPair(final Object lhs, final Object rhs) {
final IDKey left = new IDKey(lhs);
final IDKey right = new IDKey(rhs);
return new Pair<>(left, right);
}
/**
* <p>
* Returns {@code true} if the registry contains the given object pair.
* Used by the reflection methods to avoid infinite loops.
* Objects might be swapped therefore a check is needed if the object pair
* is registered in given or swapped order.
* </p>
*
* @param lhs {@code this} object to lookup in registry
* @param rhs the other object to lookup on registry
* @return boolean {@code true} if the registry contains the given object.
* @since 3.0
*/
static boolean isRegistered(final Object lhs, final Object rhs) {
final Set<Pair<IDKey, IDKey>> registry = getRegistry();
final Pair<IDKey, IDKey> pair = getRegisterPair(lhs, rhs);
final Pair<IDKey, IDKey> swappedPair = new Pair<>(pair.getKey(), pair.getValue());
return registry != null
&& (registry.contains(pair) || registry.contains(swappedPair));
}
/**
* <p>
* Registers the given object pair.
* Used by the reflection methods to avoid infinite loops.
* </p>
*
* @param lhs {@code this} object to register
* @param rhs the other object to register
*/
static void register(final Object lhs, final Object rhs) {
synchronized (EqualsBuilder.class) {
if (getRegistry() == null) {
REGISTRY.set(new HashSet<>());
}
}
final Set<Pair<IDKey, IDKey>> registry = getRegistry();
final Pair<IDKey, IDKey> pair = getRegisterPair(lhs, rhs);
registry.add(pair);
}
/**
* <p>
* Unregisters the given object pair.
* </p>
*
* <p>
* Used by the reflection methods to avoid infinite loops.
*
* @param lhs {@code this} object to unregister
* @param rhs the other object to unregister
* @since 3.0
*/
static void unregister(final Object lhs, final Object rhs) {
Set<Pair<IDKey, IDKey>> registry = getRegistry();
if (registry != null) {
final Pair<IDKey, IDKey> pair = getRegisterPair(lhs, rhs);
registry.remove(pair);
synchronized (EqualsBuilder.class) {
//read again
registry = getRegistry();
if (registry != null && registry.isEmpty()) {
REGISTRY.remove();
}
}
}
}
/**
* 是否equals此值随着构建会变更默认true
*/
private boolean isEquals = true;
/**
* 构造初始状态值为true
*/
public EqualsBuilder() {
// do nothing for now.
}
//-------------------------------------------------------------------------
/**
* <p>反射检查两个对象是否equals此方法检查对象及其父对象的属性包括私有属性是否equals</p>
*
* @param lhs 此对象
* @param rhs 另一个对象
* @param excludeFields 排除的字段集合如果有不参与计算equals的字段加入此集合即可
* @return 两个对象是否equals是返回{@code true}
*/
public static boolean reflectionEquals(final Object lhs, final Object rhs, final Collection<String> excludeFields) {
return reflectionEquals(lhs, rhs, ArrayUtil.toArray(excludeFields, String.class));
}
/**
* <p>反射检查两个对象是否equals此方法检查对象及其父对象的属性包括私有属性是否equals</p>
*
* @param lhs 此对象
* @param rhs 另一个对象
* @param excludeFields 排除的字段集合如果有不参与计算equals的字段加入此集合即可
* @return 两个对象是否equals是返回{@code true}
*/
public static boolean reflectionEquals(final Object lhs, final Object rhs, final String... excludeFields) {
return reflectionEquals(lhs, rhs, false, null, excludeFields);
}
/**
* <p>This method uses reflection to determine if the two {@code Object}s
* are equal.</p>
*
* <p>It uses {@code AccessibleObject.setAccessible} to gain access to private
* fields. This means that it will throw a security exception if run under
* a security manager, if the permissions are not set up correctly. It is also
* not as efficient as testing explicitly. Non-primitive fields are compared using
* {@code equals()}.</p>
*
* <p>If the TestTransients parameter is set to {@code true}, transient
* members will be tested, otherwise they are ignored, as they are likely
* derived fields, and not part of the value of the {@code Object}.</p>
*
* <p>Static fields will not be tested. Superclass fields will be included.</p>
*
* @param lhs {@code this} object
* @param rhs the other object
* @param testTransients whether to include transient fields
* @return {@code true} if the two Objects have tested equals.
*/
public static boolean reflectionEquals(final Object lhs, final Object rhs, final boolean testTransients) {
return reflectionEquals(lhs, rhs, testTransients, null);
}
/**
* <p>This method uses reflection to determine if the two {@code Object}s
* are equal.</p>
*
* <p>It uses {@code AccessibleObject.setAccessible} to gain access to private
* fields. This means that it will throw a security exception if run under
* a security manager, if the permissions are not set up correctly. It is also
* not as efficient as testing explicitly. Non-primitive fields are compared using
* {@code equals()}.</p>
*
* <p>If the testTransients parameter is set to {@code true}, transient
* members will be tested, otherwise they are ignored, as they are likely
* derived fields, and not part of the value of the {@code Object}.</p>
*
* <p>Static fields will not be included. Superclass fields will be appended
* up to and including the specified superclass. A null superclass is treated
* as java.lang.Object.</p>
*
* @param lhs {@code this} object
* @param rhs the other object
* @param testTransients whether to include transient fields
* @param reflectUpToClass the superclass to reflect up to (inclusive),
* may be {@code null}
* @param excludeFields array of field names to exclude from testing
* @return {@code true} if the two Objects have tested equals.
* @since 2.0
*/
public static boolean reflectionEquals(final Object lhs, final Object rhs, final boolean testTransients, final Class<?> reflectUpToClass,
final String... excludeFields) {
if (lhs == rhs) {
return true;
}
if (lhs == null || rhs == null) {
return false;
}
// Find the leaf class since there may be transients in the leaf
// class or in classes between the leaf and root.
// If we are not testing transients or a subclass has no ivars,
// then a subclass can test equals to a superclass.
final Class<?> lhsClass = lhs.getClass();
final Class<?> rhsClass = rhs.getClass();
Class<?> testClass;
if (lhsClass.isInstance(rhs)) {
testClass = lhsClass;
if (!rhsClass.isInstance(lhs)) {
// rhsClass is a subclass of lhsClass
testClass = rhsClass;
}
} else if (rhsClass.isInstance(lhs)) {
testClass = rhsClass;
if (!lhsClass.isInstance(rhs)) {
// lhsClass is a subclass of rhsClass
testClass = lhsClass;
}
} else {
// The two classes are not related.
return false;
}
final EqualsBuilder equalsBuilder = new EqualsBuilder();
try {
if (testClass.isArray()) {
equalsBuilder.append(lhs, rhs);
} else {
reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients, excludeFields);
while (testClass.getSuperclass() != null && testClass != reflectUpToClass) {
testClass = testClass.getSuperclass();
reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients, excludeFields);
}
}
} catch (final IllegalArgumentException e) {
// In this case, we tried to test a subclass vs. a superclass and
// the subclass has ivars or the ivars are transient and
// we are testing transients.
// If a subclass has ivars that we are trying to test them, we get an
// exception and we know that the objects are not equal.
return false;
}
return equalsBuilder.isEquals();
}
/**
* <p>Appends the fields and values defined by the given object of the
* given Class.</p>
*
* @param lhs the left hand object
* @param rhs the right hand object
* @param clazz the class to append details of
* @param builder the builder to append to
* @param useTransients whether to test transient fields
* @param excludeFields array of field names to exclude from testing
*/
private static void reflectionAppend(
final Object lhs,
final Object rhs,
final Class<?> clazz,
final EqualsBuilder builder,
final boolean useTransients,
final String[] excludeFields) {
if (isRegistered(lhs, rhs)) {
return;
}
try {
register(lhs, rhs);
final Field[] fields = clazz.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
for (int i = 0; i < fields.length && builder.isEquals; i++) {
final Field f = fields[i];
if (false == ArrayUtil.contains(excludeFields, f.getName())
&& (f.getName().indexOf('$') == -1)
&& (useTransients || !Modifier.isTransient(f.getModifiers()))
&& (!Modifier.isStatic(f.getModifiers()))) {
try {
builder.append(f.get(lhs), f.get(rhs));
} catch (final IllegalAccessException e) {
//this can't happen. Would get a Security exception instead
//throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
}
}
}
} finally {
unregister(lhs, rhs);
}
}
//-------------------------------------------------------------------------
/**
* <p>Adds the result of {@code super.equals()} to this builder.</p>
*
* @param superEquals the result of calling {@code super.equals()}
* @return EqualsBuilder - used to chain calls.
* @since 2.0
*/
public EqualsBuilder appendSuper(final boolean superEquals) {
if (isEquals == false) {
return this;
}
isEquals = superEquals;
return this;
}
//-------------------------------------------------------------------------
/**
* <p>Test if two {@code Object}s are equal using their
* {@code equals} method.</p>
*
* @param lhs the left hand object
* @param rhs the right hand object
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final Object lhs, final Object rhs) {
if (isEquals == false) {
return this;
}
if (lhs == rhs) {
return this;
}
if (lhs == null || rhs == null) {
return setEquals(false);
}
if (ArrayUtil.isArray(lhs)) {
// 判断数组的equals
return setEquals(ArrayUtil.equals(lhs, rhs));
}
// The simple case, not an array, just test the element
return setEquals(lhs.equals(rhs));
}
/**
* <p>
* Test if two {@code long} s are equal.
* </p>
*
* @param lhs the left hand {@code long}
* @param rhs the right hand {@code long}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final long lhs, final long rhs) {
if (isEquals == false) {
return this;
}
isEquals = (lhs == rhs);
return this;
}
/**
* <p>Test if two {@code int}s are equal.</p>
*
* @param lhs the left hand {@code int}
* @param rhs the right hand {@code int}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final int lhs, final int rhs) {
if (isEquals == false) {
return this;
}
isEquals = (lhs == rhs);
return this;
}
/**
* <p>Test if two {@code short}s are equal.</p>
*
* @param lhs the left hand {@code short}
* @param rhs the right hand {@code short}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final short lhs, final short rhs) {
if (isEquals == false) {
return this;
}
isEquals = (lhs == rhs);
return this;
}
/**
* <p>Test if two {@code char}s are equal.</p>
*
* @param lhs the left hand {@code char}
* @param rhs the right hand {@code char}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final char lhs, final char rhs) {
if (isEquals == false) {
return this;
}
isEquals = (lhs == rhs);
return this;
}
/**
* <p>Test if two {@code byte}s are equal.</p>
*
* @param lhs the left hand {@code byte}
* @param rhs the right hand {@code byte}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final byte lhs, final byte rhs) {
if (isEquals == false) {
return this;
}
isEquals = (lhs == rhs);
return this;
}
/**
* <p>Test if two {@code double}s are equal by testing that the
* pattern of bits returned by {@code doubleToLong} are equal.</p>
*
* <p>This handles NaNs, Infinities, and {@code -0.0}.</p>
*
* <p>It is compatible with the hash code generated by
* {@code HashCodeBuilder}.</p>
*
* @param lhs the left hand {@code double}
* @param rhs the right hand {@code double}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final double lhs, final double rhs) {
if (isEquals == false) {
return this;
}
return append(Double.doubleToLongBits(lhs), Double.doubleToLongBits(rhs));
}
/**
* <p>Test if two {@code float}s are equal byt testing that the
* pattern of bits returned by doubleToLong are equal.</p>
*
* <p>This handles NaNs, Infinities, and {@code -0.0}.</p>
*
* <p>It is compatible with the hash code generated by
* {@code HashCodeBuilder}.</p>
*
* @param lhs the left hand {@code float}
* @param rhs the right hand {@code float}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final float lhs, final float rhs) {
if (isEquals == false) {
return this;
}
return append(Float.floatToIntBits(lhs), Float.floatToIntBits(rhs));
}
/**
* <p>Test if two {@code booleans}s are equal.</p>
*
* @param lhs the left hand {@code boolean}
* @param rhs the right hand {@code boolean}
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(final boolean lhs, final boolean rhs) {
if (isEquals == false) {
return this;
}
isEquals = (lhs == rhs);
return this;
}
/**
* <p>Returns {@code true} if the fields that have been checked
* are all equal.</p>
*
* @return boolean
*/
public boolean isEquals() {
return this.isEquals;
}
/**
* <p>Returns {@code true} if the fields that have been checked
* are all equal.</p>
*
* @return {@code true} if all of the fields that have been checked
* are equal, {@code false} otherwise.
* @since 3.0
*/
@Override
public Boolean build() {
return isEquals();
}
/**
* Sets the {@code isEquals} value.
*
* @param isEquals The value to set.
* @return this
*/
protected EqualsBuilder setEquals(boolean isEquals) {
this.isEquals = isEquals;
return this;
}
/**
* Reset the EqualsBuilder so you can use the same object again
*
* @since 2.5
*/
public void reset() {
this.isEquals = true;
}
}

View File

@ -1,958 +0,0 @@
package cn.hutool.core.builder;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
/**
* <p>
* Assists in implementing {@link Object#hashCode()} methods.
* </p>
*
* <p>
* This class enables a good <code>hashCode</code> method to be built for any class. It follows the rules laid out in
* the book <a href="http://www.oracle.com/technetwork/java/effectivejava-136174.html">Effective Java</a> by Joshua Bloch. Writing a
* good <code>hashCode</code> method is actually quite difficult. This class aims to simplify the process.
* </p>
*
* <p>
* The following is the approach taken. When appending a data field, the current total is multiplied by the
* multiplier then a relevant value
* for that data type is added. For example, if the current hashCode is 17, and the multiplier is 37, then
* appending the integer 45 will create a hashcode of 674, namely 17 * 37 + 45.
* </p>
*
* <p>
* All relevant fields from the object should be included in the <code>hashCode</code> method. Derived fields may be
* excluded. In general, any field used in the <code>equals</code> method must be used in the <code>hashCode</code>
* method.
* </p>
*
* <p>
* To use this class write code as follows:
* </p>
*
* <pre>
* public class Person {
* String name;
* int age;
* boolean smoker;
* ...
*
* public int hashCode() {
* // you pick a hard-coded, randomly chosen, non-zero, odd number
* // ideally different for each class
* return new HashCodeBuilder(17, 37).
* append(name).
* append(age).
* append(smoker).
* toHashCode();
* }
* }
* </pre>
*
* <p>
* If required, the superclass <code>hashCode()</code> can be added using {@link #appendSuper}.
* </p>
*
* <p>
* Alternatively, there is a method that uses reflection to determine the fields to test. Because these fields are
* usually private, the method, <code>reflectionHashCode</code>, uses <code>AccessibleObject.setAccessible</code>
* to change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions
* are set up correctly. It is also slower than testing explicitly.
* </p>
*
* <p>
* A typical invocation for this method would look like:
* </p>
*
* <pre>
* public int hashCode() {
* return HashCodeBuilder.reflectionHashCode(this);
* }
* </pre>
*
* TODO 待整理
* 来自于Apache-Commons-Lang3
* @author loolyApache-Commons
* @since 4.2.2
*/
public class HashCodeBuilder implements Builder<Integer> {
private static final long serialVersionUID = 1L;
/**
* The default initial value to use in reflection hash code building.
*/
private static final int DEFAULT_INITIAL_VALUE = 17;
/**
* The default multipler value to use in reflection hash code building.
*/
private static final int DEFAULT_MULTIPLIER_VALUE = 37;
/**
* <p>
* A registry of objects used by reflection methods to detect cyclical object references and avoid infinite loops.
* </p>
*
* @since 2.3
*/
private static final ThreadLocal<Set<IDKey>> REGISTRY = new ThreadLocal<>();
/*
* NOTE: we cannot store the actual objects in a HashSet, as that would use the very hashCode()
* we are in the process of calculating.
*
* So we generate a one-to-one mapping from the original object to a new object.
*
* Now HashSet uses equals() to determine if two elements with the same hashcode really
* are equal, so we also need to ensure that the replacement objects are only equal
* if the original objects are identical.
*
* The original implementation (2.4 and before) used the System.indentityHashCode()
* method - however this is not guaranteed to generate unique ids (e.g. LANG-459)
*
* We now use the IDKey helper class (adapted from org.apache.axis.utils.IDKey)
* to disambiguate the duplicate ids.
*/
/**
* <p>
* Returns the registry of objects being traversed by the reflection methods in the current thread.
* </p>
*
* @return Set the registry of objects being traversed
* @since 2.3
*/
private static Set<IDKey> getRegistry() {
return REGISTRY.get();
}
/**
* <p>
* Returns <code>true</code> if the registry contains the given object. Used by the reflection methods to avoid
* infinite loops.
* </p>
*
* @param value
* The object to lookup in the registry.
* @return boolean <code>true</code> if the registry contains the given object.
* @since 2.3
*/
private static boolean isRegistered(final Object value) {
final Set<IDKey> registry = getRegistry();
return registry != null && registry.contains(new IDKey(value));
}
/**
* <p>
* Appends the fields and values defined by the given object of the given <code>Class</code>.
* </p>
*
* @param object
* the object to append details of
* @param clazz
* the class to append details of
* @param builder
* the builder to append to
* @param useTransients
* whether to use transient fields
* @param excludeFields
* Collection of String field names to exclude from use in calculation of hash code
*/
private static void reflectionAppend(final Object object, final Class<?> clazz, final HashCodeBuilder builder, final boolean useTransients,
final String[] excludeFields) {
if (isRegistered(object)) {
return;
}
try {
register(object);
final Field[] fields = clazz.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
for (final Field field : fields) {
if (false == ArrayUtil.contains(excludeFields, field.getName())
&& (field.getName().indexOf('$') == -1)
&& (useTransients || !Modifier.isTransient(field.getModifiers()))
&& (!Modifier.isStatic(field.getModifiers()))) {
try {
final Object fieldValue = field.get(object);
builder.append(fieldValue);
} catch (final IllegalAccessException e) {
// this can't happen. Would get a Security exception instead
// throw a runtime exception in case the impossible happens.
throw new InternalError("Unexpected IllegalAccessException");
}
}
}
} finally {
unregister(object);
}
}
/**
* <p>
* Uses reflection to build a valid hash code from the fields of {@code object}.
* </p>
*
* <p>
* It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
* throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
* also not as efficient as testing explicitly.
* </p>
*
* <p>
* Transient members will be not be used, as they are likely derived fields, and not part of the value of the
* <code>Object</code>.
* </p>
*
* <p>
* Static fields will not be tested. Superclass fields will be included.
* </p>
*
* <p>
* Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
* however this is not vital. Prime numbers are preferred, especially for the multiplier.
* </p>
*
* @param initialNonZeroOddNumber
* a non-zero, odd number used as the initial value. This will be the returned
* value if no fields are found to include in the hash code
* @param multiplierNonZeroOddNumber
* a non-zero, odd number used as the multiplier
* @param object
* the Object to create a <code>hashCode</code> for
* @return int hash code
* @throws IllegalArgumentException
* if the Object is <code>null</code>
* @throws IllegalArgumentException
* if the number is zero or even
*/
public static int reflectionHashCode(final int initialNonZeroOddNumber, final int multiplierNonZeroOddNumber, final Object object) {
return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null);
}
/**
* <p>
* Uses reflection to build a valid hash code from the fields of {@code object}.
* </p>
*
* <p>
* It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
* throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
* also not as efficient as testing explicitly.
* </p>
*
* <p>
* If the TestTransients parameter is set to <code>true</code>, transient members will be tested, otherwise they
* are ignored, as they are likely derived fields, and not part of the value of the <code>Object</code>.
* </p>
*
* <p>
* Static fields will not be tested. Superclass fields will be included.
* </p>
*
* <p>
* Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
* however this is not vital. Prime numbers are preferred, especially for the multiplier.
* </p>
*
* @param initialNonZeroOddNumber
* a non-zero, odd number used as the initial value. This will be the returned
* value if no fields are found to include in the hash code
* @param multiplierNonZeroOddNumber
* a non-zero, odd number used as the multiplier
* @param object
* the Object to create a <code>hashCode</code> for
* @param testTransients
* whether to include transient fields
* @return int hash code
* @throws IllegalArgumentException
* if the Object is <code>null</code>
* @throws IllegalArgumentException
* if the number is zero or even
*/
public static int reflectionHashCode(final int initialNonZeroOddNumber, final int multiplierNonZeroOddNumber, final Object object,
final boolean testTransients) {
return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null);
}
/**
* <p>
* Uses reflection to build a valid hash code from the fields of {@code object}.
* </p>
*
* <p>
* It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
* throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
* also not as efficient as testing explicitly.
* </p>
*
* <p>
* If the TestTransients parameter is set to <code>true</code>, transient members will be tested, otherwise they
* are ignored, as they are likely derived fields, and not part of the value of the <code>Object</code>.
* </p>
*
* <p>
* Static fields will not be included. Superclass fields will be included up to and including the specified
* superclass. A null superclass is treated as java.lang.Object.
* </p>
*
* <p>
* Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
* however this is not vital. Prime numbers are preferred, especially for the multiplier.
* </p>
*
* @param <T>
* the type of the object involved
* @param initialNonZeroOddNumber
* a non-zero, odd number used as the initial value. This will be the returned
* value if no fields are found to include in the hash code
* @param multiplierNonZeroOddNumber
* a non-zero, odd number used as the multiplier
* @param object
* the Object to create a <code>hashCode</code> for
* @param testTransients
* whether to include transient fields
* @param reflectUpToClass
* the superclass to reflect up to (inclusive), may be <code>null</code>
* @param excludeFields
* array of field names to exclude from use in calculation of hash code
* @return int hash code
* @throws IllegalArgumentException
* if the Object is <code>null</code>
* @throws IllegalArgumentException
* if the number is zero or even
* @since 2.0
*/
public static <T> int reflectionHashCode(final int initialNonZeroOddNumber, final int multiplierNonZeroOddNumber, final T object,
final boolean testTransients, final Class<? super T> reflectUpToClass, final String... excludeFields) {
if (object == null) {
throw new IllegalArgumentException("The object to build a hash code for must not be null");
}
final HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber);
Class<?> clazz = object.getClass();
reflectionAppend(object, clazz, builder, testTransients, excludeFields);
while (clazz.getSuperclass() != null && clazz != reflectUpToClass) {
clazz = clazz.getSuperclass();
reflectionAppend(object, clazz, builder, testTransients, excludeFields);
}
return builder.toHashCode();
}
/**
* <p>
* Uses reflection to build a valid hash code from the fields of {@code object}.
* </p>
*
* <p>
* This constructor uses two hard coded choices for the constants needed to build a hash code.
* </p>
*
* <p>
* It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
* throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
* also not as efficient as testing explicitly.
* </p>
*
* <P>
* If the TestTransients parameter is set to <code>true</code>, transient members will be tested, otherwise they
* are ignored, as they are likely derived fields, and not part of the value of the <code>Object</code>.
* </p>
*
* <p>
* Static fields will not be tested. Superclass fields will be included. If no fields are found to include
* in the hash code, the result of this method will be constant.
* </p>
*
* @param object
* the Object to create a <code>hashCode</code> for
* @param testTransients
* whether to include transient fields
* @return int hash code
* @throws IllegalArgumentException
* if the object is <code>null</code>
*/
public static int reflectionHashCode(final Object object, final boolean testTransients) {
return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object,
testTransients, null);
}
/**
* <p>
* Uses reflection to build a valid hash code from the fields of {@code object}.
* </p>
*
* <p>
* This constructor uses two hard coded choices for the constants needed to build a hash code.
* </p>
*
* <p>
* It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
* throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
* also not as efficient as testing explicitly.
* </p>
*
* <p>
* Transient members will be not be used, as they are likely derived fields, and not part of the value of the
* <code>Object</code>.
* </p>
*
* <p>
* Static fields will not be tested. Superclass fields will be included. If no fields are found to include
* in the hash code, the result of this method will be constant.
* </p>
*
* @param object
* the Object to create a <code>hashCode</code> for
* @param excludeFields
* Collection of String field names to exclude from use in calculation of hash code
* @return int hash code
* @throws IllegalArgumentException
* if the object is <code>null</code>
*/
public static int reflectionHashCode(final Object object, final Collection<String> excludeFields) {
return reflectionHashCode(object, ArrayUtil.toArray(excludeFields, String.class));
}
// -------------------------------------------------------------------------
/**
* <p>
* Uses reflection to build a valid hash code from the fields of {@code object}.
* </p>
*
* <p>
* This constructor uses two hard coded choices for the constants needed to build a hash code.
* </p>
*
* <p>
* It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
* throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
* also not as efficient as testing explicitly.
* </p>
*
* <p>
* Transient members will be not be used, as they are likely derived fields, and not part of the value of the
* <code>Object</code>.
* </p>
*
* <p>
* Static fields will not be tested. Superclass fields will be included. If no fields are found to include
* in the hash code, the result of this method will be constant.
* </p>
*
* @param object
* the Object to create a <code>hashCode</code> for
* @param excludeFields
* array of field names to exclude from use in calculation of hash code
* @return int hash code
* @throws IllegalArgumentException
* if the object is <code>null</code>
*/
public static int reflectionHashCode(final Object object, final String... excludeFields) {
return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, false,
null, excludeFields);
}
/**
* <p>
* Registers the given object. Used by the reflection methods to avoid infinite loops.
* </p>
*
* @param value
* The object to register.
*/
static void register(final Object value) {
synchronized (HashCodeBuilder.class) {
if (getRegistry() == null) {
REGISTRY.set(new HashSet<IDKey>());
}
}
getRegistry().add(new IDKey(value));
}
/**
* <p>
* Unregisters the given object.
* </p>
*
* <p>
* Used by the reflection methods to avoid infinite loops.
*
* @param value
* The object to unregister.
* @since 2.3
*/
static void unregister(final Object value) {
Set<IDKey> registry = getRegistry();
if (registry != null) {
registry.remove(new IDKey(value));
synchronized (HashCodeBuilder.class) {
//read again
registry = getRegistry();
if (registry != null && registry.isEmpty()) {
REGISTRY.remove();
}
}
}
}
/**
* Constant to use in building the hashCode.
*/
private final int iConstant;
/**
* Running total of the hashCode.
*/
private int iTotal;
/**
* <p>
* Uses two hard coded choices for the constants needed to build a <code>hashCode</code>.
* </p>
*/
public HashCodeBuilder() {
iConstant = 37;
iTotal = 17;
}
/**
* <p>
* Two randomly chosen, odd numbers must be passed in. Ideally these should be different for each class,
* however this is not vital.
* </p>
*
* <p>
* Prime numbers are preferred, especially for the multiplier.
* </p>
*
* @param initialOddNumber
* an odd number used as the initial value
* @param multiplierOddNumber
* an odd number used as the multiplier
* @throws IllegalArgumentException
* if the number is even
*/
public HashCodeBuilder(final int initialOddNumber, final int multiplierOddNumber) {
Assert.isTrue(initialOddNumber % 2 != 0, "HashCodeBuilder requires an odd initial value");
Assert.isTrue(multiplierOddNumber % 2 != 0, "HashCodeBuilder requires an odd multiplier");
iConstant = multiplierOddNumber;
iTotal = initialOddNumber;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>boolean</code>.
* </p>
* <p>
* This adds <code>1</code> when true, and <code>0</code> when false to the <code>hashCode</code>.
* </p>
* <p>
* This is in contrast to the standard <code>java.lang.Boolean.hashCode</code> handling, which computes
* a <code>hashCode</code> value of <code>1231</code> for <code>java.lang.Boolean</code> instances
* that represent <code>true</code> or <code>1237</code> for <code>java.lang.Boolean</code> instances
* that represent <code>false</code>.
* </p>
* <p>
* This is in accordance with the <i>Effective Java</i> design.
* </p>
*
* @param value
* the boolean to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final boolean value) {
iTotal = iTotal * iConstant + (value ? 0 : 1);
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>boolean</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final boolean[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final boolean element : array) {
append(element);
}
}
return this;
}
// -------------------------------------------------------------------------
/**
* <p>
* Append a <code>hashCode</code> for a <code>byte</code>.
* </p>
*
* @param value
* the byte to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final byte value) {
iTotal = iTotal * iConstant + value;
return this;
}
// -------------------------------------------------------------------------
/**
* <p>
* Append a <code>hashCode</code> for a <code>byte</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final byte[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final byte element : array) {
append(element);
}
}
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>char</code>.
* </p>
*
* @param value
* the char to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final char value) {
iTotal = iTotal * iConstant + value;
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>char</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final char[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final char element : array) {
append(element);
}
}
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>double</code>.
* </p>
*
* @param value
* the double to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final double value) {
return append(Double.doubleToLongBits(value));
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>double</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final double[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final double element : array) {
append(element);
}
}
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>float</code>.
* </p>
*
* @param value
* the float to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final float value) {
iTotal = iTotal * iConstant + Float.floatToIntBits(value);
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>float</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final float[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final float element : array) {
append(element);
}
}
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for an <code>int</code>.
* </p>
*
* @param value
* the int to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final int value) {
iTotal = iTotal * iConstant + value;
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for an <code>int</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final int[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final int element : array) {
append(element);
}
}
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>long</code>.
* </p>
*
* @param value
* the long to add to the <code>hashCode</code>
* @return this
*/
// NOTE: This method uses >> and not >>> as Effective Java and
// Long.hashCode do. Ideally we should switch to >>> at
// some stage. There are backwards compat issues, so
// that will have to wait for the time being. cf LANG-342.
public HashCodeBuilder append(final long value) {
iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32)));
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>long</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final long[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final long element : array) {
append(element);
}
}
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for an <code>Object</code>.
* </p>
*
* @param object
* the Object to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final Object object) {
if (object == null) {
iTotal = iTotal * iConstant;
} else {
if(object.getClass().isArray()) {
// 'Switch' on type of array, to dispatch to the correct handler
// This handles multi dimensional arrays
if (object instanceof long[]) {
append((long[]) object);
} else if (object instanceof int[]) {
append((int[]) object);
} else if (object instanceof short[]) {
append((short[]) object);
} else if (object instanceof char[]) {
append((char[]) object);
} else if (object instanceof byte[]) {
append((byte[]) object);
} else if (object instanceof double[]) {
append((double[]) object);
} else if (object instanceof float[]) {
append((float[]) object);
} else if (object instanceof boolean[]) {
append((boolean[]) object);
} else {
// Not an array of primitives
append((Object[]) object);
}
} else {
iTotal = iTotal * iConstant + object.hashCode();
}
}
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for an <code>Object</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final Object[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final Object element : array) {
append(element);
}
}
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>short</code>.
* </p>
*
* @param value
* the short to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final short value) {
iTotal = iTotal * iConstant + value;
return this;
}
/**
* <p>
* Append a <code>hashCode</code> for a <code>short</code> array.
* </p>
*
* @param array
* the array to add to the <code>hashCode</code>
* @return this
*/
public HashCodeBuilder append(final short[] array) {
if (array == null) {
iTotal = iTotal * iConstant;
} else {
for (final short element : array) {
append(element);
}
}
return this;
}
/**
* <p>
* Adds the result of super.hashCode() to this builder.
* </p>
*
* @param superHashCode
* the result of calling <code>super.hashCode()</code>
* @return this HashCodeBuilder, used to chain calls.
* @since 2.0
*/
public HashCodeBuilder appendSuper(final int superHashCode) {
iTotal = iTotal * iConstant + superHashCode;
return this;
}
/**
* <p>
* Return the computed <code>hashCode</code>.
* </p>
*
* @return <code>hashCode</code> based on the fields appended
*/
public int toHashCode() {
return iTotal;
}
/**
* Returns the computed <code>hashCode</code>.
*
* @return <code>hashCode</code> based on the fields appended
*
* @since 3.0
*/
@Override
public Integer build() {
return toHashCode();
}
/**
* <p>
* The computed <code>hashCode</code> from toHashCode() is returned due to the likelihood
* of bugs in mis-calling toHashCode() and the unlikeliness of it mattering what the hashCode for
* HashCodeBuilder itself is.</p>
*
* @return <code>hashCode</code> based on the fields appended
* @since 2.5
*/
@Override
public int hashCode() {
return toHashCode();
}
}

View File

@ -1,61 +0,0 @@
package cn.hutool.core.builder;
import java.io.Serializable;
/**
* 包装唯一键System.identityHashCode()使对象只有和自己 equals
*
* 此对象用于消除小概率下System.identityHashCode()产生的ID重复问题
*
* 来自于Apache-Commons-Lang3
* @author loolyApache-Commons
* @since 4.2.2
*/
final class IDKey implements Serializable{
private static final long serialVersionUID = 1L;
private final Object value;
private final int id;
/**
* 构造
*
* @param obj 计算唯一ID的对象
*/
public IDKey(final Object obj) {
id = System.identityHashCode(obj);
// There have been some cases (LANG-459) that return the
// same identity hash code for different objects. So
// the value is also added to disambiguate these cases.
value = obj;
}
/**
* returns hashcode - i.e. the system identity hashcode.
*
* @return the hashcode
*/
@Override
public int hashCode() {
return id;
}
/**
* checks if instances are equal
*
* @param other The other object to compare to
* @return if the instances are for the same object
*/
@Override
public boolean equals(final Object other) {
if (!(other instanceof IDKey)) {
return false;
}
final IDKey idKey = (IDKey) other;
if (id != idKey.id) {
return false;
}
// Note that identity equals is used.
return value == idKey.value;
}
}

View File

@ -1,7 +1,7 @@
package cn.hutool.core.cache;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;

0
hutool-core/src/main/java/cn/hutool/core/cache/SimpleCache.java vendored Executable file → Normal file
View File

View File

@ -1,7 +1,7 @@
package cn.hutool.core.clone;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 克隆异常

View File

@ -1,7 +1,7 @@
package cn.hutool.core.clone;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.reflect.ReflectUtil;
/**
* 克隆默认实现接口用于实现返回指定泛型类型的克隆方法

View File

@ -1,7 +1,7 @@
package cn.hutool.core.codec;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* Base16Hex编码解码器<br>

View File

@ -1,7 +1,7 @@
package cn.hutool.core.codec;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.nio.charset.Charset;
@ -37,7 +37,7 @@ public class Base32 {
* @return 被加密后的字符串
*/
public static String encode(String source) {
return encode(source, CharsetUtil.CHARSET_UTF_8);
return encode(source, CharsetUtil.UTF_8);
}
/**
@ -68,7 +68,7 @@ public class Base32 {
* @return 被加密后的字符串
*/
public static String encodeHex(String source) {
return encodeHex(source, CharsetUtil.CHARSET_UTF_8);
return encodeHex(source, CharsetUtil.UTF_8);
}
/**
@ -101,7 +101,7 @@ public class Base32 {
* @return 被加密后的字符串
*/
public static String decodeStr(String source) {
return decodeStr(source, CharsetUtil.CHARSET_UTF_8);
return decodeStr(source, CharsetUtil.UTF_8);
}
/**
@ -132,7 +132,7 @@ public class Base32 {
* @return 被加密后的字符串
*/
public static String decodeStrHex(String source) {
return decodeStrHex(source, CharsetUtil.CHARSET_UTF_8);
return decodeStrHex(source, CharsetUtil.UTF_8);
}
/**

View File

@ -1,6 +1,6 @@
package cn.hutool.core.codec;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.util.Arrays;

View File

@ -3,7 +3,7 @@ package cn.hutool.core.codec;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.File;
import java.io.InputStream;
@ -18,7 +18,7 @@ import java.nio.charset.Charset;
*/
public class Base62 {
private static final Charset DEFAULT_CHARSET = CharsetUtil.CHARSET_UTF_8;
private static final Charset DEFAULT_CHARSET = CharsetUtil.UTF_8;
// -------------------------------------------------------------------- encode
/**
@ -131,7 +131,7 @@ public class Base62 {
* @return 被加密后的字符串
*/
public static String decodeStrGbk(CharSequence source) {
return decodeStr(source, CharsetUtil.CHARSET_GBK);
return decodeStr(source, CharsetUtil.GBK);
}
/**

View File

@ -3,7 +3,7 @@ package cn.hutool.core.codec;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.File;
import java.io.InputStream;
@ -19,7 +19,7 @@ import java.nio.charset.Charset;
*/
public class Base64 {
private static final Charset DEFAULT_CHARSET = CharsetUtil.CHARSET_UTF_8;
private static final Charset DEFAULT_CHARSET = CharsetUtil.UTF_8;
// -------------------------------------------------------------------- encode
/**
@ -215,7 +215,7 @@ public class Base64 {
* @since 4.3.2
*/
public static String decodeStrGbk(CharSequence source) {
return Base64Decoder.decodeStr(source, CharsetUtil.CHARSET_GBK);
return Base64Decoder.decodeStr(source, CharsetUtil.GBK);
}
/**

View File

@ -3,7 +3,7 @@ package cn.hutool.core.codec;
import cn.hutool.core.lang.mutable.MutableInt;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.nio.charset.Charset;
@ -15,7 +15,7 @@ import java.nio.charset.Charset;
*/
public class Base64Decoder {
private static final Charset DEFAULT_CHARSET = CharsetUtil.CHARSET_UTF_8;
private static final Charset DEFAULT_CHARSET = CharsetUtil.UTF_8;
private static final byte PADDING = -2;
/** Base64解码表共128位-1表示非base64字符-2表示padding */

View File

@ -1,7 +1,7 @@
package cn.hutool.core.codec;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.nio.charset.Charset;
@ -14,7 +14,7 @@ import java.nio.charset.Charset;
*/
public class Base64Encoder {
private static final Charset DEFAULT_CHARSET = CharsetUtil.CHARSET_UTF_8;
private static final Charset DEFAULT_CHARSET = CharsetUtil.UTF_8;
/**
* 标准编码表
*/

View File

@ -1,10 +1,9 @@
package cn.hutool.core.codec;
import cn.hutool.core.codec.Base16Codec;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.awt.Color;
import java.math.BigInteger;
@ -15,7 +14,7 @@ import java.nio.charset.Charset;
* 例如十进制数57在二进制写作111001在16进制写作39<br>
* 像java,c这样的语言为了区分十六进制和十进制数值,会在十六进制数的前面加上 0x,比如0x20是十进制的32,而不是十进制的20<br>
* <p>
* 参考https://my.oschina.net/xinxingegeya/blog/287476
* 参考<a href="https://my.oschina.net/xinxingegeya/blog/287476">https://my.oschina.net/xinxingegeya/blog/287476</a>
*
* @author Looly
*/
@ -106,7 +105,7 @@ public class HexUtil {
* @return 十六进制String
*/
public static String encodeHexStr(String data) {
return encodeHexStr(data, CharsetUtil.CHARSET_UTF_8);
return encodeHexStr(data, CharsetUtil.UTF_8);
}
/**
@ -129,7 +128,7 @@ public class HexUtil {
* @return 字符串
*/
public static String decodeHexStr(String hexStr) {
return decodeHexStr(hexStr, CharsetUtil.CHARSET_UTF_8);
return decodeHexStr(hexStr, CharsetUtil.UTF_8);
}
/**

View File

@ -6,7 +6,7 @@ import java.util.Map;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 莫尔斯电码的编码和解码实现<br>

View File

@ -2,7 +2,7 @@ package cn.hutool.core.codec;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

View File

@ -2,7 +2,7 @@ package cn.hutool.core.codec;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* Punycode是一个根据RFC 3492标准而制定的编码系统主要用于把域名从地方语言所采用的Unicode编码转换成为可用于DNS系统的编码

View File

@ -16,9 +16,9 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.TypeUtil;
import java.io.Serializable;
@ -368,7 +368,7 @@ public class CollUtil {
* @return 单差集
*/
public static <T> Collection<T> subtract(Collection<T> coll1, Collection<T> coll2) {
Collection<T> result = ObjectUtil.clone(coll1);
Collection<T> result = ObjUtil.clone(coll1);
if (null == result) {
result = CollUtil.create(coll1.getClass());
result.addAll(coll1);
@ -1492,12 +1492,12 @@ public class CollUtil {
if (t instanceof Map) {
final Map<?, ?> map = (Map<?, ?>) t;
final Object value = map.get(fieldName);
return ObjectUtil.equal(value, fieldValue);
return ObjUtil.equal(value, fieldValue);
}
// 普通Bean
final Object value = ReflectUtil.getFieldValue(t, fieldName);
return ObjectUtil.equal(value, fieldValue);
return ObjUtil.equal(value, fieldValue);
});
}

View File

@ -9,8 +9,8 @@ import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrJoiner;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.reflect.ReflectUtil;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@ -422,7 +422,7 @@ public class IterUtil {
if (null == resultMap) {
resultMap = MapUtil.newHashMap();
}
if (ObjectUtil.isNull(iterable)) {
if (ObjUtil.isNull(iterable)) {
return resultMap;
}
@ -480,7 +480,7 @@ public class IterUtil {
if (null == resultMap) {
resultMap = MapUtil.newHashMap();
}
if (ObjectUtil.isNull(iterable)) {
if (ObjUtil.isNull(iterable)) {
return resultMap;
}
@ -964,7 +964,7 @@ public class IterUtil {
* @since 5.8.0
*/
public static <E> String toStr(final Iterator<E> iterator) {
return toStr(iterator, ObjectUtil::toString);
return toStr(iterator, ObjUtil::toString);
}
/**

View File

@ -4,7 +4,7 @@ import cn.hutool.core.comparator.PinyinComparator;
import cn.hutool.core.comparator.PropertyComparator;
import cn.hutool.core.lang.func.Matcher;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.PageUtil;
import java.util.ArrayList;
@ -365,7 +365,7 @@ public class ListUtil {
* @since 4.0.6
*/
public static <T> List<T> reverseNew(List<T> list) {
List<T> list2 = ObjectUtil.clone(list);
List<T> list2 = ObjUtil.clone(list);
if (null == list2) {
// 不支持clone
list2 = new ArrayList<>(list);

View File

@ -1,7 +1,7 @@
package cn.hutool.core.collection;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import java.io.Serializable;
import java.util.AbstractSet;
@ -167,7 +167,7 @@ public class UniqueKeySet<K, V> extends AbstractSet<V> implements Serializable {
public UniqueKeySet<K, V> clone() {
try {
UniqueKeySet<K, V> newSet = (UniqueKeySet<K, V>) super.clone();
newSet.map = ObjectUtil.clone(this.map);
newSet.map = ObjUtil.clone(this.map);
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);

View File

@ -1,7 +1,7 @@
package cn.hutool.core.comparator;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 比较异常

View File

@ -2,8 +2,8 @@ package cn.hutool.core.comparator;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.text.StrUtil;
import java.lang.reflect.Field;

View File

@ -1,6 +1,6 @@
package cn.hutool.core.comparator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import java.util.function.Function;
@ -53,7 +53,7 @@ public class FuncComparator<T> extends NullComparator<T> {
*/
@SuppressWarnings({"rawtypes", "unchecked"})
private int compare(T o1, T o2, Comparable v1, Comparable v2) {
int result = ObjectUtil.compare(v1, v2);
int result = ObjUtil.compare(v1, v2);
if (0 == result) {
//避免TreeSet / TreeMap 过滤掉排序字段相同但是对象不相同的情况
result = CompareUtil.compare(o1, o2, this.nullGreater);

View File

@ -1,8 +1,8 @@
package cn.hutool.core.comparator;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.util.Comparator;
@ -50,7 +50,7 @@ public class VersionComparator implements Comparator<String>, Serializable {
*/
@Override
public int compare(String version1, String version2) {
if(ObjectUtil.equal(version1, version2)) {
if(ObjUtil.equal(version1, version2)) {
return 0;
}
if (version1 == null && version2 == null) {

View File

@ -1,7 +1,7 @@
package cn.hutool.core.compiler;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 编译异常

View File

@ -3,7 +3,7 @@ package cn.hutool.core.compiler;
import cn.hutool.core.io.resource.FileObjectResource;
import cn.hutool.core.lang.ResourceClassLoader;
import cn.hutool.core.util.ClassLoaderUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
@ -44,7 +44,7 @@ class JavaClassFileManager extends ForwardingJavaFileManager<JavaFileManager> {
*/
protected JavaClassFileManager(ClassLoader parent, JavaFileManager fileManager) {
super(fileManager);
this.parent = ObjectUtil.defaultIfNull(parent, ClassLoaderUtil::getClassLoader);
this.parent = ObjUtil.defaultIfNull(parent, ClassLoaderUtil::getClassLoader);
}
/**

View File

@ -2,7 +2,7 @@ package cn.hutool.core.compiler;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.core.net.URLUtil;
import javax.tools.SimpleJavaFileObject;
import java.io.ByteArrayInputStream;
@ -57,4 +57,4 @@ class JavaClassFileObject extends SimpleJavaFileObject {
return this.byteArrayOutputStream;
}
}
}

View File

@ -1,7 +1,7 @@
package cn.hutool.core.compiler;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.core.compress.ZipUtil;
import javax.tools.JavaFileObject;
import java.io.File;

View File

@ -10,8 +10,8 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ClassLoaderUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.net.URLUtil;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler.CompilationTask;
@ -89,7 +89,7 @@ public class JavaSourceCompiler {
* @param parent 父类加载器null则使用默认类加载器
*/
private JavaSourceCompiler(ClassLoader parent) {
this.parentClassLoader = ObjectUtil.defaultIfNull(parent, ClassLoaderUtil::getClassLoader);
this.parentClassLoader = ObjUtil.defaultIfNull(parent, ClassLoaderUtil::getClassLoader);
}
/**
@ -250,7 +250,7 @@ public class JavaSourceCompiler {
private Collection<JavaFileObject> getJavaFileObjectByMap(final Map<String, String> sourceCodeMap) {
if (MapUtil.isNotEmpty(sourceCodeMap)) {
return sourceCodeMap.entrySet().stream()
.map(entry -> new JavaSourceFileObject(entry.getKey(), entry.getValue(), CharsetUtil.CHARSET_UTF_8))
.map(entry -> new JavaSourceFileObject(entry.getKey(), entry.getValue(), CharsetUtil.UTF_8))
.collect(Collectors.toList());
}
return Collections.emptySet();

View File

@ -2,7 +2,7 @@ package cn.hutool.core.compiler;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.core.net.URLUtil;
import javax.tools.SimpleJavaFileObject;
import java.io.BufferedInputStream;
@ -87,4 +87,4 @@ class JavaSourceFileObject extends SimpleJavaFileObject {
}
}
}
}

View File

@ -1,6 +1,6 @@
package cn.hutool.core.compress;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.IOException;
import java.nio.file.CopyOption;

View File

@ -4,8 +4,7 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Closeable;
import java.io.File;

View File

@ -1,11 +1,6 @@
package cn.hutool.core.util;
package cn.hutool.core.compress;
import cn.hutool.core.collection.EnumerationIter;
import cn.hutool.core.compress.Deflate;
import cn.hutool.core.compress.Gzip;
import cn.hutool.core.compress.ZipCopyVisitor;
import cn.hutool.core.compress.ZipReader;
import cn.hutool.core.compress.ZipWriter;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.io.FileUtil;
@ -14,6 +9,10 @@ import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileSystemUtil;
import cn.hutool.core.io.file.PathUtil;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjUtil;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
@ -56,12 +55,12 @@ public class ZipUtil {
* 将Zip文件转换为{@link ZipFile}
*
* @param file zip文件
* @param charset 解析zip文件的编码null表示{@link CharsetUtil#CHARSET_UTF_8}
* @param charset 解析zip文件的编码null表示{@link CharsetUtil#UTF_8}
* @return {@link ZipFile}
*/
public static ZipFile toZipFile(File file, Charset charset) {
try {
return new ZipFile(file, ObjectUtil.defaultIfNull(charset, CharsetUtil.CHARSET_UTF_8));
return new ZipFile(file, ObjUtil.defaultIfNull(charset, CharsetUtil.UTF_8));
} catch (IOException e) {
throw new IORuntimeException(e);
}

View File

@ -5,8 +5,7 @@ import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Closeable;
import java.io.File;

View File

@ -3,7 +3,7 @@ package cn.hutool.core.convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.util.Map;

View File

@ -4,14 +4,14 @@ import cn.hutool.core.convert.impl.CollectionConverter;
import cn.hutool.core.convert.impl.EnumConverter;
import cn.hutool.core.convert.impl.MapConverter;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.reflect.TypeReference;
import cn.hutool.core.reflect.TypeReference;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.codec.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.lang.reflect.Type;
import java.math.BigDecimal;

View File

@ -1,7 +1,7 @@
package cn.hutool.core.convert;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 转换异常

View File

@ -35,10 +35,10 @@ import cn.hutool.core.convert.impl.URLConverter;
import cn.hutool.core.convert.impl.UUIDConverter;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.lang.reflect.TypeReference;
import cn.hutool.core.reflect.TypeReference;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.util.ServiceLoaderUtil;
import cn.hutool.core.util.TypeUtil;
@ -241,7 +241,7 @@ public class ConverterRegistry implements Serializable {
// 对于用户不指定目标类型的情况返回原值
return (T) value;
}
if (ObjectUtil.isNull(value)) {
if (ObjUtil.isNull(value)) {
return defaultValue;
}
if (TypeUtil.isUnknown(type)) {

View File

@ -3,7 +3,7 @@ package cn.hutool.core.convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 数字转中文类<br>

View File

@ -1,7 +1,7 @@
package cn.hutool.core.convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 将浮点数类型的number转换成英语的表达方式 <br>

View File

@ -6,8 +6,8 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.lang.reflect.Array;
@ -166,7 +166,7 @@ public class ArrayConverter extends AbstractConverter<Object> {
result = ByteUtil.numberToBytes((Number)value);
} else if (value instanceof Serializable && byte.class == targetComponentType) {
// 用户可能想序列化指定对象
result = ObjectUtil.serialize(value);
result = ObjUtil.serialize(value);
} else {
// everything else:
result = convertToSingleElementArray(value);

View File

@ -7,8 +7,8 @@ import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.map.MapProxy;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.util.TypeUtil;
import java.lang.reflect.Type;
@ -78,7 +78,7 @@ public class BeanConverter<T> extends AbstractConverter<T> {
return BeanCopier.create(value, ReflectUtil.newInstanceIfPossible(this.beanClass), this.beanType, this.copyOptions).copy();
} else if(value instanceof byte[]){
// 尝试反序列化
return ObjectUtil.deserialize((byte[])value);
return ObjUtil.deserialize((byte[])value);
}
throw new ConvertException("Unsupported source type: {}", value.getClass());

View File

@ -5,7 +5,7 @@ import java.util.Date;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 日期转换器

View File

@ -2,7 +2,7 @@ package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 字符转换器

View File

@ -2,7 +2,7 @@ package cn.hutool.core.convert.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Converter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.TypeUtil;
import java.lang.reflect.Type;
@ -62,7 +62,7 @@ public class CollectionConverter implements Converter<Collection<?>> {
@Override
public Collection<?> convert(Object value, Collection<?> defaultValue) throws IllegalArgumentException {
final Collection<?> result = convertInternal(value);
return ObjectUtil.defaultIfNull(result, defaultValue);
return ObjUtil.defaultIfNull(result, defaultValue);
}
/**

View File

@ -4,7 +4,7 @@ import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;

View File

@ -7,8 +7,8 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ModifierUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.reflect.ModifierUtil;
import cn.hutool.core.reflect.ReflectUtil;
import java.lang.reflect.Method;
import java.util.Arrays;

View File

@ -3,7 +3,7 @@ package cn.hutool.core.convert.impl;
import java.util.Locale;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
*

View File

@ -4,7 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.convert.ConverterRegistry;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.TypeUtil;
import java.lang.reflect.Type;

View File

@ -5,7 +5,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.math.BigDecimal;
import java.math.BigInteger;

View File

@ -3,8 +3,8 @@ package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.text.StrUtil;
import java.util.function.Function;
@ -70,17 +70,17 @@ public class PrimitiveConverter extends AbstractConverter<Object> {
*/
protected static Object convert(Object value, Class<?> primitiveClass, Function<Object, String> toStringFunc) {
if (byte.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Byte.class, toStringFunc), 0);
return ObjUtil.defaultIfNull(NumberConverter.convert(value, Byte.class, toStringFunc), 0);
} else if (short.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Short.class, toStringFunc), 0);
return ObjUtil.defaultIfNull(NumberConverter.convert(value, Short.class, toStringFunc), 0);
} else if (int.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Integer.class, toStringFunc), 0);
return ObjUtil.defaultIfNull(NumberConverter.convert(value, Integer.class, toStringFunc), 0);
} else if (long.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Long.class, toStringFunc), 0);
return ObjUtil.defaultIfNull(NumberConverter.convert(value, Long.class, toStringFunc), 0);
} else if (float.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Float.class, toStringFunc), 0);
return ObjUtil.defaultIfNull(NumberConverter.convert(value, Float.class, toStringFunc), 0);
} else if (double.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Double.class, toStringFunc), 0);
return ObjUtil.defaultIfNull(NumberConverter.convert(value, Double.class, toStringFunc), 0);
} else if (char.class == primitiveClass) {
return Convert.convert(Character.class, value);
} else if (boolean.class == primitiveClass) {

View File

@ -2,7 +2,7 @@ package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.convert.ConverterRegistry;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.TypeUtil;
import java.lang.ref.Reference;

View File

@ -4,7 +4,7 @@ import java.util.Map;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
/**
* {@link StackTraceElement} 转换器<br>
@ -26,7 +26,7 @@ public class StackTraceElementConverter extends AbstractConverter<StackTraceElem
final String fileName = MapUtil.getStr(map, "fileName");
final Integer lineNumber = MapUtil.getInt(map, "lineNumber");
return new StackTraceElement(declaringClass, methodName, fileName, ObjectUtil.defaultIfNull(lineNumber, 0));
return new StackTraceElement(declaringClass, methodName, fileName, ObjUtil.defaultIfNull(lineNumber, 0));
}
return null;
}

View File

@ -70,7 +70,7 @@ public class StringConverter extends AbstractConverter<String> {
InputStream in = null;
try {
in = blob.getBinaryStream();
return IoUtil.read(in, CharsetUtil.CHARSET_UTF_8);
return IoUtil.read(in, CharsetUtil.UTF_8);
} catch (SQLException e) {
throw new ConvertException(e);
} finally {

View File

@ -3,8 +3,8 @@ package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.text.StrUtil;
import java.time.Instant;
import java.time.LocalDate;
@ -227,7 +227,7 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
return instant;
}
zoneId = ObjectUtil.defaultIfNull(zoneId, ZoneId::systemDefault);
zoneId = ObjUtil.defaultIfNull(zoneId, ZoneId::systemDefault);
TemporalAccessor result = null;
if (LocalDateTime.class.equals(this.targetType)) {

View File

@ -1,6 +1,6 @@
package cn.hutool.core.date;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Serializable;

View File

@ -5,8 +5,8 @@ import cn.hutool.core.convert.NumberChineseFormatter;
import cn.hutool.core.date.format.DateParser;
import cn.hutool.core.date.format.FastDateParser;
import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.text.StrUtil;
import java.text.ParsePosition;
import java.time.Instant;
@ -719,7 +719,7 @@ public class CalendarUtil {
}
final TimeZone tz = TimeZone.getDefault();
final Locale lcl = ObjectUtil.defaultIfNull(locale, Locale.getDefault());
final Locale lcl = ObjUtil.defaultIfNull(locale, Locale.getDefault());
final ParsePosition pos = new ParsePosition(0);
final Calendar calendar = Calendar.getInstance(tz, lcl);
calendar.setLenient(lenient);

View File

@ -6,7 +6,7 @@ import cn.hutool.core.date.chinese.GanZhi;
import cn.hutool.core.date.chinese.LunarFestival;
import cn.hutool.core.date.chinese.LunarInfo;
import cn.hutool.core.date.chinese.SolarTerms;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.time.LocalDate;
import java.util.Calendar;

View File

@ -1,7 +1,7 @@
package cn.hutool.core.date;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 工具类异常

View File

@ -5,8 +5,8 @@ import cn.hutool.core.date.format.DatePrinter;
import cn.hutool.core.date.format.FastDateFormat;
import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.SystemPropsUtil;
import java.sql.Timestamp;
@ -160,7 +160,7 @@ public class DateTime extends Date {
* @since 4.1.2
*/
public DateTime(Date date, TimeZone timeZone) {
this(ObjectUtil.defaultIfNull(date, Date::new).getTime(), timeZone);
this(ObjUtil.defaultIfNull(date, Date::new).getTime(), timeZone);
}
/**
@ -233,7 +233,7 @@ public class DateTime extends Date {
*/
public DateTime(long timeMillis, TimeZone timeZone) {
super(timeMillis);
this.timeZone = ObjectUtil.defaultIfNull(timeZone, TimeZone::getDefault);
this.timeZone = ObjUtil.defaultIfNull(timeZone, TimeZone::getDefault);
}
/**
@ -347,7 +347,7 @@ public class DateTime extends Date {
//noinspection MagicConstant
cal.add(datePart.getValue(), offset);
DateTime dt = mutable ? this : ObjectUtil.clone(this);
DateTime dt = mutable ? this : ObjUtil.clone(this);
return dt.setTimeInternal(cal.getTimeInMillis());
}
@ -365,7 +365,7 @@ public class DateTime extends Date {
//noinspection MagicConstant
cal.add(datePart.getValue(), offset);
return ObjectUtil.clone(this).setTimeInternal(cal.getTimeInMillis());
return ObjUtil.clone(this).setTimeInternal(cal.getTimeInMillis());
}
// -------------------------------------------------------------------- offset end
@ -419,7 +419,7 @@ public class DateTime extends Date {
DateTime dt = this;
if (false == mutable) {
dt = ObjectUtil.clone(this);
dt = ObjUtil.clone(this);
}
return dt.setTimeInternal(calendar.getTimeInMillis());
}
@ -930,7 +930,7 @@ public class DateTime extends Date {
* @since 4.1.2
*/
public DateTime setTimeZone(TimeZone timeZone) {
this.timeZone = ObjectUtil.defaultIfNull(timeZone, TimeZone::getDefault);
this.timeZone = ObjUtil.defaultIfNull(timeZone, TimeZone::getDefault);
return this;
}

View File

@ -11,7 +11,7 @@ import cn.hutool.core.regex.PatternPool;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.regex.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

View File

@ -1,6 +1,6 @@
package cn.hutool.core.date;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import java.io.Serializable;
import java.util.Map;
@ -60,7 +60,7 @@ public class GroupTimeInterval implements Serializable {
*/
public long intervalRestart(String id) {
final long now = getTime();
return now - ObjectUtil.defaultIfNull(this.groupMap.put(id, now), now);
return now - ObjUtil.defaultIfNull(this.groupMap.put(id, now), now);
}
//----------------------------------------------------------- Interval

View File

@ -1,9 +1,9 @@
package cn.hutool.core.date;
import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.regex.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.time.DayOfWeek;
import java.time.Duration;
@ -90,7 +90,7 @@ public class LocalDateTimeUtil {
return null;
}
return LocalDateTime.ofInstant(instant, ObjectUtil.defaultIfNull(zoneId, ZoneId::systemDefault));
return LocalDateTime.ofInstant(instant, ObjUtil.defaultIfNull(zoneId, ZoneId::systemDefault));
}
/**
@ -105,7 +105,7 @@ public class LocalDateTimeUtil {
return null;
}
return of(instant, ObjectUtil.defaultIfNull(timeZone, TimeZone::getDefault).toZoneId());
return of(instant, ObjUtil.defaultIfNull(timeZone, TimeZone::getDefault).toZoneId());
}
/**

View File

@ -1,7 +1,7 @@
package cn.hutool.core.date;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.text.NumberFormat;
import java.util.ArrayList;

View File

@ -1,7 +1,7 @@
package cn.hutool.core.date;
import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.time.Instant;
import java.time.LocalDate;

View File

@ -1,6 +1,6 @@
package cn.hutool.core.date;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 计时器<br>

View File

@ -4,7 +4,7 @@ import cn.hutool.core.date.ChineseDate;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.time.LocalDate;
import java.util.Date;

View File

@ -1,6 +1,6 @@
package cn.hutool.core.exceptions;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 依赖异常

View File

@ -3,8 +3,8 @@ package cn.hutool.core.exceptions;
import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.reflect.ReflectUtil;
import cn.hutool.core.text.StrUtil;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;

View File

@ -1,6 +1,6 @@
package cn.hutool.core.exceptions;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 未初始化异常

View File

@ -1,6 +1,6 @@
package cn.hutool.core.exceptions;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 带有状态码的异常

View File

@ -1,6 +1,6 @@
package cn.hutool.core.exceptions;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 工具类异常

View File

@ -1,6 +1,6 @@
package cn.hutool.core.exceptions;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* 验证异常

View File

@ -44,7 +44,7 @@ public class BOMInputStream extends InputStream {
* @param in
*/
public BOMInputStream(InputStream in) {
this(in, CharsetUtil.UTF_8);
this(in, CharsetUtil.NAME_UTF_8);
}
/**

View File

@ -1,7 +1,7 @@
package cn.hutool.core.io;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
@ -75,7 +75,7 @@ public class BufferUtil {
* @since 4.5.0
*/
public static String readUtf8Str(ByteBuffer buffer) {
return readStr(buffer, CharsetUtil.CHARSET_UTF_8);
return readStr(buffer, CharsetUtil.UTF_8);
}
/**

View File

@ -1,7 +1,7 @@
package cn.hutool.core.io;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import java.io.IOException;
import java.io.OutputStream;
@ -117,7 +117,7 @@ public class FastByteArrayOutputStream extends OutputStream {
*/
public String toString(Charset charset) {
return new String(toByteArray(),
ObjectUtil.defaultIfNull(charset, CharsetUtil::defaultCharset));
ObjUtil.defaultIfNull(charset, CharsetUtil::defaultCharset));
}
}

View File

@ -1,6 +1,6 @@
package cn.hutool.core.io;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.File;
import java.io.FileInputStream;

View File

@ -19,9 +19,9 @@ import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.regex.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.net.URLUtil;
import cn.hutool.core.compress.ZipUtil;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@ -1927,7 +1927,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static BufferedReader getUtf8Reader(File file) throws IORuntimeException {
return getReader(file, CharsetUtil.CHARSET_UTF_8);
return getReader(file, CharsetUtil.UTF_8);
}
/**
@ -1938,7 +1938,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static BufferedReader getUtf8Reader(String path) throws IORuntimeException {
return getReader(path, CharsetUtil.CHARSET_UTF_8);
return getReader(path, CharsetUtil.UTF_8);
}
/**
@ -2000,7 +2000,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static String readUtf8String(File file) throws IORuntimeException {
return readString(file, CharsetUtil.CHARSET_UTF_8);
return readString(file, CharsetUtil.UTF_8);
}
/**
@ -2011,7 +2011,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static String readUtf8String(String path) throws IORuntimeException {
return readString(path, CharsetUtil.CHARSET_UTF_8);
return readString(path, CharsetUtil.UTF_8);
}
/**
@ -2074,7 +2074,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.1
*/
public static <T extends Collection<String>> T readUtf8Lines(String path, T collection) throws IORuntimeException {
return readLines(path, CharsetUtil.CHARSET_UTF_8, collection);
return readLines(path, CharsetUtil.UTF_8, collection);
}
/**
@ -2116,7 +2116,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.1
*/
public static <T extends Collection<String>> T readUtf8Lines(File file, T collection) throws IORuntimeException {
return readLines(file, CharsetUtil.CHARSET_UTF_8, collection);
return readLines(file, CharsetUtil.UTF_8, collection);
}
/**
@ -2157,7 +2157,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static <T extends Collection<String>> T readUtf8Lines(URL url, T collection) throws IORuntimeException {
return readLines(url, CharsetUtil.CHARSET_UTF_8, collection);
return readLines(url, CharsetUtil.UTF_8, collection);
}
/**
@ -2191,7 +2191,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static List<String> readUtf8Lines(URL url) throws IORuntimeException {
return readLines(url, CharsetUtil.CHARSET_UTF_8);
return readLines(url, CharsetUtil.UTF_8);
}
/**
@ -2215,7 +2215,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.1
*/
public static List<String> readUtf8Lines(String path) throws IORuntimeException {
return readLines(path, CharsetUtil.CHARSET_UTF_8);
return readLines(path, CharsetUtil.UTF_8);
}
/**
@ -2252,7 +2252,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.1
*/
public static List<String> readUtf8Lines(File file) throws IORuntimeException {
return readLines(file, CharsetUtil.CHARSET_UTF_8);
return readLines(file, CharsetUtil.UTF_8);
}
/**
@ -2287,7 +2287,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static void readUtf8Lines(File file, LineHandler lineHandler) throws IORuntimeException {
readLines(file, CharsetUtil.CHARSET_UTF_8, lineHandler);
readLines(file, CharsetUtil.UTF_8, lineHandler);
}
/**
@ -2315,7 +2315,7 @@ public class FileUtil extends PathUtil {
String line;
try {
while ((line = file.readLine()) != null) {
lineHandler.handle(CharsetUtil.convert(line, CharsetUtil.CHARSET_ISO_8859_1, charset));
lineHandler.handle(CharsetUtil.convert(line, CharsetUtil.ISO_8859_1, charset));
}
} catch (IOException e) {
throw new IORuntimeException(e);
@ -2355,7 +2355,7 @@ public class FileUtil extends PathUtil {
throw new IORuntimeException(e);
}
if (null != line) {
return CharsetUtil.convert(line, CharsetUtil.CHARSET_ISO_8859_1, charset);
return CharsetUtil.convert(line, CharsetUtil.ISO_8859_1, charset);
}
return null;
@ -2372,7 +2372,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.1
*/
public static <T> T loadUtf8(String path, ReaderHandler<T> readerHandler) throws IORuntimeException {
return load(path, CharsetUtil.CHARSET_UTF_8, readerHandler);
return load(path, CharsetUtil.UTF_8, readerHandler);
}
/**
@ -2416,7 +2416,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.1
*/
public static <T> T loadUtf8(File file, ReaderHandler<T> readerHandler) throws IORuntimeException {
return load(file, CharsetUtil.CHARSET_UTF_8, readerHandler);
return load(file, CharsetUtil.UTF_8, readerHandler);
}
/**
@ -2546,7 +2546,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static File writeUtf8String(String content, String path) throws IORuntimeException {
return writeString(content, path, CharsetUtil.CHARSET_UTF_8);
return writeString(content, path, CharsetUtil.UTF_8);
}
/**
@ -2558,7 +2558,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常
*/
public static File writeUtf8String(String content, File file) throws IORuntimeException {
return writeString(content, file, CharsetUtil.CHARSET_UTF_8);
return writeString(content, file, CharsetUtil.UTF_8);
}
/**
@ -2623,7 +2623,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.2
*/
public static File appendUtf8String(String content, String path) throws IORuntimeException {
return appendString(content, path, CharsetUtil.CHARSET_UTF_8);
return appendString(content, path, CharsetUtil.UTF_8);
}
/**
@ -2662,7 +2662,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.2
*/
public static File appendUtf8String(String content, File file) throws IORuntimeException {
return appendString(content, file, CharsetUtil.CHARSET_UTF_8);
return appendString(content, file, CharsetUtil.UTF_8);
}
/**
@ -2702,7 +2702,7 @@ public class FileUtil extends PathUtil {
* @since 3.2.0
*/
public static <T> File writeUtf8Lines(Collection<T> list, String path) throws IORuntimeException {
return writeLines(list, path, CharsetUtil.CHARSET_UTF_8);
return writeLines(list, path, CharsetUtil.UTF_8);
}
/**
@ -2716,7 +2716,7 @@ public class FileUtil extends PathUtil {
* @since 3.2.0
*/
public static <T> File writeUtf8Lines(Collection<T> list, File file) throws IORuntimeException {
return writeLines(list, file, CharsetUtil.CHARSET_UTF_8);
return writeLines(list, file, CharsetUtil.UTF_8);
}
/**
@ -2788,7 +2788,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.2
*/
public static <T> File appendUtf8Lines(Collection<T> list, File file) throws IORuntimeException {
return appendLines(list, file, CharsetUtil.CHARSET_UTF_8);
return appendLines(list, file, CharsetUtil.UTF_8);
}
/**
@ -2802,7 +2802,7 @@ public class FileUtil extends PathUtil {
* @since 3.1.2
*/
public static <T> File appendUtf8Lines(Collection<T> list, String path) throws IORuntimeException {
return appendLines(list, path, CharsetUtil.CHARSET_UTF_8);
return appendLines(list, path, CharsetUtil.UTF_8);
}
/**
@ -2940,7 +2940,7 @@ public class FileUtil extends PathUtil {
* @since 4.0.5
*/
public static File writeUtf8Map(Map<?, ?> map, File file, String kvSeparator, boolean isAppend) throws IORuntimeException {
return FileWriter.create(file, CharsetUtil.CHARSET_UTF_8).writeMap(map, kvSeparator, isAppend);
return FileWriter.create(file, CharsetUtil.UTF_8).writeMap(map, kvSeparator, isAppend);
}
/**
@ -3364,7 +3364,7 @@ public class FileUtil extends PathUtil {
* @param handler 行处理器
*/
public static void tail(File file, LineHandler handler) {
tail(file, CharsetUtil.CHARSET_UTF_8, handler);
tail(file, CharsetUtil.UTF_8, handler);
}
/**

View File

@ -1,7 +1,7 @@
package cn.hutool.core.io;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
/**
* IO运行时异常常用于对IOException的包装

View File

@ -8,7 +8,7 @@ import cn.hutool.core.io.copy.StreamCopier;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.codec.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@ -198,7 +198,7 @@ public class IoUtil extends NioUtil {
* @since 5.1.6
*/
public static BufferedReader getUtf8Reader(InputStream in) {
return getReader(in, CharsetUtil.CHARSET_UTF_8);
return getReader(in, CharsetUtil.UTF_8);
}
/**
@ -282,7 +282,7 @@ public class IoUtil extends NioUtil {
* @since 5.1.6
*/
public static OutputStreamWriter getUtf8Writer(OutputStream out) {
return getWriter(out, CharsetUtil.CHARSET_UTF_8);
return getWriter(out, CharsetUtil.UTF_8);
}
/**
@ -316,7 +316,7 @@ public class IoUtil extends NioUtil {
* @since 5.4.4
*/
public static String readUtf8(InputStream in) throws IORuntimeException {
return read(in, CharsetUtil.CHARSET_UTF_8);
return read(in, CharsetUtil.UTF_8);
}
/**
@ -594,7 +594,7 @@ public class IoUtil extends NioUtil {
* @throws IORuntimeException IO异常
*/
public static <T extends Collection<String>> T readUtf8Lines(InputStream in, T collection) throws IORuntimeException {
return readLines(in, CharsetUtil.CHARSET_UTF_8, collection);
return readLines(in, CharsetUtil.UTF_8, collection);
}
/**
@ -634,7 +634,7 @@ public class IoUtil extends NioUtil {
* @since 3.1.1
*/
public static void readUtf8Lines(InputStream in, LineHandler lineHandler) throws IORuntimeException {
readLines(in, CharsetUtil.CHARSET_UTF_8, lineHandler);
readLines(in, CharsetUtil.UTF_8, lineHandler);
}
/**
@ -692,7 +692,7 @@ public class IoUtil extends NioUtil {
* @since 4.5.1
*/
public static ByteArrayInputStream toUtf8Stream(String content) {
return toStream(content, CharsetUtil.CHARSET_UTF_8);
return toStream(content, CharsetUtil.UTF_8);
}
/**
@ -935,7 +935,7 @@ public class IoUtil extends NioUtil {
* @since 3.1.1
*/
public static void writeUtf8(OutputStream out, boolean isCloseOut, Object... contents) throws IORuntimeException {
write(out, CharsetUtil.CHARSET_UTF_8, isCloseOut, contents);
write(out, CharsetUtil.UTF_8, isCloseOut, contents);
}
/**

View File

@ -3,7 +3,7 @@ package cn.hutool.core.io;
import cn.hutool.core.io.copy.ChannelCopier;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.IOException;
import java.io.InputStream;
@ -222,7 +222,7 @@ public class NioUtil {
* @throws IORuntimeException IO异常
*/
public static String readUtf8(FileChannel fileChannel) throws IORuntimeException {
return read(fileChannel, CharsetUtil.CHARSET_UTF_8);
return read(fileChannel, CharsetUtil.UTF_8);
}
/**

View File

@ -1,7 +1,7 @@
package cn.hutool.core.io.checksum.crc16;
import cn.hutool.core.codec.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.util.zip.Checksum;

View File

@ -2,7 +2,7 @@ package cn.hutool.core.io.file;
import cn.hutool.core.thread.lock.LockUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ObjUtil;
import java.io.File;
import java.io.PrintWriter;
@ -50,7 +50,7 @@ public class FileAppender implements Serializable {
* @param isNewLineMode 追加内容是否为新行
*/
public FileAppender(File destFile, int capacity, boolean isNewLineMode) {
this(destFile, CharsetUtil.CHARSET_UTF_8, capacity, isNewLineMode);
this(destFile, CharsetUtil.UTF_8, capacity, isNewLineMode);
}
/**
@ -79,7 +79,7 @@ public class FileAppender implements Serializable {
this.list = new ArrayList<>(capacity);
this.isNewLineMode = isNewLineMode;
this.writer = FileWriter.create(destFile, charset);
this.lock = ObjectUtil.defaultIfNull(lock, LockUtil::getNoLock);
this.lock = ObjUtil.defaultIfNull(lock, LockUtil::getNoLock);
}
/**

View File

@ -5,7 +5,7 @@ import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.copier.SrcToDestCopier;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.File;
import java.io.IOException;

View File

@ -2,7 +2,7 @@ package cn.hutool.core.io.file;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.regex.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.File;
import java.util.regex.Pattern;

View File

@ -5,7 +5,7 @@ import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.LineHandler;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.StrUtil;
import java.io.BufferedInputStream;
import java.io.BufferedReader;

Some files were not shown because too many files have changed in this diff Show More