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 026 /** 027 * 第一个字符转换为小写 028 * 029 * @param string 030 */ 031 public static String firstCharToLowerCase(String string) { 032 char firstChar = string.charAt(0); 033 if (firstChar >= 'A' && firstChar <= 'Z') { 034 char[] arr = string.toCharArray(); 035 arr[0] += ('a' - 'A'); 036 return new String(arr); 037 } 038 return string; 039 } 040 041 042 /** 043 * 第一个字符转换为大写 044 * 045 * @param string 046 */ 047 public static String firstCharToUpperCase(String string) { 048 char firstChar = string.charAt(0); 049 if (firstChar >= 'a' && firstChar <= 'z') { 050 char[] arr = string.toCharArray(); 051 arr[0] -= ('a' - 'A'); 052 return new String(arr); 053 } 054 return string; 055 } 056 057 058 /** 059 * 驼峰转下划线格式 060 * 061 * @param string 062 */ 063 public static String camelToUnderline(String string) { 064 if (isBlank(string)) { 065 return ""; 066 } 067 int strLen = string.length(); 068 StringBuilder sb = new StringBuilder(strLen); 069 for (int i = 0; i < strLen; i++) { 070 char c = string.charAt(i); 071 if (Character.isUpperCase(c) && i > 0) { 072 sb.append('_'); 073 } 074 sb.append(Character.toLowerCase(c)); 075 } 076 return sb.toString(); 077 } 078 079 /** 080 * 下划线转驼峰格式 081 * 082 * @param string 083 */ 084 public static String underlineToCamel(String string) { 085 if (isBlank(string)) { 086 return ""; 087 } 088 String temp = string.toLowerCase(); 089 int strLen = temp.length(); 090 StringBuilder sb = new StringBuilder(strLen); 091 for (int i = 0; i < strLen; i++) { 092 char c = temp.charAt(i); 093 if (c == '_') { 094 if (++i < strLen) { 095 sb.append(Character.toUpperCase(temp.charAt(i))); 096 } 097 } else { 098 sb.append(c); 099 } 100 } 101 return sb.toString(); 102 } 103 104 /** 105 * 字符串为 null 或者内部字符全部为 ' ', '\t', '\n', '\r' 这四类字符时返回 true 106 */ 107 public static boolean isBlank(String str) { 108 if (str == null) { 109 return true; 110 } 111 112 for (int i = 0, len = str.length(); i < len; i++) { 113 if (str.charAt(i) > ' ') { 114 return false; 115 } 116 } 117 return true; 118 } 119 120 121 public static boolean isAnyBlank(String... strings) { 122 if (strings == null || strings.length == 0) { 123 throw new IllegalArgumentException("args is empty."); 124 } 125 126 for (String str : strings) { 127 if (isBlank(str)) { 128 return true; 129 } 130 } 131 return false; 132 } 133 134 135 public static boolean isNotBlank(String str) { 136 return !isBlank(str); 137 } 138 139 140 public static boolean areNotBlank(String... strings) { 141 return !isAnyBlank(); 142 } 143 144 145 /** 146 * 这个字符串是否是全是数字 147 * 148 * @param str 149 * @return 150 */ 151 public static boolean isNumeric(String str) { 152 if (isBlank(str)) { 153 return false; 154 } 155 for (int i = str.length(); --i >= 0; ) { 156 int chr = str.charAt(i); 157 if (chr < 48 || chr > 57) { 158 return false; 159 } 160 } 161 return true; 162 } 163 164 165 public static boolean startsWithAny(String str, String... prefixes) { 166 if (isBlank(str) || prefixes == null || prefixes.length == 0) { 167 return false; 168 } 169 170 for (String prefix : prefixes) { 171 if (str.startsWith(prefix)) { 172 return true; 173 } 174 } 175 return false; 176 } 177 178 179 public static boolean endsWithAny(String str, String... suffixes) { 180 if (isBlank(str) || suffixes == null || suffixes.length == 0) { 181 return false; 182 } 183 184 for (String suffix : suffixes) { 185 if (str.endsWith(suffix)) { 186 return true; 187 } 188 } 189 return false; 190 } 191 192 193 public static String trimOrNull(String string) { 194 return string != null ? string.trim() : null; 195 } 196 197 198 /** 199 * 正则匹配 200 * 201 * @param regex 202 * @param input 203 * @return 204 */ 205 public static boolean matches(String regex, String input) { 206 if (null == regex || null == input) { 207 return false; 208 } 209 return Pattern.matches(regex, input); 210 } 211 212 /** 213 * 合并字符串,优化 String.join() 方法 214 * 215 * @param delimiter 216 * @param elements 217 * @return 新拼接好的字符串 218 * @see String#join(CharSequence, CharSequence...) 219 */ 220 public static String join(String delimiter, CharSequence... elements) { 221 if (ArrayUtil.isEmpty(elements)) { 222 return ""; 223 } else if (elements.length == 1) { 224 return String.valueOf(elements[0]); 225 } else { 226 return String.join(delimiter, elements); 227 } 228 } 229 230 231 /** 232 * 合并字符串,优化 String.join() 方法 233 * 234 * @param delimiter 235 * @param elements 236 * @return 新拼接好的字符串 237 * @see String#join(CharSequence, CharSequence...) 238 */ 239 public static String join(String delimiter, Collection<? extends CharSequence> elements) { 240 if (CollectionUtil.isEmpty(elements)) { 241 return ""; 242 } else if (elements.size() == 1) { 243 return String.valueOf(elements.iterator().next()); 244 } else { 245 return String.join(delimiter, elements); 246 } 247 } 248 249 /** 250 * 合并字符串,优化 String.join() 方法 251 * 252 * @param delimiter 253 * @param objs 254 * @param function 255 * @param <T> 256 * @return 257 */ 258 public static <T> String join(String delimiter, Collection<T> objs, Function<T, String> function) { 259 if (CollectionUtil.isEmpty(objs)) { 260 return ""; 261 } else if (objs.size() == 1) { 262 T next = objs.iterator().next(); 263 return String.valueOf(function.apply(next)); 264 } else { 265 String[] strings = new String[objs.size()]; 266 int index = 0; 267 for (T obj : objs) { 268 strings[index++] = function.apply(obj); 269 } 270 return String.join(delimiter, strings); 271 } 272 } 273 274 275}