package top.csaf;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.IteratorUtils;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
/**
* 集合工具类
*/
@Slf4j
public class CollectionUtils {
/**
* 是否 集合为 null 或 没有元素
*
* @param coll 集合
* @return 是否 集合为 null 或 没有元素
*/
public static boolean isEmpty(final Collection> coll) {
return !org.apache.commons.collections4.CollectionUtils.isNotEmpty(coll);
}
/**
* 是否 集合不为 null 且 有元素
*
* @param coll 集合
* @return 是否 集合不为 null 且 有元素
*/
public static boolean isNotEmpty(final Collection> coll) {
return !isEmpty(coll);
}
/**
* 是否 每个集合都 (为 null 或 没有元素)
*
* @param colls 多个集合
* @return 是否 每个集合都 (为 null 或 没有元素)
*/
public static boolean isEmptys(final Collection>... colls) {
if (colls == null) {
return true;
}
if (colls.length == 0) {
throw new IllegalArgumentException("Colls: length should be greater than 0");
}
for (Collection> coll : colls) {
// 如果 某个集合 (不为 null 且 有元素)
if (isEmpty(coll)) {
return false;
}
}
return true;
}
/**
* 是否 每个集合都 (不为 null 且 有元素)
*
* @param colls 多个集合
* @return 是否 每个集合都 (不为 null 且 有元素)
*/
public static boolean isNotEmptys(final Collection>... colls) {
return !isEmptys(colls);
}
/**
* 是否 对象为 null 或 没有元素
*
*
* - Collection - via collection isEmpty
*
- Map - via map isEmpty
*
- Array - using array size
*
- Iterator - via hasNext
*
- Enumeration - via hasMoreElements
*
*
* @param object 对象
* @return 是否 对象为 null 或 没有元素
*/
public static boolean sizeIsEmpty(final Object object) {
return org.apache.commons.collections4.CollectionUtils.sizeIsEmpty(object);
}
/**
* 是否 对象不为 null 且 有元素
*
* @param object 对象
* @return 是否 对象不为 null 且 有元素
*/
public static boolean sizeIsNotEmpty(@NonNull final Object object) {
return !sizeIsEmpty(object);
}
/**
* 是否 每个对象都 (为 null 或 没有元素)
*
*
* - Collection - via collection isEmpty
*
- Map - via map isEmpty
*
- Array - using array size
*
- Iterator - via hasNext
*
- Enumeration - via hasMoreElements
*
*
* @param objects 多个对象
* @return 是否 每个对象都 (为 null 或 没有元素)
*/
public static boolean sizeIsEmptys(final Object... objects) {
if (objects == null) {
return true;
}
if (objects.length == 0) {
throw new IllegalArgumentException("Objects: length should be greater than 0");
}
for (Object object : objects) {
// 如果 某个对象 (不为 null 且 有元素)
if (sizeIsEmpty(object)) {
return false;
}
}
return true;
}
/**
* 是否 每个对象都 (不为 null 且 有元素)
*
* @param objects 多个对象
* @return 是否 每个对象都 (不为 null 且 有元素)
*/
public static boolean sizeIsNotEmptys(@NonNull final Object... objects) {
return !sizeIsEmptys(objects);
}
/**
* 是否 对象所有元素都为 null 或 没有元素
*
* 注意:会遍历 Iterator,后续使用需重新创建,但是和 {@link CollectionUtils#isAllEquals(boolean, Function, Object...)}、{@link CollectionUtils#isAllEqualsSameIndex(boolean, Function, Object...)} 使用时却无须担心,因为其内部会在调用此方法前就将 Iterator 转换为 List
*
*
* - Collection - removeIf null, size() == 0
*
- Map - self(values())
*
- Array - noneMatch nonNull
*
- Iterator - !(next() != null)
*
- Enumeration - 同 Iterator
*
*
* @param object 对象
* @return 是否 对象所有元素都为 null 或 没有元素)
*/
public static boolean isAllEmpty(final Object object) {
if (object == null) {
return true;
}
if (object instanceof Collection) {
Collection> obj1 = (Collection>) object;
obj1.removeIf(Objects::isNull);
return obj1.size() == 0;
} else if (object instanceof Iterable>) {
for (Object o : (Iterable>) object) {
if (o != null) {
return false;
}
}
} else if (object instanceof Map, ?>) {
return isAllEmptys(((Map, ?>) object).values());
} else if (object instanceof Object[]) {
Object[] obj1 = (Object[]) object;
return Arrays.stream(obj1).noneMatch(Objects::nonNull);
} else if (object instanceof Iterator>) {
Iterator> obj1 = (Iterator>) object;
while (obj1.hasNext()) {
if (obj1.next() != null) {
return false;
}
}
} else if (object instanceof Enumeration>) {
Enumeration> obj1 = (Enumeration>) object;
while (obj1.hasMoreElements()) {
if (obj1.nextElement() != null) {
return false;
}
}
}
return true;
}
/**
* 是否 对象所有元素都不为 null 且 有元素
*
* @param object 对象
* @return 是否 对象元素都不为 null 且 有元素
*/
public static boolean isNotAllEmpty(@NonNull final Object object) {
return !isAllEmptys(object);
}
/**
* 是否 每个对象的 (所有元素都为 null 或 没有元素)
*
* 注意:会遍历 Iterator,后续使用需重新创建,但是和 {@link CollectionUtils#isAllEquals(boolean, Function, Object...)}、{@link CollectionUtils#isAllEqualsSameIndex(boolean, Function, Object...)} 使用时却无须担心,因为其内部会在调用此方法前就将 Iterator 转换为 List
*
*
* - Collection - removeIf null, size() == 0
*
- Map - self(values())
*
- Array - noneMatch nonNull
*
- Iterator - !(next() != null)
*
- Enumeration - 同 Iterator
*
*
* @param objects 多个对象
* @return 是否 每个对象的 (所有元素都为 null 或 没有元素)
*/
public static boolean isAllEmptys(final Object... objects) {
if (objects == null) {
return true;
}
if (objects.length == 0) {
throw new IllegalArgumentException("Objects: length should be greater than 0");
}
for (Object object : objects) {
if (!isAllEmpty(object)) {
return false;
}
}
return true;
}
/**
* 是否 每个对象的 (所有元素都不为 null 且 有元素)
*
* @param objects 多个对象
* @return 是否 每个对象的 (所有元素都不为 null 且 有元素)
*/
public static boolean isNotAllEmptys(@NonNull final Object... objects) {
return !isAllEmptys(objects);
}
/**
* 是否 任意对象为 null 或 没有元素 或 任意元素为 null
*
* 注意:会遍历 Iterator,后续使用需重新创建,但是和 {@link CollectionUtils#isAllEquals(boolean, Function, Object...)}、{@link CollectionUtils#isAllEqualsSameIndex(boolean, Function, Object...)} 使用时却无须担心,因为其内部会在调用此方法前就将 Iterator 转换为 List
*
*
* - Collection - contains null
*
- Map - containsValue null
*
- Array - anyMatch null
*
- Iterator - next() == null
*
- Enumeration - 同 Iterator
*
*
* @param object 对象
* @return 是否 任意对象为 null 或 没有元素 或 任意元素为 null
*/
public static boolean isAnyEmpty(final Object object) {
if (sizeIsEmpty(object)) {
return true;
}
if (object instanceof Collection>) {
Collection> obj1 = (Collection>) object;
return obj1.contains(null);
} else if (object instanceof Iterable>) {
for (Object o : (Iterable>) object) {
if (o == null) {
return true;
}
}
} else if (object instanceof Map, ?>) {
return ((Map, ?>) object).containsValue(null);
} else if (object instanceof Object[]) {
Object[] obj1 = (Object[]) object;
return Arrays.stream(obj1).anyMatch(Objects::isNull);
} else if (object instanceof Iterator>) {
Iterator> obj1 = (Iterator>) object;
while (obj1.hasNext()) {
if (obj1.next() == null) {
return true;
}
}
} else if (object instanceof Enumeration>) {
Enumeration> obj1 = (Enumeration>) object;
while (obj1.hasMoreElements()) {
if (obj1.nextElement() == null) {
return true;
}
}
}
return false;
}
/**
* 是否 对象不为 null 且 有元素 且 每个元素都不为 null
*
* @param object 对象
* @return 是否 对象不为 null 且 有元素 且 每个元素都不为 null
*/
public static boolean isNotAnyEmpty(final Object object) {
return !isAnyEmpty(object);
}
/**
* 是否 任意对象 (为 null 或 没有元素 或 任意元素为 null)
*
* 注意:会遍历 Iterator,后续使用需重新创建,但是和 {@link CollectionUtils#isAllEquals(boolean, Function, Object...)}、{@link CollectionUtils#isAllEqualsSameIndex(boolean, Function, Object...)} 使用时却无须担心,因为其内部会在调用此方法前就将 Iterator 转换为 List
*
*
* - Collection - contains null
*
- Map - containsValue null
*
- Array - anyMatch null
*
- Iterator - next() == null
*
- Enumeration - 同 Iterator
*
*
* @param objects 多个对象
* @return 是否 任意对象 (为 null 或 没有元素 或 任意元素为 null)
*/
public static boolean isAnyEmptys(final Object... objects) {
if (objects == null) {
return true;
}
if (objects.length == 0) {
throw new IllegalArgumentException("Objects: length should be greater than 0");
}
for (Object object : objects) {
if (isAnyEmpty(object)) {
return true;
}
}
return false;
}
/**
* 是否 每个对象 (不为 null 且 有元素 且 每个元素都不为 null)
*
* @param objects 多个对象
* @return 是否 每个对象 (不为 null 且 有元素 且 每个元素都不为 null)
*/
public static boolean isNotAnyEmptys(final Object... objects) {
return !isAnyEmptys(objects);
}
/**
* 转为字符串,Float、Double、BigDecimal 小数点后多余的 0 会被去除
*
* @param object 需转换的对象
* @param isByString 是否转换
* @return 字符串
*/
private static Object stripTrailingZerosToString(Object object, boolean isByString) {
if (isByString) {
if (object instanceof Float || object instanceof Double || object instanceof BigDecimal) {
object = new BigDecimal(object.toString()).stripTrailingZeros().toPlainString();
} else {
object = object.toString();
}
}
return object;
}
/**
* 是否 每个对象的每个元素都相等
*
* @param isByString 是否根据 toString() 的值来判断是否相等,Float、Double、BigDecimal 小数点后多余的 0 会被去除
* @param continueFunction 对象何时不参与判断
* @param objects 多个对象
* @return 是否 每个对象的每个元素都相等
*/
public static boolean isAllEquals(boolean isByString, Function