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