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    /**
194     * 正则匹配
195     *
196     * @param regex
197     * @param input
198     * @return
199     */
200    public static boolean matches(String regex, String input) {
201        if (null == regex || null == input) {
202            return false;
203        }
204        return Pattern.matches(regex, input);
205    }
206
207    /**
208     * 合并字符串,优化 String.join() 方法
209     *
210     * @param delimiter
211     * @param elements
212     * @return 新拼接好的字符串
213     * @see String#join(CharSequence, CharSequence...)
214     */
215    public static String join(String delimiter, CharSequence... elements) {
216        if (ArrayUtil.isEmpty(elements)) {
217            return "";
218        } else if (elements.length == 1) {
219            return String.valueOf(elements[0]);
220        } else {
221            return String.join(delimiter, elements);
222        }
223    }
224
225
226    /**
227     * 合并字符串,优化 String.join() 方法
228     *
229     * @param delimiter
230     * @param elements
231     * @return 新拼接好的字符串
232     * @see String#join(CharSequence, CharSequence...)
233     */
234    public static String join(String delimiter, Collection<? extends CharSequence> elements) {
235        if (CollectionUtil.isEmpty(elements)) {
236            return "";
237        } else if (elements.size() == 1) {
238            return String.valueOf(elements.iterator().next());
239        } else {
240            return String.join(delimiter, elements);
241        }
242    }
243
244    /**
245     * 合并字符串,优化 String.join() 方法
246     *
247     * @param delimiter
248     * @param objs
249     * @param function
250     * @param <T>
251     * @return
252     */
253    public static <T> String join(String delimiter, Collection<T> objs, Function<T, String> function) {
254        if (CollectionUtil.isEmpty(objs)) {
255            return "";
256        } else if (objs.size() == 1) {
257            T next = objs.iterator().next();
258            return String.valueOf(function.apply(next));
259        } else {
260            String[] strings = new String[objs.size()];
261            int index = 0;
262            for (T obj : objs) {
263                strings[index++] = function.apply(obj);
264            }
265            return String.join(delimiter, strings);
266        }
267    }
268
269
270}