一、String工具类
1 package com.mkyong.common; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * 8 * String工具类. <br> 9 * 10 * @author 宋立君 11 * @date 2014年06月24日 12 */ 13 public class StringUtil { 14 15 private static final int INDEX_NOT_FOUND = -1; 16 private static final String EMPTY = ""; 17 /** 18 * <p> 19 * The maximum size to which the padding constant(s) can expand. 20 * </p> 21 */ 22 private static final int PAD_LIMIT = 8192; 23 24 /** 25 * 功能:将半角的符号转换成全角符号.(即英文字符转中文字符) 26 * 27 * @author 宋立君 28 * @param str 29 * 源字符串 30 * @return String 31 * @date 2014年06月24日 32 */ 33 public static String changeToFull(String str) { 34 String source = "[email protected]#$%^&*()abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_=+\\|[];:‘\",<.>/?"; 35 String[] decode = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", 36 "!", "@", "#", "$", "%", "︿", "&", "*", "(", ")", "a", "b", 37 "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", 38 "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 39 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", 40 "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", 41 "Y", "Z", "-", "_", "=", "+", "\", "|", "【", "】", ";", ":", 42 "‘", "\"", ",", "〈", "。", "〉", "/", "?" }; 43 String result = ""; 44 for (int i = 0; i < str.length(); i++) { 45 int pos = source.indexOf(str.charAt(i)); 46 if (pos != -1) { 47 result += decode[pos]; 48 } else { 49 result += str.charAt(i); 50 } 51 } 52 return result; 53 } 54 55 /** 56 * 功能:cs串中是否一个都不包含字符数组searchChars中的字符。 57 * 58 * @author 宋立君 59 * @param cs 60 * 字符串 61 * @param searchChars 62 * 字符数组 63 * @return boolean 都不包含返回true,否则返回false。 64 * @date 2014年06月24日 65 */ 66 public static boolean containsNone(CharSequence cs, char... searchChars) { 67 if (cs == null || searchChars == null) { 68 return true; 69 } 70 int csLen = cs.length(); 71 int csLast = csLen - 1; 72 int searchLen = searchChars.length; 73 int searchLast = searchLen - 1; 74 for (int i = 0; i < csLen; i++) { 75 char ch = cs.charAt(i); 76 for (int j = 0; j < searchLen; j++) { 77 if (searchChars[j] == ch) { 78 if (Character.isHighSurrogate(ch)) { 79 if (j == searchLast) { 80 // missing low surrogate, fine, like 81 // String.indexOf(String) 82 return false; 83 } 84 if (i < csLast 85 && searchChars[j + 1] == cs.charAt(i + 1)) { 86 return false; 87 } 88 } else { 89 // ch is in the Basic Multilingual Plane 90 return false; 91 } 92 } 93 } 94 } 95 return true; 96 } 97 98 /** 99 * <p> 100 * 编码为Unicode,格式 ‘\u0020‘. 101 * </p> 102 * 103 * @author 宋立君 104 * 105 * <pre> 106 * CharUtils.unicodeEscaped(‘ ‘) = "\u0020" 107 * CharUtils.unicodeEscaped(‘A‘) = "\u0041" 108 * </pre> 109 * 110 * @param ch 111 * 源字符串 112 * @return 转码后的字符串 113 * @date 2014年06月24日 114 */ 115 public static String unicodeEscaped(char ch) { 116 if (ch < 0x10) { 117 return "\\u000" + Integer.toHexString(ch); 118 } else if (ch < 0x100) { 119 return "\\u00" + Integer.toHexString(ch); 120 } else if (ch < 0x1000) { 121 return "\\u0" + Integer.toHexString(ch); 122 } 123 return "\\u" + Integer.toHexString(ch); 124 } 125 126 /** 127 * <p> 128 * 进行tostring操作,如果传入的是null,返回空字符串。 129 * </p> 130 * 131 * <pre> 132 * ObjectUtils.toString(null) = "" 133 * ObjectUtils.toString("") = "" 134 * ObjectUtils.toString("bat") = "bat" 135 * ObjectUtils.toString(Boolean.TRUE) = "true" 136 * </pre> 137 * 138 * @param obj 139 * 源 140 * @return String 141 */ 142 public static String toString(Object obj) { 143 return obj == null ? "" : obj.toString(); 144 } 145 146 /** 147 * <p> 148 * 进行tostring操作,如果传入的是null,返回指定的默认值。 149 * </p> 150 * 151 * <pre> 152 * ObjectUtils.toString(null, null) = null 153 * ObjectUtils.toString(null, "null") = "null" 154 * ObjectUtils.toString("", "null") = "" 155 * ObjectUtils.toString("bat", "null") = "bat" 156 * ObjectUtils.toString(Boolean.TRUE, "null") = "true" 157 * </pre> 158 * 159 * @param obj 160 * 源 161 * @param nullStr 162 * 如果obj为null时返回这个指定值 163 * @return String 164 */ 165 public static String toString(Object obj, String nullStr) { 166 return obj == null ? nullStr : obj.toString(); 167 } 168 169 /** 170 * <p> 171 * 只从源字符串中移除指定开头子字符串. 172 * </p> 173 * 174 * <pre> 175 * StringUtil.removeStart(null, *) = null 176 * StringUtil.removeStart("", *) = "" 177 * StringUtil.removeStart(*, null) = * 178 * StringUtil.removeStart("www.domain.com", "www.") = "domain.com" 179 * StringUtil.removeStart("domain.com", "www.") = "domain.com" 180 * StringUtil.removeStart("www.domain.com", "domain") = "www.domain.com" 181 * StringUtil.removeStart("abc", "") = "abc" 182 * </pre> 183 * 184 * @param str 185 * 源字符串 186 * @param remove 187 * 将要被移除的子字符串 188 * @return String 189 */ 190 public static String removeStart(String str, String remove) { 191 if (isEmpty(str) || isEmpty(remove)) { 192 return str; 193 } 194 if (str.startsWith(remove)) { 195 return str.substring(remove.length()); 196 } 197 return str; 198 } 199 200 /** 201 * <p> 202 * 只从源字符串中移除指定结尾的子字符串. 203 * </p> 204 * 205 * <pre> 206 * StringUtil.removeEnd(null, *) = null 207 * StringUtil.removeEnd("", *) = "" 208 * StringUtil.removeEnd(*, null) = * 209 * StringUtil.removeEnd("www.domain.com", ".com.") = "www.domain.com" 210 * StringUtil.removeEnd("www.domain.com", ".com") = "www.domain" 211 * StringUtil.removeEnd("www.domain.com", "domain") = "www.domain.com" 212 * StringUtil.removeEnd("abc", "") = "abc" 213 * </pre> 214 * 215 * @param str 216 * 源字符串 217 * @param remove 218 * 将要被移除的子字符串 219 * @return String 220 */ 221 public static String removeEnd(String str, String remove) { 222 if (isEmpty(str) || isEmpty(remove)) { 223 return str; 224 } 225 if (str.endsWith(remove)) { 226 return str.substring(0, str.length() - remove.length()); 227 } 228 return str; 229 } 230 231 /** 232 * <p> 233 * 将一个字符串重复N次 234 * </p> 235 * 236 * <pre> 237 * StringUtil.repeat(null, 2) = null 238 * StringUtil.repeat("", 0) = "" 239 * StringUtil.repeat("", 2) = "" 240 * StringUtil.repeat("a", 3) = "aaa" 241 * StringUtil.repeat("ab", 2) = "abab" 242 * StringUtil.repeat("a", -2) = "" 243 * </pre> 244 * 245 * @param str 246 * 源字符串 247 * @param repeat 248 * 重复的次数 249 * @return String 250 */ 251 public static String repeat(String str, int repeat) { 252 // Performance tuned for 2.0 (JDK1.4) 253 254 if (str == null) { 255 return null; 256 } 257 if (repeat <= 0) { 258 return EMPTY; 259 } 260 int inputLength = str.length(); 261 if (repeat == 1 || inputLength == 0) { 262 return str; 263 } 264 if (inputLength == 1 && repeat <= PAD_LIMIT) { 265 return repeat(str.charAt(0), repeat); 266 } 267 268 int outputLength = inputLength * repeat; 269 switch (inputLength) { 270 case 1: 271 return repeat(str.charAt(0), repeat); 272 case 2: 273 char ch0 = str.charAt(0); 274 char ch1 = str.charAt(1); 275 char[] output2 = new char[outputLength]; 276 for (int i = repeat * 2 - 2; i >= 0; i--, i--) { 277 output2[i] = ch0; 278 output2[i + 1] = ch1; 279 } 280 return new String(output2); 281 default: 282 StringBuilder buf = new StringBuilder(outputLength); 283 for (int i = 0; i < repeat; i++) { 284 buf.append(str); 285 } 286 return buf.toString(); 287 } 288 } 289 290 /** 291 * <p> 292 * 将一个字符串重复N次,并且中间加上指定的分隔符 293 * </p> 294 * 295 * <pre> 296 * StringUtil.repeat(null, null, 2) = null 297 * StringUtil.repeat(null, "x", 2) = null 298 * StringUtil.repeat("", null, 0) = "" 299 * StringUtil.repeat("", "", 2) = "" 300 * StringUtil.repeat("", "x", 3) = "xxx" 301 * StringUtil.repeat("?", ", ", 3) = "?, ?, ?" 302 * </pre> 303 * 304 * @param str 305 * 源字符串 306 * @param separator 307 * 分隔符 308 * @param repeat 309 * 重复次数 310 * @return String 311 */ 312 public static String repeat(String str, String separator, int repeat) { 313 if (str == null || separator == null) { 314 return repeat(str, repeat); 315 } else { 316 // given that repeat(String, int) is quite optimized, better to rely 317 // on it than try and splice this into it 318 String result = repeat(str + separator, repeat); 319 return removeEnd(result, separator); 320 } 321 } 322 323 /** 324 * <p> 325 * 将某个字符重复N次. 326 * </p> 327 * 328 * @param ch 329 * 某个字符 330 * @param repeat 331 * 重复次数 332 * @return String 333 */ 334 public static String repeat(char ch, int repeat) { 335 char[] buf = new char[repeat]; 336 for (int i = repeat - 1; i >= 0; i--) { 337 buf[i] = ch; 338 } 339 return new String(buf); 340 } 341 342 /** 343 * <p> 344 * 字符串长度达不到指定长度时,在字符串右边补指定的字符. 345 * </p> 346 * 347 * <pre> 348 * StringUtil.rightPad(null, *, *) = null 349 * StringUtil.rightPad("", 3, ‘z‘) = "zzz" 350 * StringUtil.rightPad("bat", 3, ‘z‘) = "bat" 351 * StringUtil.rightPad("bat", 5, ‘z‘) = "batzz" 352 * StringUtil.rightPad("bat", 1, ‘z‘) = "bat" 353 * StringUtil.rightPad("bat", -1, ‘z‘) = "bat" 354 * </pre> 355 * 356 * @param str 357 * 源字符串 358 * @param size 359 * 指定的长度 360 * @param padChar 361 * 进行补充的字符 362 * @return String 363 */ 364 public static String rightPad(String str, int size, char padChar) { 365 if (str == null) { 366 return null; 367 } 368 int pads = size - str.length(); 369 if (pads <= 0) { 370 return str; // returns original String when possible 371 } 372 if (pads > PAD_LIMIT) { 373 return rightPad(str, size, String.valueOf(padChar)); 374 } 375 return str.concat(repeat(padChar, pads)); 376 } 377 378 /** 379 * <p> 380 * 扩大字符串长度,从左边补充指定字符 381 * </p> 382 * 383 * <pre> 384 * StringUtil.rightPad(null, *, *) = null 385 * StringUtil.rightPad("", 3, "z") = "zzz" 386 * StringUtil.rightPad("bat", 3, "yz") = "bat" 387 * StringUtil.rightPad("bat", 5, "yz") = "batyz" 388 * StringUtil.rightPad("bat", 8, "yz") = "batyzyzy" 389 * StringUtil.rightPad("bat", 1, "yz") = "bat" 390 * StringUtil.rightPad("bat", -1, "yz") = "bat" 391 * StringUtil.rightPad("bat", 5, null) = "bat " 392 * StringUtil.rightPad("bat", 5, "") = "bat " 393 * </pre> 394 * 395 * @param str 396 * 源字符串 397 * @param size 398 * 扩大后的长度 399 * @param padStr 400 * 在右边补充的字符串 401 * @return String 402 */ 403 public static String rightPad(String str, int size, String padStr) { 404 if (str == null) { 405 return null; 406 } 407 if (isEmpty(padStr)) { 408 padStr = " "; 409 } 410 int padLen = padStr.length(); 411 int strLen = str.length(); 412 int pads = size - strLen; 413 if (pads <= 0) { 414 return str; // returns original String when possible 415 } 416 if (padLen == 1 && pads <= PAD_LIMIT) { 417 return rightPad(str, size, padStr.charAt(0)); 418 } 419 420 if (pads == padLen) { 421 return str.concat(padStr); 422 } else if (pads < padLen) { 423 return str.concat(padStr.substring(0, pads)); 424 } else { 425 char[] padding = new char[pads]; 426 char[] padChars = padStr.toCharArray(); 427 for (int i = 0; i < pads; i++) { 428 padding[i] = padChars[i % padLen]; 429 } 430 return str.concat(new String(padding)); 431 } 432 } 433 434 /** 435 * <p> 436 * 扩大字符串长度,从左边补充空格 437 * </p> 438 * 439 * <pre> 440 * StringUtil.leftPad(null, *) = null 441 * StringUtil.leftPad("", 3) = " " 442 * StringUtil.leftPad("bat", 3) = "bat" 443 * StringUtil.leftPad("bat", 5) = " bat" 444 * StringUtil.leftPad("bat", 1) = "bat" 445 * StringUtil.leftPad("bat", -1) = "bat" 446 * </pre> 447 * 448 * @param str 449 * 源字符串 450 * @param size 451 * 扩大后的长度 452 * @return String 453 */ 454 public static String leftPad(String str, int size) { 455 return leftPad(str, size, ‘ ‘); 456 } 457 458 /** 459 * <p> 460 * 扩大字符串长度,从左边补充指定的字符 461 * </p> 462 * 463 * <pre> 464 * StringUtil.leftPad(null, *, *) = null 465 * StringUtil.leftPad("", 3, ‘z‘) = "zzz" 466 * StringUtil.leftPad("bat", 3, ‘z‘) = "bat" 467 * StringUtil.leftPad("bat", 5, ‘z‘) = "zzbat" 468 * StringUtil.leftPad("bat", 1, ‘z‘) = "bat" 469 * StringUtil.leftPad("bat", -1, ‘z‘) = "bat" 470 * </pre> 471 * 472 * @param str 473 * 源字符串 474 * @param size 475 * 扩大后的长度 476 * @param padStr 477 * 补充的字符 478 * @return String 479 */ 480 public static String leftPad(String str, int size, char padChar) { 481 if (str == null) { 482 return null; 483 } 484 int pads = size - str.length(); 485 if (pads <= 0) { 486 return str; // returns original String when possible 487 } 488 if (pads > PAD_LIMIT) { 489 return leftPad(str, size, String.valueOf(padChar)); 490 } 491 return repeat(padChar, pads).concat(str); 492 } 493 494 /** 495 * <p> 496 * 扩大字符串长度,从左边补充指定的字符 497 * </p> 498 * 499 * <pre> 500 * StringUtil.leftPad(null, *, *) = null 501 * StringUtil.leftPad("", 3, "z") = "zzz" 502 * StringUtil.leftPad("bat", 3, "yz") = "bat" 503 * StringUtil.leftPad("bat", 5, "yz") = "yzbat" 504 * StringUtil.leftPad("bat", 8, "yz") = "yzyzybat" 505 * StringUtil.leftPad("bat", 1, "yz") = "bat" 506 * StringUtil.leftPad("bat", -1, "yz") = "bat" 507 * StringUtil.leftPad("bat", 5, null) = " bat" 508 * StringUtil.leftPad("bat", 5, "") = " bat" 509 * </pre> 510 * 511 * @param str 512 * 源字符串 513 * @param size 514 * 扩大后的长度 515 * @param padStr 516 * 补充的字符串 517 * @return String 518 */ 519 public static String leftPad(String str, int size, String padStr) { 520 if (str == null) { 521 return null; 522 } 523 if (isEmpty(padStr)) { 524 padStr = " "; 525 } 526 int padLen = padStr.length(); 527 int strLen = str.length(); 528 int pads = size - strLen; 529 if (pads <= 0) { 530 return str; // returns original String when possible 531 } 532 if (padLen == 1 && pads <= PAD_LIMIT) { 533 return leftPad(str, size, padStr.charAt(0)); 534 } 535 536 if (pads == padLen) { 537 return padStr.concat(str); 538 } else if (pads < padLen) { 539 return padStr.substring(0, pads).concat(str); 540 } else { 541 char[] padding = new char[pads]; 542 char[] padChars = padStr.toCharArray(); 543 for (int i = 0; i < pads; i++) { 544 padding[i] = padChars[i % padLen]; 545 } 546 return new String(padding).concat(str); 547 } 548 } 549 550 /** 551 * <p> 552 * 扩大字符串长度并将现在的字符串居中,被扩大部分用空格填充。 553 * <p> 554 * 555 * <pre> 556 * StringUtil.center(null, *) = null 557 * StringUtil.center("", 4) = " " 558 * StringUtil.center("ab", -1) = "ab" 559 * StringUtil.center("ab", 4) = " ab " 560 * StringUtil.center("abcd", 2) = "abcd" 561 * StringUtil.center("a", 4) = " a " 562 * </pre> 563 * 564 * @param str 565 * 源字符串 566 * @param size 567 * 扩大后的长度 568 * @return String 569 */ 570 public static String center(String str, int size) { 571 return center(str, size, ‘ ‘); 572 } 573 574 /** 575 * <p> 576 * 将字符串长度修改为指定长度,并进行居中显示。 577 * </p> 578 * 579 * <pre> 580 * StringUtil.center(null, *, *) = null 581 * StringUtil.center("", 4, ‘ ‘) = " " 582 * StringUtil.center("ab", -1, ‘ ‘) = "ab" 583 * StringUtil.center("ab", 4, ‘ ‘) = " ab" 584 * StringUtil.center("abcd", 2, ‘ ‘) = "abcd" 585 * StringUtil.center("a", 4, ‘ ‘) = " a " 586 * StringUtil.center("a", 4, ‘y‘) = "yayy" 587 * </pre> 588 * 589 * @param str 590 * 源字符串 591 * @param size 592 * 指定的长度 593 * @param padStr 594 * 长度不够时补充的字符串 595 * @return String 596 * @throws IllegalArgumentException 597 * 如果被补充字符串为 null或者 empty 598 */ 599 public static String center(String str, int size, char padChar) { 600 if (str == null || size <= 0) { 601 return str; 602 } 603 int strLen = str.length(); 604 int pads = size - strLen; 605 if (pads <= 0) { 606 return str; 607 } 608 str = leftPad(str, strLen + pads / 2, padChar); 609 str = rightPad(str, size, padChar); 610 return str; 611 } 612 613 /** 614 * <p> 615 * 将字符串长度修改为指定长度,并进行居中显示。 616 * </p> 617 * 618 * <pre> 619 * StringUtil.center(null, *, *) = null 620 * StringUtil.center("", 4, " ") = " " 621 * StringUtil.center("ab", -1, " ") = "ab" 622 * StringUtil.center("ab", 4, " ") = " ab" 623 * StringUtil.center("abcd", 2, " ") = "abcd" 624 * StringUtil.center("a", 4, " ") = " a " 625 * StringUtil.center("a", 4, "yz") = "yayz" 626 * StringUtil.center("abc", 7, null) = " abc " 627 * StringUtil.center("abc", 7, "") = " abc " 628 * </pre> 629 * 630 * @param str 631 * 源字符串 632 * @param size 633 * 指定的长度 634 * @param padStr 635 * 长度不够时补充的字符串 636 * @return String 637 * @throws IllegalArgumentException 638 * 如果被补充字符串为 null或者 empty 639 */ 640 public static String center(String str, int size, String padStr) { 641 if (str == null || size <= 0) { 642 return str; 643 } 644 if (isEmpty(padStr)) { 645 padStr = " "; 646 } 647 int strLen = str.length(); 648 int pads = size - strLen; 649 if (pads <= 0) { 650 return str; 651 } 652 str = leftPad(str, strLen + pads / 2, padStr); 653 str = rightPad(str, size, padStr); 654 return str; 655 } 656 657 /** 658 * <p> 659 * 检查字符串是否全部为小写. 660 * </p> 661 * 662 * <pre> 663 * StringUtil.isAllLowerCase(null) = false 664 * StringUtil.isAllLowerCase("") = false 665 * StringUtil.isAllLowerCase(" ") = false 666 * StringUtil.isAllLowerCase("abc") = true 667 * StringUtil.isAllLowerCase("abC") = false 668 * </pre> 669 * 670 * @param cs 671 * 源字符串 672 * @return String 673 */ 674 public static boolean isAllLowerCase(String cs) { 675 if (cs == null || isEmpty(cs)) { 676 return false; 677 } 678 int sz = cs.length(); 679 for (int i = 0; i < sz; i++) { 680 if (Character.isLowerCase(cs.charAt(i)) == false) { 681 return false; 682 } 683 } 684 return true; 685 } 686 687 /** 688 * <p> 689 * 检查是否都是大写. 690 * </p> 691 * 692 * <pre> 693 * StringUtil.isAllUpperCase(null) = false 694 * StringUtil.isAllUpperCase("") = false 695 * StringUtil.isAllUpperCase(" ") = false 696 * StringUtil.isAllUpperCase("ABC") = true 697 * StringUtil.isAllUpperCase("aBC") = false 698 * </pre> 699 * 700 * @param cs 701 * 源字符串 702 * @return String 703 */ 704 public static boolean isAllUpperCase(String cs) { 705 if (cs == null || StringUtil.isEmpty(cs)) { 706 return false; 707 } 708 int sz = cs.length(); 709 for (int i = 0; i < sz; i++) { 710 if (Character.isUpperCase(cs.charAt(i)) == false) { 711 return false; 712 } 713 } 714 return true; 715 } 716 717 /** 718 * <p> 719 * 反转字符串. 720 * </p> 721 * 722 * <pre> 723 * StringUtil.reverse(null) = null 724 * StringUtil.reverse("") = "" 725 * StringUtil.reverse("bat") = "tab" 726 * </pre> 727 * 728 * @param str 729 * 源字符串 730 * @return String 731 */ 732 public static String reverse(String str) { 733 if (str == null) { 734 return null; 735 } 736 return new StringBuilder(str).reverse().toString(); 737 } 738 739 /** 740 * <p> 741 * 字符串达不到一定长度时在右边补空白. 742 * </p> 743 * 744 * <pre> 745 * StringUtil.rightPad(null, *) = null 746 * StringUtil.rightPad("", 3) = " " 747 * StringUtil.rightPad("bat", 3) = "bat" 748 * StringUtil.rightPad("bat", 5) = "bat " 749 * StringUtil.rightPad("bat", 1) = "bat" 750 * StringUtil.rightPad("bat", -1) = "bat" 751 * </pre> 752 * 753 * @param str 754 * 源字符串 755 * @param size 756 * 指定的长度 757 * @return String 758 */ 759 public static String rightPad(String str, int size) { 760 return rightPad(str, size, ‘ ‘); 761 } 762 763 /** 764 * 从右边截取字符串.</p> 765 * 766 * <pre> 767 * StringUtil.right(null, *) = null 768 * StringUtil.right(*, -ve) = "" 769 * StringUtil.right("", *) = "" 770 * StringUtil.right("abc", 0) = "" 771 * StringUtil.right("abc", 2) = "bc" 772 * StringUtil.right("abc", 4) = "abc" 773 * </pre> 774 * 775 * @param str 776 * 源字符串 777 * @param len 778 * 长度 779 * @return String 780 */ 781 public static String right(String str, int len) { 782 if (str == null) { 783 return null; 784 } 785 if (len < 0) { 786 return EMPTY; 787 } 788 if (str.length() <= len) { 789 return str; 790 } 791 return str.substring(str.length() - len); 792 } 793 794 /** 795 * <p> 796 * 截取一个字符串的前几个. 797 * </p> 798 * 799 * <pre> 800 * StringUtil.left(null, *) = null 801 * StringUtil.left(*, -ve) = "" 802 * StringUtil.left("", *) = "" 803 * StringUtil.left("abc", 0) = "" 804 * StringUtil.left("abc", 2) = "ab" 805 * StringUtil.left("abc", 4) = "abc" 806 * </pre> 807 * 808 * @param str 809 * 源字符串 810 * @param len 811 * 截取的长度 812 * @return the String 813 */ 814 public static String left(String str, int len) { 815 if (str == null) { 816 return null; 817 } 818 if (len < 0) { 819 return EMPTY; 820 } 821 if (str.length() <= len) { 822 return str; 823 } 824 return str.substring(0, len); 825 } 826 827 /** 828 * <p> 829 * 得到tag字符串中间的子字符串,只返回第一个匹配项。 830 * </p> 831 * 832 * <pre> 833 * StringUtil.substringBetween(null, *) = null 834 * StringUtil.substringBetween("", "") = "" 835 * StringUtil.substringBetween("", "tag") = null 836 * StringUtil.substringBetween("tagabctag", null) = null 837 * StringUtil.substringBetween("tagabctag", "") = "" 838 * StringUtil.substringBetween("tagabctag", "tag") = "abc" 839 * </pre> 840 * 841 * @param str 842 * 源字符串。 843 * @param tag 844 * 标识字符串。 845 * @return String 子字符串, 如果没有符合要求的,返回{@code null}。 846 */ 847 public static String substringBetween(String str, String tag) { 848 return substringBetween(str, tag, tag); 849 } 850 851 /** 852 * <p> 853 * 得到两个字符串中间的子字符串,只返回第一个匹配项。 854 * </p> 855 * 856 * <pre> 857 * StringUtil.substringBetween("wx[b]yz", "[", "]") = "b" 858 * StringUtil.substringBetween(null, *, *) = null 859 * StringUtil.substringBetween(*, null, *) = null 860 * StringUtil.substringBetween(*, *, null) = null 861 * StringUtil.substringBetween("", "", "") = "" 862 * StringUtil.substringBetween("", "", "]") = null 863 * StringUtil.substringBetween("", "[", "]") = null 864 * StringUtil.substringBetween("yabcz", "", "") = "" 865 * StringUtil.substringBetween("yabcz", "y", "z") = "abc" 866 * StringUtil.substringBetween("yabczyabcz", "y", "z") = "abc" 867 * </pre> 868 * 869 * @param str 870 * 源字符串 871 * @param open 872 * 起字符串。 873 * @param close 874 * 末字符串。 875 * @return String 子字符串, 如果没有符合要求的,返回{@code null}。 876 */ 877 public static String substringBetween(String str, String open, String close) { 878 if (str == null || open == null || close == null) { 879 return null; 880 } 881 int start = str.indexOf(open); 882 if (start != INDEX_NOT_FOUND) { 883 int end = str.indexOf(close, start + open.length()); 884 if (end != INDEX_NOT_FOUND) { 885 return str.substring(start + open.length(), end); 886 } 887 } 888 return null; 889 } 890 891 /** 892 * <p> 893 * 得到两个字符串中间的子字符串,所有匹配项组合为数组并返回。 894 * </p> 895 * 896 * <pre> 897 * StringUtil.substringsBetween("[a][b][c]", "[", "]") = ["a","b","c"] 898 * StringUtil.substringsBetween(null, *, *) = null 899 * StringUtil.substringsBetween(*, null, *) = null 900 * StringUtil.substringsBetween(*, *, null) = null 901 * StringUtil.substringsBetween("", "[", "]") = [] 902 * </pre> 903 * 904 * @param str 905 * 源字符串 906 * @param open 907 * 起字符串。 908 * @param close 909 * 末字符串。 910 * @return String 子字符串数组, 如果没有符合要求的,返回{@code null}。 911 */ 912 public static String[] substringsBetween(String str, String open, 913 String close) { 914 if (str == null || isEmpty(open) || isEmpty(close)) { 915 return null; 916 } 917 int strLen = str.length(); 918 if (strLen == 0) { 919 return new String[0]; 920 } 921 int closeLen = close.length(); 922 int openLen = open.length(); 923 List<String> list = new ArrayList<String>(); 924 int pos = 0; 925 while (pos < strLen - closeLen) { 926 int start = str.indexOf(open, pos); 927 if (start < 0) { 928 break; 929 } 930 start += openLen; 931 int end = str.indexOf(close, start); 932 if (end < 0) { 933 break; 934 } 935 list.add(str.substring(start, end)); 936 pos = end + closeLen; 937 } 938 if (list.isEmpty()) { 939 return null; 940 } 941 return list.toArray(new String[list.size()]); 942 } 943 944 /** 945 * 功能:切换字符串中的所有字母大小写。<br/> 946 * 947 * <pre> 948 * StringUtil.swapCase(null) = null 949 * StringUtil.swapCase("") = "" 950 * StringUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone" 951 * </pre> 952 * 953 * 954 * @param str 955 * 源字符串 956 * @return String 957 */ 958 public static String swapCase(String str) { 959 if (StringUtil.isEmpty(str)) { 960 return str; 961 } 962 char[] buffer = str.toCharArray(); 963 964 boolean whitespace = true; 965 966 for (int i = 0; i < buffer.length; i++) { 967 char ch = buffer[i]; 968 if (Character.isUpperCase(ch)) { 969 buffer[i] = Character.toLowerCase(ch); 970 whitespace = false; 971 } else if (Character.isTitleCase(ch)) { 972 buffer[i] = Character.toLowerCase(ch); 973 whitespace = false; 974 } else if (Character.isLowerCase(ch)) { 975 if (whitespace) { 976 buffer[i] = Character.toTitleCase(ch); 977 whitespace = false; 978 } else { 979 buffer[i] = Character.toUpperCase(ch); 980 } 981 } else { 982 whitespace = Character.isWhitespace(ch); 983 } 984 } 985 return new String(buffer); 986 } 987 988 /** 989 * 功能:截取出最后一个标志位之后的字符串.<br/> 990 * 如果sourceStr为empty或者expr为null,直接返回源字符串。<br/> 991 * 如果expr长度为0,直接返回sourceStr。<br/> 992 * 如果expr在sourceStr中不存在,直接返回sourceStr。<br/> 993 * 994 * @author 宋立君 995 * @date 2014年06月24日 996 * @param sourceStr 997 * 被截取的字符串 998 * @param expr 999 * 分隔符 1000 * @return String 1001 */ 1002 public static String substringAfterLast(String sourceStr, String expr) { 1003 if (isEmpty(sourceStr) || expr == null) { 1004 return sourceStr; 1005 } 1006 if (expr.length() == 0) { 1007 return sourceStr; 1008 } 1009 1010 int pos = sourceStr.lastIndexOf(expr); 1011 if (pos == -1) { 1012 return sourceStr; 1013 } 1014 return sourceStr.substring(pos + expr.length()); 1015 } 1016 1017 /** 1018 * 功能:截取出最后一个标志位之前的字符串.<br/> 1019 * 如果sourceStr为empty或者expr为null,直接返回源字符串。<br/> 1020 * 如果expr长度为0,直接返回sourceStr。<br/> 1021 * 如果expr在sourceStr中不存在,直接返回sourceStr。<br/> 1022 * 1023 * @author 宋立君 1024 * @date 2014年06月24日 1025 * @param sourceStr 1026 * 被截取的字符串 1027 * @param expr 1028 * 分隔符 1029 * @return String 1030 */ 1031 public static String substringBeforeLast(String sourceStr, String expr) { 1032 if (isEmpty(sourceStr) || expr == null) { 1033 return sourceStr; 1034 } 1035 if (expr.length() == 0) { 1036 return sourceStr; 1037 } 1038 int pos = sourceStr.lastIndexOf(expr); 1039 if (pos == -1) { 1040 return sourceStr; 1041 } 1042 return sourceStr.substring(0, pos); 1043 } 1044 1045 /** 1046 * 功能:截取出第一个标志位之后的字符串.<br/> 1047 * 如果sourceStr为empty或者expr为null,直接返回源字符串。<br/> 1048 * 如果expr长度为0,直接返回sourceStr。<br/> 1049 * 如果expr在sourceStr中不存在,直接返回sourceStr。<br/> 1050 * 1051 * @author 宋立君 1052 * @date 2014年06月24日 1053 * @param sourceStr 1054 * 被截取的字符串 1055 * @param expr 1056 * 分隔符 1057 * @return String 1058 */ 1059 public static String substringAfter(String sourceStr, String expr) { 1060 if (isEmpty(sourceStr) || expr == null) { 1061 return sourceStr; 1062 } 1063 if (expr.length() == 0) { 1064 return sourceStr; 1065 } 1066 1067 int pos = sourceStr.indexOf(expr); 1068 if (pos == -1) { 1069 return sourceStr; 1070 } 1071 return sourceStr.substring(pos + expr.length()); 1072 } 1073 1074 /** 1075 * 功能:截取出第一个标志位之前的字符串.<br/> 1076 * 如果sourceStr为empty或者expr为null,直接返回源字符串。<br/> 1077 * 如果expr长度为0,直接返回sourceStr。<br/> 1078 * 如果expr在sourceStr中不存在,直接返回sourceStr。<br/> 1079 * 如果expr在sourceStr中存在不止一个,以第一个位置为准。 1080 * 1081 * @author 宋立君 1082 * @date 2014年06月24日 1083 * @param sourceStr 1084 * 被截取的字符串 1085 * @param expr 1086 * 分隔符 1087 * @return String 1088 */ 1089 public static String substringBefore(String sourceStr, String expr) { 1090 if (isEmpty(sourceStr) || expr == null) { 1091 return sourceStr; 1092 } 1093 if (expr.length() == 0) { 1094 return sourceStr; 1095 } 1096 int pos = sourceStr.indexOf(expr); 1097 if (pos == -1) { 1098 return sourceStr; 1099 } 1100 return sourceStr.substring(0, pos); 1101 } 1102 1103 /** 1104 * 功能:检查这个字符串是不是空字符串。<br/> 1105 * 如果这个字符串为null或者trim后为空字符串则返回true,否则返回false。 1106 * 1107 * @author 宋立君 1108 * @date 2014年06月24日 1109 * @param chkStr 1110 * 被检查的字符串 1111 * @return boolean 1112 */ 1113 public static boolean isEmpty(String chkStr) { 1114 if (chkStr == null) { 1115 return true; 1116 } else { 1117 return "".equals(chkStr.trim()) ? true : false; 1118 } 1119 } 1120 1121 /** 1122 * 如果字符串没有超过最长显示长度返回原字符串,否则从开头截取指定长度并加...返回。 1123 * 1124 * @param str 1125 * 原字符串 1126 * @param length 1127 * 字符串最长显示的长度 1128 * @return 转换后的字符串 1129 */ 1130 public static String trimString(String str, int length) { 1131 if (str == null) { 1132 return ""; 1133 } else if (str.length() > length) { 1134 return str.substring(0, length - 3) + "..."; 1135 } else { 1136 return str; 1137 } 1138 } 1139 1140 }
二、MD5
1 package com.mkyong.common; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.IOException; 6 import java.nio.MappedByteBuffer; 7 import java.nio.channels.FileChannel; 8 import java.security.MessageDigest; 9 import java.security.NoSuchAlgorithmException; 10 11 /** 12 * 13 * String工具类. <br> 14 * 15 * @author 宋立君 16 * @date 2014年06月24日 17 */ 18 public class MD5Util { 19 20 protected static char hexDigits[] = { ‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, 21 ‘7‘, ‘8‘, ‘9‘, ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘ }; 22 23 protected static MessageDigest messagedigest = null; 24 25 static { 26 try { 27 messagedigest = MessageDigest.getInstance("MD5"); 28 } catch (NoSuchAlgorithmException nsaex) { 29 System.err.println(MD5Util.class.getName() 30 + "初始化失败,MessageDigest不支持MD5Util。"); 31 nsaex.printStackTrace(); 32 } 33 } 34 35 /** 36 * 功能:加盐版的MD5.返回格式为MD5(密码+{盐值}) 37 * 38 * @author 宋立君 39 * @date 2014年06月24日 40 * @param password 41 * 密码 42 * @param salt 43 * 盐值 44 * @return String 45 */ 46 public static String getMD5StringWithSalt(String password, String salt) { 47 if (password == null) { 48 throw new IllegalArgumentException("password不能为null"); 49 } 50 if (StringUtil.isEmpty(salt)) { 51 throw new IllegalArgumentException("salt不能为空"); 52 } 53 if ((salt.toString().lastIndexOf("{") != -1) 54 || (salt.toString().lastIndexOf("}") != -1)) { 55 throw new IllegalArgumentException("salt中不能包含 { 或者 }"); 56 } 57 return getMD5String(password + "{" + salt.toString() + "}"); 58 } 59 60 /** 61 * 功能:得到文件的md5值。 62 * 63 * @author 宋立君 64 * @date 2014年06月24日 65 * @param file 66 * 文件。 67 * @return String 68 * @throws IOException 69 * 读取文件IO异常时。 70 */ 71 public static String getFileMD5String(File file) throws IOException { 72 FileInputStream in = new FileInputStream(file); 73 FileChannel ch = in.getChannel(); 74 MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, 75 file.length()); 76 messagedigest.update(byteBuffer); 77 return bufferToHex(messagedigest.digest()); 78 } 79 80 /** 81 * 功能:得到一个字符串的MD5值。 82 * 83 * @author 宋立君 84 * @date 2014年06月24日 85 * @param str 86 * 字符串 87 * @return String 88 */ 89 public static String getMD5String(String str) { 90 return getMD5String(str.getBytes()); 91 } 92 93 private static String getMD5String(byte[] bytes) { 94 messagedigest.update(bytes); 95 return bufferToHex(messagedigest.digest()); 96 } 97 98 private static String bufferToHex(byte bytes[]) { 99 return bufferToHex(bytes, 0, bytes.length); 100 } 101 102 private static String bufferToHex(byte bytes[], int m, int n) { 103 StringBuffer stringbuffer = new StringBuffer(2 * n); 104 int k = m + n; 105 for (int l = m; l < k; l++) { 106 appendHexPair(bytes[l], stringbuffer); 107 } 108 return stringbuffer.toString(); 109 } 110 111 private static void appendHexPair(byte bt, StringBuffer stringbuffer) { 112 char c0 = hexDigits[(bt & 0xf0) >> 4]; 113 char c1 = hexDigits[bt & 0xf]; 114 stringbuffer.append(c0); 115 stringbuffer.append(c1); 116 } 117 }
三、File工具类
1 package com.mkyong.common; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.io.OutputStream; 10 11 /** 12 * 文件相关操作辅助类。 13 * 14 * @author 宋立君 15 * @date 2014年06月24日 16 */ 17 public class FileUtil { 18 private static final String FOLDER_SEPARATOR = "/"; 19 private static final char EXTENSION_SEPARATOR = ‘.‘; 20 21 /** 22 * 功能:复制文件或者文件夹。 23 * 24 * @author 宋立君 25 * @date 2014年06月24日 26 * @param inputFile 27 * 源文件 28 * @param outputFile 29 * 目的文件 30 * @param isOverWrite 31 * 是否覆盖(只针对文件) 32 * @throws IOException 33 */ 34 public static void copy(File inputFile, File outputFile, boolean isOverWrite) 35 throws IOException { 36 if (!inputFile.exists()) { 37 throw new RuntimeException(inputFile.getPath() + "源目录不存在!"); 38 } 39 copyPri(inputFile, outputFile, isOverWrite); 40 } 41 42 /** 43 * 功能:为copy 做递归使用。 44 * 45 * @author 宋立君 46 * @date 2014年06月24日 47 * @param inputFile 48 * @param outputFile 49 * @param isOverWrite 50 * @throws IOException 51 */ 52 private static void copyPri(File inputFile, File outputFile, 53 boolean isOverWrite) throws IOException { 54 // 是个文件。 55 if (inputFile.isFile()) { 56 copySimpleFile(inputFile, outputFile, isOverWrite); 57 } else { 58 // 文件夹 59 if (!outputFile.exists()) { 60 outputFile.mkdir(); 61 } 62 // 循环子文件夹 63 for (File child : inputFile.listFiles()) { 64 copy(child, 65 new File(outputFile.getPath() + "/" + child.getName()), 66 isOverWrite); 67 } 68 } 69 } 70 71 /** 72 * 功能:copy单个文件 73 * 74 * @author 宋立君 75 * @date 2014年06月24日 76 * @param inputFile 77 * 源文件 78 * @param outputFile 79 * 目标文件 80 * @param isOverWrite 81 * 是否允许覆盖 82 * @throws IOException 83 */ 84 private static void copySimpleFile(File inputFile, File outputFile, 85 boolean isOverWrite) throws IOException { 86 // 目标文件已经存在 87 if (outputFile.exists()) { 88 if (isOverWrite) { 89 if (!outputFile.delete()) { 90 throw new RuntimeException(outputFile.getPath() + "无法覆盖!"); 91 } 92 } else { 93 // 不允许覆盖 94 return; 95 } 96 } 97 InputStream in = new FileInputStream(inputFile); 98 OutputStream out = new FileOutputStream(outputFile); 99 byte[] buffer = new byte[1024]; 100 int read = 0; 101 while ((read = in.read(buffer)) != -1) { 102 out.write(buffer, 0, read); 103 } 104 in.close(); 105 out.close(); 106 } 107 108 /** 109 * 功能:删除文件 110 * 111 * @author 宋立君 112 * @date 2014年06月24日 113 * @param file 114 * 文件 115 */ 116 public static void delete(File file) { 117 deleteFile(file); 118 } 119 120 /** 121 * 功能:删除文件,内部递归使用 122 * 123 * @author 宋立君 124 * @date 2014年06月24日 125 * @param file 126 * 文件 127 * @return boolean true 删除成功,false 删除失败。 128 */ 129 private static void deleteFile(File file) { 130 if (file == null || !file.exists()) { 131 return; 132 } 133 // 单文件 134 if (!file.isDirectory()) { 135 boolean delFlag = file.delete(); 136 if (!delFlag) { 137 throw new RuntimeException(file.getPath() + "删除失败!"); 138 } else { 139 return; 140 } 141 } 142 // 删除子目录 143 for (File child : file.listFiles()) { 144 deleteFile(child); 145 } 146 // 删除自己 147 file.delete(); 148 } 149 150 /** 151 * 从文件路径中抽取文件的扩展名, 例如. "mypath/myfile.txt" -> "txt". * @author 宋立君 152 * 153 * @date 2014年06月24日 154 * @param 文件路径 155 * @return 如果path为null,直接返回null。 156 */ 157 public static String getFilenameExtension(String path) { 158 if (path == null) { 159 return null; 160 } 161 int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR); 162 if (extIndex == -1) { 163 return null; 164 } 165 int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR); 166 if (folderIndex > extIndex) { 167 return null; 168 } 169 return path.substring(extIndex + 1); 170 } 171 172 /** 173 * 从文件路径中抽取文件名, 例如: "mypath/myfile.txt" -> "myfile.txt"。 * @author 宋立君 174 * 175 * @date 2014年06月24日 176 * @param path 177 * 文件路径。 178 * @return 抽取出来的文件名, 如果path为null,直接返回null。 179 */ 180 public static String getFilename(String path) { 181 if (path == null) { 182 return null; 183 } 184 int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); 185 return (separatorIndex != -1 ? path.substring(separatorIndex + 1) 186 : path); 187 } 188 189 /** 190 * 功能:保存文件。 191 * 192 * @author 宋立君 193 * @date 2014年06月24日 194 * @param content 195 * 字节 196 * @param file 197 * 保存到的文件 198 * @throws IOException 199 */ 200 public static void save(byte[] content, File file) throws IOException { 201 if (file == null) { 202 throw new RuntimeException("保存文件不能为空"); 203 } 204 if (content == null) { 205 throw new RuntimeException("文件流不能为空"); 206 } 207 InputStream is = new ByteArrayInputStream(content); 208 save(is, file); 209 } 210 211 /** 212 * 功能:保存文件 213 * 214 * @author 宋立君 215 * @date 2014年06月24日 216 * @param streamIn 217 * 文件流 218 * @param file 219 * 保存到的文件 220 * @throws IOException 221 */ 222 public static void save(InputStream streamIn, File file) throws IOException { 223 if (file == null) { 224 throw new RuntimeException("保存文件不能为空"); 225 } 226 if (streamIn == null) { 227 throw new RuntimeException("文件流不能为空"); 228 } 229 // 输出流 230 OutputStream streamOut = null; 231 // 文件夹不存在就创建。 232 if (!file.getParentFile().exists()) { 233 file.getParentFile().mkdirs(); 234 } 235 streamOut = new FileOutputStream(file); 236 int bytesRead = 0; 237 byte[] buffer = new byte[8192]; 238 while ((bytesRead = streamIn.read(buffer, 0, 8192)) != -1) { 239 streamOut.write(buffer, 0, bytesRead); 240 } 241 streamOut.close(); 242 streamIn.close(); 243 } 244 }
时间: 2024-10-14 11:17:44