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

icu.easyj.core.util.StringUtils Maven / Gradle / Ivy

/*
 * Copyright 2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package icu.easyj.core.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.function.Predicate;
import java.util.function.Supplier;

import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

/**
 * 字符串工具类
 *
 * @author wangliang181230
 */
public abstract class StringUtils {

	/**
	 * 大小写字符的差值
	 */
	public static final int CASE_DIFF = ('a' - 'A');

	/**
	 * 字符串的value属性
	 */
	private static final Field STRING_VALUE_FIELD;

	static {
		try {
			STRING_VALUE_FIELD = String.class.getDeclaredField("value");
			STRING_VALUE_FIELD.setAccessible(true);
		} catch (NoSuchFieldException e) {
			throw new RuntimeException(e);
		}
	}


	//region 获取字符串的value属性

	/**
	 * 直接获取String的value属性。
	 * 

* 部分场景下,我们获取字符串的char数组,只是为了校验字符串,并没有任何修改、删除操作。
* 但由于 {@link String#toCharArray()} 方法会复制一次字符数组,导致无谓的性能损耗。
* 所以,开发了此方法用于提升性能。 * * @param str 字符串 * @return 字符数组 * @see String#toCharArray() */ public static char[] toCharArrayWithoutCopy(CharSequence str) { try { return (char[])STRING_VALUE_FIELD.get(str.toString()); } catch (IllegalAccessException e) { throw new RuntimeException("获取字符串的value失败", e); } } //endregion //region 判断方法 /** * 字符串是否为空 * * @param cs 字符串 * @return 是否为空 */ public static boolean isEmpty(final CharSequence cs) { return cs == null || cs.length() == 0; } /** * 字符串是否不为空 * * @param cs 字符串 * @return 是否不为空 */ public static boolean isNotEmpty(final CharSequence cs) { return !isEmpty(cs); } /** * 字符串是否为空白 * * @param cs 字符串 * @return 是否为空白 */ public static boolean isBlank(final CharSequence cs) { if (cs == null) { return true; } final int length = cs.length(); if (length > 0) { for (int i = 0; i < length; ++i) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } } return true; } /** * 字符串是否不为空白 * * @param cs 字符串 * @return 是否不为空白 */ public static boolean isNotBlank(final CharSequence cs) { return !isBlank(cs); } /** * 判断字符串是否相等 * * @param cs1 字符串1 * @param cs2 字符串2 * @return 是否相等 */ public static boolean equals(final CharSequence cs1, final CharSequence cs2) { if (cs1 == cs2) { return true; } if (cs1 == null || cs2 == null) { return false; } if (cs1.length() != cs2.length()) { return false; } if (cs1 instanceof String && cs2 instanceof String) { return cs1.equals(cs2); } final int length = cs1.length(); for (int i = 0; i < length; i++) { if (cs1.charAt(i) != cs2.charAt(i)) { return false; } } return true; } //endregion //region 如果为空则取默认值的方法 /** * 如果为空字符串,则取默认值 * * @param cs 字符串 * @param defaultValue 默认值 * @param 字符串类型 * @return 字符串或默认值 */ public static T defaultIfEmpty(T cs, T defaultValue) { if (isEmpty(cs)) { return defaultValue; } return cs; } /** * 如果为空字符串,则执行supplier生成新的值 * * @param cs 字符串 * @param defaultValueSupplier 默认值提供者 * @param 字符串类型 * @return 入参字符串或生成的默认值 */ public static T defaultIfEmpty(final T cs, Supplier defaultValueSupplier) { if (isEmpty(cs)) { return defaultValueSupplier.get(); } return cs; } /** * 如果为空白字符串,则取默认值 * * @param cs 字符串 * @param defaultValue 默认值 * @param 字符串类型 * @return 字符串或默认值 */ public static T defaultIfBlank(T cs, T defaultValue) { if (isBlank(cs)) { return defaultValue; } return cs; } /** * 如果为空白字符串,则执行supplier生成新的值 * * @param cs 字符串 * @param defaultValueSupplier 默认值提供者 * @param 字符串类型 * @return 入参字符串或生成的默认值 */ public static T defaultIfBlank(final T cs, Supplier defaultValueSupplier) { if (isBlank(cs)) { return defaultValueSupplier.get(); } return cs; } //endregion //region 中文相关方法 /** * 判断是否为中文字符 * * @param c 字符 * @return 是否为中文字符 */ public static boolean isChinese(final char c) { return c >= 0x4E00 && c <= 0x9FA5; } /** * 计算字符串长度,中文计2个字符 * * @param cs 字符串 * @return strLength 字符串 */ public static int chineseLength(final CharSequence cs) { if (isEmpty(cs)) { return 0; } final int length = cs.length(); int resultLength = length; // 返回长度 for (int i = 0; i < length; ++i) { if (isChinese(cs.charAt(i))) { ++resultLength; } } return resultLength; } //endregion //region 查找数据 /** * 根据匹配函数,查找数据 * * @param strArr 字符串数组 * @param matcher 匹配函数 * @return 返回找到的字符串 或 {@code null} */ @Nullable public static String find(final String[] strArr, final Predicate matcher) { for (final String str : strArr) { if (matcher.test(str)) { return str; } } return null; } //region 查找第一个不为空的字符串 /** * 查找一个不为null或空字符串的字符串 * * @param strArr 字符串数组 * @return 返回找到的字符串 或 {@code null} */ @Nullable public static String findNotEmptyOne(final String... strArr) { return find(strArr, StringUtils::isNotEmpty); } /** * 查找一个不为null或空白字符串的字符串 * * @param strArr 字符串数组 * @return 返回找到的字符串 或 {@code null} */ @Nullable public static String findNotBlankOne(final String... strArr) { return find(strArr, StringUtils::isNotBlank); } //endregion //endregion //region toString /** * 将对象转换为字符串 * * @param obj 任意类型的对象 * @return str 转换后的字符串 */ @NonNull public static String toString(final Object obj) { if (obj == null) { return "null"; } //region Convert simple types to String directly if (obj instanceof CharSequence) { return "\"" + obj + "\""; } if (obj instanceof Character) { return "'" + obj + "'"; } if (obj instanceof Long) { return obj + "L"; } if (obj instanceof Date) { return DateUtils.toString((Date)obj); } if (obj instanceof Enum) { return obj.getClass().getSimpleName() + "." + ((Enum)obj).name(); } if (obj instanceof Class) { return ReflectionUtils.classToString((Class)obj); } if (obj instanceof Field) { return ReflectionUtils.fieldToString((Field)obj); } if (obj instanceof Method) { return ReflectionUtils.methodToString((Method)obj); } if (obj instanceof Annotation) { return ReflectionUtils.annotationToString((Annotation)obj); } //endregion //region Convert the Collection and Map if (obj instanceof Collection) { return CollectionUtils.toString((Collection)obj); } if (obj.getClass().isArray()) { return ArrayUtils.toString((Object[])obj); } if (obj instanceof Map) { return MapUtils.toString((Map)obj); } //endregion //the jdk classes if (obj.getClass().getClassLoader() == null) { return obj.toString(); } // 未知类型的对象转换为字符串 return unknownTypeObjectToString(obj); } /** * 未知类型的对象转换为字符串 * * @param obj 未知类型的对象 * @return str 转换后的字符串 */ @NonNull private static String unknownTypeObjectToString(@NonNull final Object obj) { return CycleDependencyHandler.wrap(obj, o -> { final StringBuilder sb = new StringBuilder(32); // handle the anonymous class String classSimpleName; if (obj.getClass().isAnonymousClass()) { if (!obj.getClass().getSuperclass().equals(Object.class)) { classSimpleName = obj.getClass().getSuperclass().getSimpleName(); } else { classSimpleName = obj.getClass().getInterfaces()[0].getSimpleName(); } // Connect a '$', different from ordinary class classSimpleName += "$"; } else { classSimpleName = obj.getClass().getSimpleName(); } sb.append(classSimpleName).append("("); // the initial length final int initialLength = sb.length(); // Gets all fields, excluding static or synthetic fields final Field[] fields = ReflectionUtils.getAllFields(obj.getClass()); Object fieldValue; for (Field field : fields) { if (sb.length() > initialLength) { sb.append(", "); } sb.append(field.getName()); sb.append("="); try { fieldValue = ReflectionUtils.getFieldValue(obj, field); } catch (RuntimeException ignore) { continue; } if (fieldValue == obj) { sb.append("(this ").append(fieldValue.getClass().getSimpleName()).append(")"); } else { sb.append(toString(fieldValue)); } } sb.append(")"); return sb.toString(); }); } //endregion }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy