001/* 002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.mybatisflex.core.util; 017 018 019import java.util.Collection; 020import java.util.function.Function; 021import java.util.regex.Pattern; 022 023public class StringUtil { 024 025 private StringUtil() { 026 } 027 028 029 /** 030 * 第一个字符转换为小写 031 * 032 * @param string 033 */ 034 public static String firstCharToLowerCase(String string) { 035 char firstChar = string.charAt(0); 036 if (firstChar >= 'A' && firstChar <= 'Z') { 037 char[] arr = string.toCharArray(); 038 arr[0] += ('a' - 'A'); 039 return new String(arr); 040 } 041 return string; 042 } 043 044 045 /** 046 * 第一个字符转换为大写 047 * 048 * @param string 049 */ 050 public static String firstCharToUpperCase(String string) { 051 char firstChar = string.charAt(0); 052 if (firstChar >= 'a' && firstChar <= 'z') { 053 char[] arr = string.toCharArray(); 054 arr[0] -= ('a' - 'A'); 055 return new String(arr); 056 } 057 return string; 058 } 059 060 061 /** 062 * 驼峰转下划线格式 063 * 064 * @param string 065 */ 066 public static String camelToUnderline(String string) { 067 if (isBlank(string)) { 068 return ""; 069 } 070 int strLen = string.length(); 071 StringBuilder sb = new StringBuilder(strLen); 072 for (int i = 0; i < strLen; i++) { 073 char c = string.charAt(i); 074 if (Character.isUpperCase(c) && i > 0) { 075 sb.append('_'); 076 } 077 sb.append(Character.toLowerCase(c)); 078 } 079 return sb.toString(); 080 } 081 082 /** 083 * 下划线转驼峰格式 084 * 085 * @param string 086 */ 087 public static String underlineToCamel(String string) { 088 if (isBlank(string)) { 089 return ""; 090 } 091 String temp = string.toLowerCase(); 092 int strLen = temp.length(); 093 StringBuilder sb = new StringBuilder(strLen); 094 for (int i = 0; i < strLen; i++) { 095 char c = temp.charAt(i); 096 if (c == '_') { 097 if (++i < strLen) { 098 sb.append(Character.toUpperCase(temp.charAt(i))); 099 } 100 } else { 101 sb.append(c); 102 } 103 } 104 return sb.toString(); 105 } 106 107 108 /** 109 * 删除字符串中的字符 110 */ 111 public static String deleteChar(String string,char deleteChar) { 112 if (isBlank(string)) { 113 return ""; 114 } 115 char[] chars = string.toCharArray(); 116 StringBuilder sb = new StringBuilder(string.length()); 117 for (char aChar : chars) { 118 if (aChar != deleteChar){ 119 sb.append(aChar); 120 } 121 } 122 return sb.toString(); 123 } 124 125 /** 126 * 字符串为 null 或者内部字符全部为 ' ', '\t', '\n', '\r' 这四类字符时返回 true 127 */ 128 public static boolean isBlank(String str) { 129 if (str == null) { 130 return true; 131 } 132 133 for (int i = 0, len = str.length(); i < len; i++) { 134 if (str.charAt(i) > ' ') { 135 return false; 136 } 137 } 138 return true; 139 } 140 141 142 public static boolean isAnyBlank(String... strings) { 143 if (strings == null || strings.length == 0) { 144 throw new IllegalArgumentException("args is empty."); 145 } 146 147 for (String str : strings) { 148 if (isBlank(str)) { 149 return true; 150 } 151 } 152 return false; 153 } 154 155 156 public static boolean isNotBlank(String str) { 157 return !isBlank(str); 158 } 159 160 161 public static boolean areNotBlank(String... strings) { 162 return !isAnyBlank(); 163 } 164 165 166 /** 167 * 这个字符串是否是全是数字 168 * 169 * @param str 170 * @return 171 */ 172 public static boolean isNumeric(String str) { 173 if (isBlank(str)) { 174 return false; 175 } 176 for (int i = str.length(); --i >= 0; ) { 177 int chr = str.charAt(i); 178 if (chr < 48 || chr > 57) { 179 return false; 180 } 181 } 182 return true; 183 } 184 185 186 public static boolean startsWithAny(String str, String... prefixes) { 187 if (isBlank(str) || prefixes == null || prefixes.length == 0) { 188 return false; 189 } 190 191 for (String prefix : prefixes) { 192 if (str.startsWith(prefix)) { 193 return true; 194 } 195 } 196 return false; 197 } 198 199 200 public static boolean endsWithAny(String str, String... suffixes) { 201 if (isBlank(str) || suffixes == null || suffixes.length == 0) { 202 return false; 203 } 204 205 for (String suffix : suffixes) { 206 if (str.endsWith(suffix)) { 207 return true; 208 } 209 } 210 return false; 211 } 212 213 214 public static String trimOrNull(String string) { 215 return string != null ? string.trim() : null; 216 } 217 218 219 /** 220 * 正则匹配 221 * 222 * @param regex 223 * @param input 224 * @return 225 */ 226 public static boolean matches(String regex, String input) { 227 if (null == regex || null == input) { 228 return false; 229 } 230 return Pattern.matches(regex, input); 231 } 232 233 /** 234 * 合并字符串,优化 String.join() 方法 235 * 236 * @param delimiter 237 * @param elements 238 * @return 新拼接好的字符串 239 * @see String#join(CharSequence, CharSequence...) 240 */ 241 public static String join(String delimiter, CharSequence... elements) { 242 if (ArrayUtil.isEmpty(elements)) { 243 return ""; 244 } else if (elements.length == 1) { 245 return String.valueOf(elements[0]); 246 } else { 247 return String.join(delimiter, elements); 248 } 249 } 250 251 /** 252 * 合并字符串,优化 String.join() 方法 253 * 254 * @param delimiter 255 * @param elements 256 * @return 新拼接好的字符串 257 * @see String#join(CharSequence, CharSequence...) 258 */ 259 public static String join(String delimiter, Collection<? extends CharSequence> elements) { 260 if (CollectionUtil.isEmpty(elements)) { 261 return ""; 262 } else if (elements.size() == 1) { 263 return String.valueOf(elements.iterator().next()); 264 } else { 265 return String.join(delimiter, elements); 266 } 267 } 268 269 270 /** 271 * 合并字符串,优化 String.join() 方法 272 * 273 * @param delimiter 274 * @param objs 275 * @param function 276 * @param <T> 277 */ 278 public static <T> String join(String delimiter, Collection<T> objs, Function<T, String> function) { 279 if (CollectionUtil.isEmpty(objs)) { 280 return ""; 281 } else if (objs.size() == 1) { 282 T next = objs.iterator().next(); 283 return String.valueOf(function.apply(next)); 284 } else { 285 String[] strings = new String[objs.size()]; 286 int index = 0; 287 for (T obj : objs) { 288 strings[index++] = function.apply(obj); 289 } 290 return String.join(delimiter, strings); 291 } 292 } 293 294 public static String buildSchemaWithTable(String schema, String tableName) { 295 return isNotBlank(schema) ? schema + "." + tableName : tableName; 296 } 297 298 public static String[] getSchemaAndTableName(String tableNameWithSchema) { 299 int index = tableNameWithSchema.indexOf("."); 300 return index <= 0 ? new String[]{null, tableNameWithSchema.trim()} 301 : new String[]{tableNameWithSchema.substring(0, index).trim(), tableNameWithSchema.substring(index + 1).trim()}; 302 } 303 304 public static String[] getTableNameWithAlisa(String tableNameWithAlisa) { 305 int index = tableNameWithAlisa.indexOf("."); 306 return index <= 0 ? new String[]{tableNameWithAlisa, null} 307 : new String[]{tableNameWithAlisa.substring(0, index), tableNameWithAlisa.substring(index + 1)}; 308 } 309 310 public static String tryTrim(String string) { 311 return string != null ? string.trim() : null; 312 } 313 314 public static String substringAfterLast(String text, String str) { 315 if (text == null) { 316 return null; 317 } 318 if (str == null) { 319 return text; 320 } 321 return text.substring(text.lastIndexOf(str) + 1); 322 } 323 324 325}