中国算力平台算力登记系统2.0
yanzhaofeige
2024-09-30 3c4fee1db116c11d4f04727cfe076d7c94daeaf2
commit | author | age
43dc29 1 package com.odcc.cpzidc.common.utils;
Y 2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9 import org.springframework.util.AntPathMatcher;
10 import com.odcc.cpzidc.common.constant.Constants;
11 import com.odcc.cpzidc.common.core.text.StrFormatter;
12
13 /**
14  * 字符串工具类
15  * 
16  * @author ruoyi
17  */
18 public class StringUtils extends org.apache.commons.lang3.StringUtils
19 {
20     /** 空字符串 */
21     private static final String NULLSTR = "";
22
23     /** 下划线 */
24     private static final char SEPARATOR = '_';
25
26     /** 星号 */
27     private static final char ASTERISK = '*';
28
29     /**
30      * 获取参数不为空值
31      * 
32      * @param value defaultValue 要判断的value
33      * @return value 返回值
34      */
35     public static <T> T nvl(T value, T defaultValue)
36     {
37         return value != null ? value : defaultValue;
38     }
39
40     /**
41      * * 判断一个Collection是否为空, 包含List,Set,Queue
42      * 
43      * @param coll 要判断的Collection
44      * @return true:为空 false:非空
45      */
46     public static boolean isEmpty(Collection<?> coll)
47     {
48         return isNull(coll) || coll.isEmpty();
49     }
50
51     /**
52      * * 判断一个Collection是否非空,包含List,Set,Queue
53      * 
54      * @param coll 要判断的Collection
55      * @return true:非空 false:空
56      */
57     public static boolean isNotEmpty(Collection<?> coll)
58     {
59         return !isEmpty(coll);
60     }
61
62     /**
63      * * 判断一个对象数组是否为空
64      * 
65      * @param objects 要判断的对象数组
66      ** @return true:为空 false:非空
67      */
68     public static boolean isEmpty(Object[] objects)
69     {
70         return isNull(objects) || (objects.length == 0);
71     }
72
73     /**
74      * * 判断一个对象数组是否非空
75      * 
76      * @param objects 要判断的对象数组
77      * @return true:非空 false:空
78      */
79     public static boolean isNotEmpty(Object[] objects)
80     {
81         return !isEmpty(objects);
82     }
83
84     /**
85      * * 判断一个Map是否为空
86      * 
87      * @param map 要判断的Map
88      * @return true:为空 false:非空
89      */
90     public static boolean isEmpty(Map<?, ?> map)
91     {
92         return isNull(map) || map.isEmpty();
93     }
94
95     /**
96      * * 判断一个Map是否为空
97      * 
98      * @param map 要判断的Map
99      * @return true:非空 false:空
100      */
101     public static boolean isNotEmpty(Map<?, ?> map)
102     {
103         return !isEmpty(map);
104     }
105
106     /**
107      * * 判断一个字符串是否为空串
108      * 
109      * @param str String
110      * @return true:为空 false:非空
111      */
112     public static boolean isEmpty(String str)
113     {
114         return isNull(str) || NULLSTR.equals(str.trim());
115     }
116
117     /**
118      * * 判断一个字符串是否为非空串
119      * 
120      * @param str String
121      * @return true:非空串 false:空串
122      */
123     public static boolean isNotEmpty(String str)
124     {
125         return !isEmpty(str);
126     }
127
128     /**
129      * * 判断一个对象是否为空
130      * 
131      * @param object Object
132      * @return true:为空 false:非空
133      */
134     public static boolean isNull(Object object)
135     {
136         return object == null;
137     }
138
139     /**
140      * * 判断一个对象是否非空
141      * 
142      * @param object Object
143      * @return true:非空 false:空
144      */
145     public static boolean isNotNull(Object object)
146     {
147         return !isNull(object);
148     }
149
150     /**
151      * * 判断一个对象是否是数组类型(Java基本型别的数组)
152      * 
153      * @param object 对象
154      * @return true:是数组 false:不是数组
155      */
156     public static boolean isArray(Object object)
157     {
158         return isNotNull(object) && object.getClass().isArray();
159     }
160
161     /**
162      * 去空格
163      */
164     public static String trim(String str)
165     {
166         return (str == null ? "" : str.trim());
167     }
168
169     /**
170      * 替换指定字符串的指定区间内字符为"*"
171      *
172      * @param str 字符串
173      * @param startInclude 开始位置(包含)
174      * @param endExclude 结束位置(不包含)
175      * @return 替换后的字符串
176      */
177     public static String hide(CharSequence str, int startInclude, int endExclude)
178     {
179         if (isEmpty(str))
180         {
181             return NULLSTR;
182         }
183         final int strLength = str.length();
184         if (startInclude > strLength)
185         {
186             return NULLSTR;
187         }
188         if (endExclude > strLength)
189         {
190             endExclude = strLength;
191         }
192         if (startInclude > endExclude)
193         {
194             // 如果起始位置大于结束位置,不替换
195             return NULLSTR;
196         }
197         final char[] chars = new char[strLength];
198         for (int i = 0; i < strLength; i++)
199         {
200             if (i >= startInclude && i < endExclude)
201             {
202                 chars[i] = ASTERISK;
203             }
204             else
205             {
206                 chars[i] = str.charAt(i);
207             }
208         }
209         return new String(chars);
210     }
211
212     /**
213      * 截取字符串
214      * 
215      * @param str 字符串
216      * @param start 开始
217      * @return 结果
218      */
219     public static String substring(final String str, int start)
220     {
221         if (str == null)
222         {
223             return NULLSTR;
224         }
225
226         if (start < 0)
227         {
228             start = str.length() + start;
229         }
230
231         if (start < 0)
232         {
233             start = 0;
234         }
235         if (start > str.length())
236         {
237             return NULLSTR;
238         }
239
240         return str.substring(start);
241     }
242
243     /**
244      * 截取字符串
245      * 
246      * @param str 字符串
247      * @param start 开始
248      * @param end 结束
249      * @return 结果
250      */
251     public static String substring(final String str, int start, int end)
252     {
253         if (str == null)
254         {
255             return NULLSTR;
256         }
257
258         if (end < 0)
259         {
260             end = str.length() + end;
261         }
262         if (start < 0)
263         {
264             start = str.length() + start;
265         }
266
267         if (end > str.length())
268         {
269             end = str.length();
270         }
271
272         if (start > end)
273         {
274             return NULLSTR;
275         }
276
277         if (start < 0)
278         {
279             start = 0;
280         }
281         if (end < 0)
282         {
283             end = 0;
284         }
285
286         return str.substring(start, end);
287     }
288
289     /**
290      * 判断是否为空,并且不是空白字符
291      * 
292      * @param str 要判断的value
293      * @return 结果
294      */
295     public static boolean hasText(String str)
296     {
297         return (str != null && !str.isEmpty() && containsText(str));
298     }
299
300     private static boolean containsText(CharSequence str)
301     {
302         int strLen = str.length();
303         for (int i = 0; i < strLen; i++)
304         {
305             if (!Character.isWhitespace(str.charAt(i)))
306             {
307                 return true;
308             }
309         }
310         return false;
311     }
312
313     /**
314      * 格式化文本, {} 表示占位符<br>
315      * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
316      * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
317      * 例:<br>
318      * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
319      * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
320      * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
321      * 
322      * @param template 文本模板,被替换的部分用 {} 表示
323      * @param params 参数值
324      * @return 格式化后的文本
325      */
326     public static String format(String template, Object... params)
327     {
328         if (isEmpty(params) || isEmpty(template))
329         {
330             return template;
331         }
332         return StrFormatter.format(template, params);
333     }
334
335     /**
336      * 是否为http(s)://开头
337      * 
338      * @param link 链接
339      * @return 结果
340      */
341     public static boolean ishttp(String link)
342     {
343         return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
344     }
345
346     /**
347      * 字符串转set
348      * 
349      * @param str 字符串
350      * @param sep 分隔符
351      * @return set集合
352      */
353     public static final Set<String> str2Set(String str, String sep)
354     {
355         return new HashSet<String>(str2List(str, sep, true, false));
356     }
357
358     /**
359      * 字符串转list
360      * 
361      * @param str 字符串
362      * @param sep 分隔符
363      * @param filterBlank 过滤纯空白
364      * @param trim 去掉首尾空白
365      * @return list集合
366      */
367     public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
368     {
369         List<String> list = new ArrayList<String>();
370         if (StringUtils.isEmpty(str))
371         {
372             return list;
373         }
374
375         // 过滤空白字符串
376         if (filterBlank && StringUtils.isBlank(str))
377         {
378             return list;
379         }
380         String[] split = str.split(sep);
381         for (String string : split)
382         {
383             if (filterBlank && StringUtils.isBlank(string))
384             {
385                 continue;
386             }
387             if (trim)
388             {
389                 string = string.trim();
390             }
391             list.add(string);
392         }
393
394         return list;
395     }
396
397     /**
398      * 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
399      *
400      * @param collection 给定的集合
401      * @param array 给定的数组
402      * @return boolean 结果
403      */
404     public static boolean containsAny(Collection<String> collection, String... array)
405     {
406         if (isEmpty(collection) || isEmpty(array))
407         {
408             return false;
409         }
410         else
411         {
412             for (String str : array)
413             {
414                 if (collection.contains(str))
415                 {
416                     return true;
417                 }
418             }
419             return false;
420         }
421     }
422
423     /**
424      * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
425      *
426      * @param cs 指定字符串
427      * @param searchCharSequences 需要检查的字符串数组
428      * @return 是否包含任意一个字符串
429      */
430     public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences)
431     {
432         if (isEmpty(cs) || isEmpty(searchCharSequences))
433         {
434             return false;
435         }
436         for (CharSequence testStr : searchCharSequences)
437         {
438             if (containsIgnoreCase(cs, testStr))
439             {
440                 return true;
441             }
442         }
443         return false;
444     }
445
446     /**
447      * 驼峰转下划线命名
448      */
449     public static String toUnderScoreCase(String str)
450     {
451         if (str == null)
452         {
453             return null;
454         }
455         StringBuilder sb = new StringBuilder();
456         // 前置字符是否大写
457         boolean preCharIsUpperCase = true;
458         // 当前字符是否大写
459         boolean curreCharIsUpperCase = true;
460         // 下一字符是否大写
461         boolean nexteCharIsUpperCase = true;
462         for (int i = 0; i < str.length(); i++)
463         {
464             char c = str.charAt(i);
465             if (i > 0)
466             {
467                 preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
468             }
469             else
470             {
471                 preCharIsUpperCase = false;
472             }
473
474             curreCharIsUpperCase = Character.isUpperCase(c);
475
476             if (i < (str.length() - 1))
477             {
478                 nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
479             }
480
481             if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
482             {
483                 sb.append(SEPARATOR);
484             }
485             else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
486             {
487                 sb.append(SEPARATOR);
488             }
489             sb.append(Character.toLowerCase(c));
490         }
491
492         return sb.toString();
493     }
494
495     /**
496      * 是否包含字符串
497      * 
498      * @param str 验证字符串
499      * @param strs 字符串组
500      * @return 包含返回true
501      */
502     public static boolean inStringIgnoreCase(String str, String... strs)
503     {
504         if (str != null && strs != null)
505         {
506             for (String s : strs)
507             {
508                 if (str.equalsIgnoreCase(trim(s)))
509                 {
510                     return true;
511                 }
512             }
513         }
514         return false;
515     }
516
517     /**
518      * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
519      * 
520      * @param name 转换前的下划线大写方式命名的字符串
521      * @return 转换后的驼峰式命名的字符串
522      */
523     public static String convertToCamelCase(String name)
524     {
525         StringBuilder result = new StringBuilder();
526         // 快速检查
527         if (name == null || name.isEmpty())
528         {
529             // 没必要转换
530             return "";
531         }
532         else if (!name.contains("_"))
533         {
534             // 不含下划线,仅将首字母大写
535             return name.substring(0, 1).toUpperCase() + name.substring(1);
536         }
537         // 用下划线将原始字符串分割
538         String[] camels = name.split("_");
539         for (String camel : camels)
540         {
541             // 跳过原始字符串中开头、结尾的下换线或双重下划线
542             if (camel.isEmpty())
543             {
544                 continue;
545             }
546             // 首字母大写
547             result.append(camel.substring(0, 1).toUpperCase());
548             result.append(camel.substring(1).toLowerCase());
549         }
550         return result.toString();
551     }
552
553     /**
554      * 驼峰式命名法
555      * 例如:user_name->userName
556      */
557     public static String toCamelCase(String s)
558     {
559         if (s == null)
560         {
561             return null;
562         }
563         if (s.indexOf(SEPARATOR) == -1)
564         {
565             return s;
566         }
567         s = s.toLowerCase();
568         StringBuilder sb = new StringBuilder(s.length());
569         boolean upperCase = false;
570         for (int i = 0; i < s.length(); i++)
571         {
572             char c = s.charAt(i);
573
574             if (c == SEPARATOR)
575             {
576                 upperCase = true;
577             }
578             else if (upperCase)
579             {
580                 sb.append(Character.toUpperCase(c));
581                 upperCase = false;
582             }
583             else
584             {
585                 sb.append(c);
586             }
587         }
588         return sb.toString();
589     }
590
591     /**
592      * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
593      * 
594      * @param str 指定字符串
595      * @param strs 需要检查的字符串数组
596      * @return 是否匹配
597      */
598     public static boolean matches(String str, List<String> strs)
599     {
600         if (isEmpty(str) || isEmpty(strs))
601         {
602             return false;
603         }
604         for (String pattern : strs)
605         {
606             if (isMatch(pattern, str))
607             {
608                 return true;
609             }
610         }
611         return false;
612     }
613
614     /**
615      * 判断url是否与规则配置: 
616      * ? 表示单个字符; 
617      * * 表示一层路径内的任意字符串,不可跨层级; 
618      * ** 表示任意层路径;
619      * 
620      * @param pattern 匹配规则
621      * @param url 需要匹配的url
622      * @return
623      */
624     public static boolean isMatch(String pattern, String url)
625     {
626         AntPathMatcher matcher = new AntPathMatcher();
627         return matcher.match(pattern, url);
628     }
629
630     @SuppressWarnings("unchecked")
631     public static <T> T cast(Object obj)
632     {
633         return (T) obj;
634     }
635
636     /**
637      * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
638      * 
639      * @param num 数字对象
640      * @param size 字符串指定长度
641      * @return 返回数字的字符串格式,该字符串为指定长度。
642      */
643     public static final String padl(final Number num, final int size)
644     {
645         return padl(num.toString(), size, '0');
646     }
647
648     /**
649      * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
650      * 
651      * @param s 原始字符串
652      * @param size 字符串指定长度
653      * @param c 用于补齐的字符
654      * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
655      */
656     public static final String padl(final String s, final int size, final char c)
657     {
658         final StringBuilder sb = new StringBuilder(size);
659         if (s != null)
660         {
661             final int len = s.length();
662             if (s.length() <= size)
663             {
664                 for (int i = size - len; i > 0; i--)
665                 {
666                     sb.append(c);
667                 }
668                 sb.append(s);
669             }
670             else
671             {
672                 return s.substring(len - size, len);
673             }
674         }
675         else
676         {
677             for (int i = size; i > 0; i--)
678             {
679                 sb.append(c);
680             }
681         }
682         return sb.toString();
683     }
684 }