001/* 002* Licensed to the Apache Software Foundation (ASF) under one or more 003* contributor license agreements. See the NOTICE file distributed with 004* this work for additional information regarding copyright ownership. 005* The ASF licenses this file to You under the Apache License, Version 2.0 006* (the "License"); you may not use this file except in compliance with 007* the License. You may obtain a copy of the License at 008* 009* http://www.apache.org/licenses/LICENSE-2.0 010* 011* Unless required by applicable law or agreed to in writing, software 012* distributed under the License is distributed on an "AS IS" BASIS, 013* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014* See the License for the specific language governing permissions and 015* limitations under the License. 016*/ 017 018package co.aikar.commands.apachecommonslang; 019 020import java.lang.reflect.Array; 021import java.util.Iterator; 022import java.util.Locale; 023 024/** 025 * Select methods copied from Apache Commons to avoid importing entire lib 026 * No changes to logic 027 */ 028public class ApacheCommonsLangUtil { 029 030 /** 031 * The empty String {@code ""}. 032 * @since 2.0 033 */ 034 public static final String EMPTY = ""; 035 /** 036 * <p>Shallow clones an array returning a typecast result and handling 037 * {@code null}. 038 * 039 * <p>The objects in the array are not cloned, thus there is no special 040 * handling for multi-dimensional arrays. 041 * 042 * <p>This method returns {@code null} for a {@code null} input array. 043 * 044 * @param <T> the component type of the array 045 * @param array the array to shallow clone, may be {@code null} 046 * @return the cloned array, {@code null} if {@code null} input 047 */ 048 public static <T> T[] clone(final T[] array) { 049 if (array == null) { 050 return null; 051 } 052 return array.clone(); 053 } 054 055 /** 056 * <p>Adds all the elements of the given arrays into a new array. 057 * <p>The new array contains all of the element of {@code array1} followed 058 * by all of the elements {@code array2}. When an array is returned, it is always 059 * a new array. 060 * 061 * <pre> 062 * ArrayUtils.addAll(null, null) = null 063 * ArrayUtils.addAll(array1, null) = cloned copy of array1 064 * ArrayUtils.addAll(null, array2) = cloned copy of array2 065 * ArrayUtils.addAll([], []) = [] 066 * ArrayUtils.addAll([null], [null]) = [null, null] 067 * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"] 068 * </pre> 069 * 070 * @param <T> the component type of the array 071 * @param array1 the first array whose elements are added to the new array, may be {@code null} 072 * @param array2 the second array whose elements are added to the new array, may be {@code null} 073 * @return The new array, {@code null} if both arrays are {@code null}. 074 * The type of the new array is the type of the first array, 075 * unless the first array is null, in which case the type is the same as the second array. 076 * @since 2.1 077 * @throws IllegalArgumentException if the array types are incompatible 078 */ 079 public static <T> T[] addAll(final T[] array1, final T... array2) { 080 if (array1 == null) { 081 return clone(array2); 082 } else if (array2 == null) { 083 return clone(array1); 084 } 085 final Class<?> type1 = array1.getClass().getComponentType(); 086 @SuppressWarnings("unchecked") // OK, because array is of type T 087 final T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length); 088 System.arraycopy(array1, 0, joinedArray, 0, array1.length); 089 try { 090 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); 091 } catch (final ArrayStoreException ase) { 092 // Check if problem was due to incompatible types 093 /* 094 * We do this here, rather than before the copy because: 095 * - it would be a wasted check most of the time 096 * - safer, in case check turns out to be too strict 097 */ 098 final Class<?> type2 = array2.getClass().getComponentType(); 099 if (!type1.isAssignableFrom(type2)) { 100 throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of " 101 + type1.getName(), ase); 102 } 103 throw ase; // No, so rethrow original 104 } 105 return joinedArray; 106 } 107 108 //----------------------------------------------------------------------- 109 /** 110 * <p>Converts all the whitespace separated words in a String into capitalized words, 111 * that is each word is made up of a titlecase character and then a series of 112 * lowercase characters. </p> 113 * 114 * <p>Whitespace is defined by {@link Character#isWhitespace(char)}. 115 * A <code>null</code> input String returns <code>null</code>. 116 * Capitalization uses the Unicode title case, normally equivalent to 117 * upper case.</p> 118 * 119 * <pre> 120 * WordUtils.capitalizeFully(null) = null 121 * WordUtils.capitalizeFully("") = "" 122 * WordUtils.capitalizeFully("i am FINE") = "I Am Fine" 123 * </pre> 124 * 125 * @param str the String to capitalize, may be null 126 * @return capitalized String, <code>null</code> if null String input 127 */ 128 public static String capitalizeFully(final String str) { 129 return capitalizeFully(str, null); 130 } 131 132 /** 133 * <p>Converts all the delimiter separated words in a String into capitalized words, 134 * that is each word is made up of a titlecase character and then a series of 135 * lowercase characters. </p> 136 * 137 * <p>The delimiters represent a set of characters understood to separate words. 138 * The first string character and the first non-delimiter character after a 139 * delimiter will be capitalized. </p> 140 * 141 * <p>A <code>null</code> input String returns <code>null</code>. 142 * Capitalization uses the Unicode title case, normally equivalent to 143 * upper case.</p> 144 * 145 * <pre> 146 * WordUtils.capitalizeFully(null, *) = null 147 * WordUtils.capitalizeFully("", *) = "" 148 * WordUtils.capitalizeFully(*, null) = * 149 * WordUtils.capitalizeFully(*, new char[0]) = * 150 * WordUtils.capitalizeFully("i aM.fine", {'.'}) = "I am.Fine" 151 * </pre> 152 * 153 * @param str the String to capitalize, may be null 154 * @param delimiters set of characters to determine capitalization, null means whitespace 155 * @return capitalized String, <code>null</code> if null String input 156 * @since 2.1 157 */ 158 public static String capitalizeFully(String str, final char... delimiters) { 159 final int delimLen = delimiters == null ? -1 : delimiters.length; 160 if (str == null || str.isEmpty() || delimLen == 0) { 161 return str; 162 } 163 str = str.toLowerCase(Locale.ENGLISH); 164 return capitalize(str, delimiters); 165 } 166 167 // Capitalizing 168 //----------------------------------------------------------------------- 169 /** 170 * <p>Capitalizes all the whitespace separated words in a String. 171 * Only the first character of each word is changed. To convert the 172 * rest of each word to lowercase at the same time, 173 * use {@link #capitalizeFully(String)}.</p> 174 * 175 * <p>Whitespace is defined by {@link Character#isWhitespace(char)}. 176 * A <code>null</code> input String returns <code>null</code>. 177 * Capitalization uses the Unicode title case, normally equivalent to 178 * upper case.</p> 179 * 180 * <pre> 181 * WordUtils.capitalize(null) = null 182 * WordUtils.capitalize("") = "" 183 * WordUtils.capitalize("i am FINE") = "I Am FINE" 184 * </pre> 185 * 186 * @param str the String to capitalize, may be null 187 * @return capitalized String, <code>null</code> if null String input 188 * @see #capitalizeFully(String) 189 */ 190 public static String capitalize(final String str) { 191 return capitalize(str, null); 192 } 193 194 /** 195 * <p>Capitalizes all the delimiter separated words in a String. 196 * Only the first character of each word is changed. To convert the 197 * rest of each word to lowercase at the same time, 198 * use {@link #capitalizeFully(String, char[])}.</p> 199 * 200 * <p>The delimiters represent a set of characters understood to separate words. 201 * The first string character and the first non-delimiter character after a 202 * delimiter will be capitalized. </p> 203 * 204 * <p>A <code>null</code> input String returns <code>null</code>. 205 * Capitalization uses the Unicode title case, normally equivalent to 206 * upper case.</p> 207 * 208 * <pre> 209 * WordUtils.capitalize(null, *) = null 210 * WordUtils.capitalize("", *) = "" 211 * WordUtils.capitalize(*, new char[0]) = * 212 * WordUtils.capitalize("i am fine", null) = "I Am Fine" 213 * WordUtils.capitalize("i aM.fine", {'.'}) = "I aM.Fine" 214 * </pre> 215 * 216 * @param str the String to capitalize, may be null 217 * @param delimiters set of characters to determine capitalization, null means whitespace 218 * @return capitalized String, <code>null</code> if null String input 219 * @see #capitalizeFully(String) 220 * @since 2.1 221 */ 222 public static String capitalize(final String str, final char... delimiters) { 223 final int delimLen = delimiters == null ? -1 : delimiters.length; 224 if (str == null || str.isEmpty() || delimLen == 0) { 225 return str; 226 } 227 final char[] buffer = str.toCharArray(); 228 boolean capitalizeNext = true; 229 for (int i = 0; i < buffer.length; i++) { 230 final char ch = buffer[i]; 231 if (isDelimiter(ch, delimiters)) { 232 capitalizeNext = true; 233 } else if (capitalizeNext) { 234 buffer[i] = Character.toTitleCase(ch); 235 capitalizeNext = false; 236 } 237 } 238 return new String(buffer); 239 } 240 //----------------------------------------------------------------------- 241 /** 242 * Is the character a delimiter. 243 * 244 * @param ch the character to check 245 * @param delimiters the delimiters 246 * @return true if it is a delimiter 247 */ 248 public static boolean isDelimiter(final char ch, final char[] delimiters) { 249 if (delimiters == null) { 250 return Character.isWhitespace(ch); 251 } 252 for (final char delimiter : delimiters) { 253 if (ch == delimiter) { 254 return true; 255 } 256 } 257 return false; 258 } 259 260 // Joining 261 //----------------------------------------------------------------------- 262 /** 263 * <p>Joins the elements of the provided array into a single String 264 * containing the provided list of elements.</p> 265 * 266 * <p>No separator is added to the joined String. 267 * Null objects or empty strings within the array are represented by 268 * empty strings.</p> 269 * 270 * <pre> 271 * StringUtils.join(null) = null 272 * StringUtils.join([]) = "" 273 * StringUtils.join([null]) = "" 274 * StringUtils.join(["a", "b", "c"]) = "abc" 275 * StringUtils.join([null, "", "a"]) = "a" 276 * </pre> 277 * 278 * @param <T> the specific type of values to join together 279 * @param elements the values to join together, may be null 280 * @return the joined String, {@code null} if null array input 281 * @since 2.0 282 * @since 3.0 Changed signature to use varargs 283 */ 284 @SafeVarargs 285 public static <T> String join(final T... elements) { 286 return join(elements, null); 287 } 288 289 /** 290 * <p>Joins the elements of the provided array into a single String 291 * containing the provided list of elements.</p> 292 * 293 * <p>No delimiter is added before or after the list. 294 * Null objects or empty strings within the array are represented by 295 * empty strings.</p> 296 * 297 * <pre> 298 * StringUtils.join(null, *) = null 299 * StringUtils.join([], *) = "" 300 * StringUtils.join([null], *) = "" 301 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c" 302 * StringUtils.join(["a", "b", "c"], null) = "abc" 303 * StringUtils.join([null, "", "a"], ';') = ";;a" 304 * </pre> 305 * 306 * @param array the array of values to join together, may be null 307 * @param separator the separator character to use 308 * @return the joined String, {@code null} if null array input 309 * @since 2.0 310 */ 311 public static String join(final Object[] array, final char separator) { 312 if (array == null) { 313 return null; 314 } 315 return join(array, separator, 0, array.length); 316 } 317 318 /** 319 * <p> 320 * Joins the elements of the provided array into a single String containing the provided list of elements. 321 * </p> 322 * 323 * <p> 324 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 325 * by empty strings. 326 * </p> 327 * 328 * <pre> 329 * StringUtils.join(null, *) = null 330 * StringUtils.join([], *) = "" 331 * StringUtils.join([null], *) = "" 332 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 333 * StringUtils.join([1, 2, 3], null) = "123" 334 * </pre> 335 * 336 * @param array 337 * the array of values to join together, may be null 338 * @param separator 339 * the separator character to use 340 * @return the joined String, {@code null} if null array input 341 * @since 3.2 342 */ 343 public static String join(final long[] array, final char separator) { 344 if (array == null) { 345 return null; 346 } 347 return join(array, separator, 0, array.length); 348 } 349 350 /** 351 * <p> 352 * Joins the elements of the provided array into a single String containing the provided list of elements. 353 * </p> 354 * 355 * <p> 356 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 357 * by empty strings. 358 * </p> 359 * 360 * <pre> 361 * StringUtils.join(null, *) = null 362 * StringUtils.join([], *) = "" 363 * StringUtils.join([null], *) = "" 364 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 365 * StringUtils.join([1, 2, 3], null) = "123" 366 * </pre> 367 * 368 * @param array 369 * the array of values to join together, may be null 370 * @param separator 371 * the separator character to use 372 * @return the joined String, {@code null} if null array input 373 * @since 3.2 374 */ 375 public static String join(final int[] array, final char separator) { 376 if (array == null) { 377 return null; 378 } 379 return join(array, separator, 0, array.length); 380 } 381 382 /** 383 * <p> 384 * Joins the elements of the provided array into a single String containing the provided list of elements. 385 * </p> 386 * 387 * <p> 388 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 389 * by empty strings. 390 * </p> 391 * 392 * <pre> 393 * StringUtils.join(null, *) = null 394 * StringUtils.join([], *) = "" 395 * StringUtils.join([null], *) = "" 396 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 397 * StringUtils.join([1, 2, 3], null) = "123" 398 * </pre> 399 * 400 * @param array 401 * the array of values to join together, may be null 402 * @param separator 403 * the separator character to use 404 * @return the joined String, {@code null} if null array input 405 * @since 3.2 406 */ 407 public static String join(final short[] array, final char separator) { 408 if (array == null) { 409 return null; 410 } 411 return join(array, separator, 0, array.length); 412 } 413 414 /** 415 * <p> 416 * Joins the elements of the provided array into a single String containing the provided list of elements. 417 * </p> 418 * 419 * <p> 420 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 421 * by empty strings. 422 * </p> 423 * 424 * <pre> 425 * StringUtils.join(null, *) = null 426 * StringUtils.join([], *) = "" 427 * StringUtils.join([null], *) = "" 428 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 429 * StringUtils.join([1, 2, 3], null) = "123" 430 * </pre> 431 * 432 * @param array 433 * the array of values to join together, may be null 434 * @param separator 435 * the separator character to use 436 * @return the joined String, {@code null} if null array input 437 * @since 3.2 438 */ 439 public static String join(final byte[] array, final char separator) { 440 if (array == null) { 441 return null; 442 } 443 return join(array, separator, 0, array.length); 444 } 445 446 /** 447 * <p> 448 * Joins the elements of the provided array into a single String containing the provided list of elements. 449 * </p> 450 * 451 * <p> 452 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 453 * by empty strings. 454 * </p> 455 * 456 * <pre> 457 * StringUtils.join(null, *) = null 458 * StringUtils.join([], *) = "" 459 * StringUtils.join([null], *) = "" 460 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 461 * StringUtils.join([1, 2, 3], null) = "123" 462 * </pre> 463 * 464 * @param array 465 * the array of values to join together, may be null 466 * @param separator 467 * the separator character to use 468 * @return the joined String, {@code null} if null array input 469 * @since 3.2 470 */ 471 public static String join(final char[] array, final char separator) { 472 if (array == null) { 473 return null; 474 } 475 return join(array, separator, 0, array.length); 476 } 477 478 /** 479 * <p> 480 * Joins the elements of the provided array into a single String containing the provided list of elements. 481 * </p> 482 * 483 * <p> 484 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 485 * by empty strings. 486 * </p> 487 * 488 * <pre> 489 * StringUtils.join(null, *) = null 490 * StringUtils.join([], *) = "" 491 * StringUtils.join([null], *) = "" 492 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 493 * StringUtils.join([1, 2, 3], null) = "123" 494 * </pre> 495 * 496 * @param array 497 * the array of values to join together, may be null 498 * @param separator 499 * the separator character to use 500 * @return the joined String, {@code null} if null array input 501 * @since 3.2 502 */ 503 public static String join(final float[] array, final char separator) { 504 if (array == null) { 505 return null; 506 } 507 return join(array, separator, 0, array.length); 508 } 509 510 /** 511 * <p> 512 * Joins the elements of the provided array into a single String containing the provided list of elements. 513 * </p> 514 * 515 * <p> 516 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 517 * by empty strings. 518 * </p> 519 * 520 * <pre> 521 * StringUtils.join(null, *) = null 522 * StringUtils.join([], *) = "" 523 * StringUtils.join([null], *) = "" 524 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 525 * StringUtils.join([1, 2, 3], null) = "123" 526 * </pre> 527 * 528 * @param array 529 * the array of values to join together, may be null 530 * @param separator 531 * the separator character to use 532 * @return the joined String, {@code null} if null array input 533 * @since 3.2 534 */ 535 public static String join(final double[] array, final char separator) { 536 if (array == null) { 537 return null; 538 } 539 return join(array, separator, 0, array.length); 540 } 541 542 543 /** 544 * <p>Joins the elements of the provided array into a single String 545 * containing the provided list of elements.</p> 546 * 547 * <p>No delimiter is added before or after the list. 548 * Null objects or empty strings within the array are represented by 549 * empty strings.</p> 550 * 551 * <pre> 552 * StringUtils.join(null, *) = null 553 * StringUtils.join([], *) = "" 554 * StringUtils.join([null], *) = "" 555 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c" 556 * StringUtils.join(["a", "b", "c"], null) = "abc" 557 * StringUtils.join([null, "", "a"], ';') = ";;a" 558 * </pre> 559 * 560 * @param array the array of values to join together, may be null 561 * @param separator the separator character to use 562 * @param startIndex the first index to start joining from. It is 563 * an error to pass in an end index past the end of the array 564 * @param endIndex the index to stop joining from (exclusive). It is 565 * an error to pass in an end index past the end of the array 566 * @return the joined String, {@code null} if null array input 567 * @since 2.0 568 */ 569 public static String join(final Object[] array, final char separator, final int startIndex, final int endIndex) { 570 if (array == null) { 571 return null; 572 } 573 final int noOfItems = endIndex - startIndex; 574 if (noOfItems <= 0) { 575 return EMPTY; 576 } 577 final StringBuilder buf = new StringBuilder(noOfItems * 16); 578 for (int i = startIndex; i < endIndex; i++) { 579 if (i > startIndex) { 580 buf.append(separator); 581 } 582 if (array[i] != null) { 583 buf.append(array[i]); 584 } 585 } 586 return buf.toString(); 587 } 588 589 /** 590 * <p> 591 * Joins the elements of the provided array into a single String containing the provided list of elements. 592 * </p> 593 * 594 * <p> 595 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 596 * by empty strings. 597 * </p> 598 * 599 * <pre> 600 * StringUtils.join(null, *) = null 601 * StringUtils.join([], *) = "" 602 * StringUtils.join([null], *) = "" 603 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 604 * StringUtils.join([1, 2, 3], null) = "123" 605 * </pre> 606 * 607 * @param array 608 * the array of values to join together, may be null 609 * @param separator 610 * the separator character to use 611 * @param startIndex 612 * the first index to start joining from. It is an error to pass in an end index past the end of the 613 * array 614 * @param endIndex 615 * the index to stop joining from (exclusive). It is an error to pass in an end index past the end of 616 * the array 617 * @return the joined String, {@code null} if null array input 618 * @since 3.2 619 */ 620 public static String join(final long[] array, final char separator, final int startIndex, final int endIndex) { 621 if (array == null) { 622 return null; 623 } 624 final int noOfItems = endIndex - startIndex; 625 if (noOfItems <= 0) { 626 return EMPTY; 627 } 628 final StringBuilder buf = new StringBuilder(noOfItems * 16); 629 for (int i = startIndex; i < endIndex; i++) { 630 if (i > startIndex) { 631 buf.append(separator); 632 } 633 buf.append(array[i]); 634 } 635 return buf.toString(); 636 } 637 638 /** 639 * <p> 640 * Joins the elements of the provided array into a single String containing the provided list of elements. 641 * </p> 642 * 643 * <p> 644 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 645 * by empty strings. 646 * </p> 647 * 648 * <pre> 649 * StringUtils.join(null, *) = null 650 * StringUtils.join([], *) = "" 651 * StringUtils.join([null], *) = "" 652 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 653 * StringUtils.join([1, 2, 3], null) = "123" 654 * </pre> 655 * 656 * @param array 657 * the array of values to join together, may be null 658 * @param separator 659 * the separator character to use 660 * @param startIndex 661 * the first index to start joining from. It is an error to pass in an end index past the end of the 662 * array 663 * @param endIndex 664 * the index to stop joining from (exclusive). It is an error to pass in an end index past the end of 665 * the array 666 * @return the joined String, {@code null} if null array input 667 * @since 3.2 668 */ 669 public static String join(final int[] array, final char separator, final int startIndex, final int endIndex) { 670 if (array == null) { 671 return null; 672 } 673 final int noOfItems = endIndex - startIndex; 674 if (noOfItems <= 0) { 675 return EMPTY; 676 } 677 final StringBuilder buf = new StringBuilder(noOfItems * 16); 678 for (int i = startIndex; i < endIndex; i++) { 679 if (i > startIndex) { 680 buf.append(separator); 681 } 682 buf.append(array[i]); 683 } 684 return buf.toString(); 685 } 686 687 /** 688 * <p> 689 * Joins the elements of the provided array into a single String containing the provided list of elements. 690 * </p> 691 * 692 * <p> 693 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 694 * by empty strings. 695 * </p> 696 * 697 * <pre> 698 * StringUtils.join(null, *) = null 699 * StringUtils.join([], *) = "" 700 * StringUtils.join([null], *) = "" 701 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 702 * StringUtils.join([1, 2, 3], null) = "123" 703 * </pre> 704 * 705 * @param array 706 * the array of values to join together, may be null 707 * @param separator 708 * the separator character to use 709 * @param startIndex 710 * the first index to start joining from. It is an error to pass in an end index past the end of the 711 * array 712 * @param endIndex 713 * the index to stop joining from (exclusive). It is an error to pass in an end index past the end of 714 * the array 715 * @return the joined String, {@code null} if null array input 716 * @since 3.2 717 */ 718 public static String join(final byte[] array, final char separator, final int startIndex, final int endIndex) { 719 if (array == null) { 720 return null; 721 } 722 final int noOfItems = endIndex - startIndex; 723 if (noOfItems <= 0) { 724 return EMPTY; 725 } 726 final StringBuilder buf = new StringBuilder(noOfItems * 16); 727 for (int i = startIndex; i < endIndex; i++) { 728 if (i > startIndex) { 729 buf.append(separator); 730 } 731 buf.append(array[i]); 732 } 733 return buf.toString(); 734 } 735 736 /** 737 * <p> 738 * Joins the elements of the provided array into a single String containing the provided list of elements. 739 * </p> 740 * 741 * <p> 742 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 743 * by empty strings. 744 * </p> 745 * 746 * <pre> 747 * StringUtils.join(null, *) = null 748 * StringUtils.join([], *) = "" 749 * StringUtils.join([null], *) = "" 750 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 751 * StringUtils.join([1, 2, 3], null) = "123" 752 * </pre> 753 * 754 * @param array 755 * the array of values to join together, may be null 756 * @param separator 757 * the separator character to use 758 * @param startIndex 759 * the first index to start joining from. It is an error to pass in an end index past the end of the 760 * array 761 * @param endIndex 762 * the index to stop joining from (exclusive). It is an error to pass in an end index past the end of 763 * the array 764 * @return the joined String, {@code null} if null array input 765 * @since 3.2 766 */ 767 public static String join(final short[] array, final char separator, final int startIndex, final int endIndex) { 768 if (array == null) { 769 return null; 770 } 771 final int noOfItems = endIndex - startIndex; 772 if (noOfItems <= 0) { 773 return EMPTY; 774 } 775 final StringBuilder buf = new StringBuilder(noOfItems * 16); 776 for (int i = startIndex; i < endIndex; i++) { 777 if (i > startIndex) { 778 buf.append(separator); 779 } 780 buf.append(array[i]); 781 } 782 return buf.toString(); 783 } 784 785 /** 786 * <p> 787 * Joins the elements of the provided array into a single String containing the provided list of elements. 788 * </p> 789 * 790 * <p> 791 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 792 * by empty strings. 793 * </p> 794 * 795 * <pre> 796 * StringUtils.join(null, *) = null 797 * StringUtils.join([], *) = "" 798 * StringUtils.join([null], *) = "" 799 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 800 * StringUtils.join([1, 2, 3], null) = "123" 801 * </pre> 802 * 803 * @param array 804 * the array of values to join together, may be null 805 * @param separator 806 * the separator character to use 807 * @param startIndex 808 * the first index to start joining from. It is an error to pass in an end index past the end of the 809 * array 810 * @param endIndex 811 * the index to stop joining from (exclusive). It is an error to pass in an end index past the end of 812 * the array 813 * @return the joined String, {@code null} if null array input 814 * @since 3.2 815 */ 816 public static String join(final char[] array, final char separator, final int startIndex, final int endIndex) { 817 if (array == null) { 818 return null; 819 } 820 final int noOfItems = endIndex - startIndex; 821 if (noOfItems <= 0) { 822 return EMPTY; 823 } 824 final StringBuilder buf = new StringBuilder(noOfItems * 16); 825 for (int i = startIndex; i < endIndex; i++) { 826 if (i > startIndex) { 827 buf.append(separator); 828 } 829 buf.append(array[i]); 830 } 831 return buf.toString(); 832 } 833 834 /** 835 * <p> 836 * Joins the elements of the provided array into a single String containing the provided list of elements. 837 * </p> 838 * 839 * <p> 840 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 841 * by empty strings. 842 * </p> 843 * 844 * <pre> 845 * StringUtils.join(null, *) = null 846 * StringUtils.join([], *) = "" 847 * StringUtils.join([null], *) = "" 848 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 849 * StringUtils.join([1, 2, 3], null) = "123" 850 * </pre> 851 * 852 * @param array 853 * the array of values to join together, may be null 854 * @param separator 855 * the separator character to use 856 * @param startIndex 857 * the first index to start joining from. It is an error to pass in an end index past the end of the 858 * array 859 * @param endIndex 860 * the index to stop joining from (exclusive). It is an error to pass in an end index past the end of 861 * the array 862 * @return the joined String, {@code null} if null array input 863 * @since 3.2 864 */ 865 public static String join(final double[] array, final char separator, final int startIndex, final int endIndex) { 866 if (array == null) { 867 return null; 868 } 869 final int noOfItems = endIndex - startIndex; 870 if (noOfItems <= 0) { 871 return EMPTY; 872 } 873 final StringBuilder buf = new StringBuilder(noOfItems * 16); 874 for (int i = startIndex; i < endIndex; i++) { 875 if (i > startIndex) { 876 buf.append(separator); 877 } 878 buf.append(array[i]); 879 } 880 return buf.toString(); 881 } 882 883 /** 884 * <p> 885 * Joins the elements of the provided array into a single String containing the provided list of elements. 886 * </p> 887 * 888 * <p> 889 * No delimiter is added before or after the list. Null objects or empty strings within the array are represented 890 * by empty strings. 891 * </p> 892 * 893 * <pre> 894 * StringUtils.join(null, *) = null 895 * StringUtils.join([], *) = "" 896 * StringUtils.join([null], *) = "" 897 * StringUtils.join([1, 2, 3], ';') = "1;2;3" 898 * StringUtils.join([1, 2, 3], null) = "123" 899 * </pre> 900 * 901 * @param array 902 * the array of values to join together, may be null 903 * @param separator 904 * the separator character to use 905 * @param startIndex 906 * the first index to start joining from. It is an error to pass in an end index past the end of the 907 * array 908 * @param endIndex 909 * the index to stop joining from (exclusive). It is an error to pass in an end index past the end of 910 * the array 911 * @return the joined String, {@code null} if null array input 912 * @since 3.2 913 */ 914 public static String join(final float[] array, final char separator, final int startIndex, final int endIndex) { 915 if (array == null) { 916 return null; 917 } 918 final int noOfItems = endIndex - startIndex; 919 if (noOfItems <= 0) { 920 return EMPTY; 921 } 922 final StringBuilder buf = new StringBuilder(noOfItems * 16); 923 for (int i = startIndex; i < endIndex; i++) { 924 if (i > startIndex) { 925 buf.append(separator); 926 } 927 buf.append(array[i]); 928 } 929 return buf.toString(); 930 } 931 932 933 /** 934 * <p>Joins the elements of the provided array into a single String 935 * containing the provided list of elements.</p> 936 * 937 * <p>No delimiter is added before or after the list. 938 * A {@code null} separator is the same as an empty String (""). 939 * Null objects or empty strings within the array are represented by 940 * empty strings.</p> 941 * 942 * <pre> 943 * StringUtils.join(null, *) = null 944 * StringUtils.join([], *) = "" 945 * StringUtils.join([null], *) = "" 946 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c" 947 * StringUtils.join(["a", "b", "c"], null) = "abc" 948 * StringUtils.join(["a", "b", "c"], "") = "abc" 949 * StringUtils.join([null, "", "a"], ',') = ",,a" 950 * </pre> 951 * 952 * @param array the array of values to join together, may be null 953 * @param separator the separator character to use, null treated as "" 954 * @return the joined String, {@code null} if null array input 955 */ 956 public static String join(final Object[] array, final String separator) { 957 if (array == null) { 958 return null; 959 } 960 return join(array, separator, 0, array.length); 961 } 962 963 /** 964 * <p>Joins the elements of the provided array into a single String 965 * containing the provided list of elements.</p> 966 * 967 * <p>No delimiter is added before or after the list. 968 * A {@code null} separator is the same as an empty String (""). 969 * Null objects or empty strings within the array are represented by 970 * empty strings.</p> 971 * 972 * <pre> 973 * StringUtils.join(null, *, *, *) = null 974 * StringUtils.join([], *, *, *) = "" 975 * StringUtils.join([null], *, *, *) = "" 976 * StringUtils.join(["a", "b", "c"], "--", 0, 3) = "a--b--c" 977 * StringUtils.join(["a", "b", "c"], "--", 1, 3) = "b--c" 978 * StringUtils.join(["a", "b", "c"], "--", 2, 3) = "c" 979 * StringUtils.join(["a", "b", "c"], "--", 2, 2) = "" 980 * StringUtils.join(["a", "b", "c"], null, 0, 3) = "abc" 981 * StringUtils.join(["a", "b", "c"], "", 0, 3) = "abc" 982 * StringUtils.join([null, "", "a"], ',', 0, 3) = ",,a" 983 * </pre> 984 * 985 * @param array the array of values to join together, may be null 986 * @param separator the separator character to use, null treated as "" 987 * @param startIndex the first index to start joining from. 988 * @param endIndex the index to stop joining from (exclusive). 989 * @return the joined String, {@code null} if null array input; or the empty string 990 * if {@code endIndex - startIndex <= 0}. The number of joined entries is given by 991 * {@code endIndex - startIndex} 992 * @throws ArrayIndexOutOfBoundsException ife<br> 993 * {@code startIndex < 0} or <br> 994 * {@code startIndex >= array.length()} or <br> 995 * {@code endIndex < 0} or <br> 996 * {@code endIndex > array.length()} 997 */ 998 public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) { 999 if (array == null) { 1000 return null; 1001 } 1002 if (separator == null) { 1003 separator = EMPTY; 1004 } 1005 1006 // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator)) 1007 // (Assuming that all Strings are roughly equally long) 1008 final int noOfItems = endIndex - startIndex; 1009 if (noOfItems <= 0) { 1010 return EMPTY; 1011 } 1012 1013 final StringBuilder buf = new StringBuilder(noOfItems * 16); 1014 1015 for (int i = startIndex; i < endIndex; i++) { 1016 if (i > startIndex) { 1017 buf.append(separator); 1018 } 1019 if (array[i] != null) { 1020 buf.append(array[i]); 1021 } 1022 } 1023 return buf.toString(); 1024 } 1025 1026 /** 1027 * <p>Joins the elements of the provided {@code Iterator} into 1028 * a single String containing the provided elements.</p> 1029 * 1030 * <p>No delimiter is added before or after the list. Null objects or empty 1031 * strings within the iteration are represented by empty strings.</p> 1032 * 1033 * <p>See the examples here: {@link #join(Object[],char)}. </p> 1034 * 1035 * @param iterator the {@code Iterator} of values to join together, may be null 1036 * @param separator the separator character to use 1037 * @return the joined String, {@code null} if null iterator input 1038 * @since 2.0 1039 */ 1040 public static String join(final Iterator<?> iterator, final char separator) { 1041 1042 // handle null, zero and one elements before building a buffer 1043 if (iterator == null) { 1044 return null; 1045 } 1046 if (!iterator.hasNext()) { 1047 return EMPTY; 1048 } 1049 final Object first = iterator.next(); 1050 if (!iterator.hasNext()) { 1051 final String result = first != null ? first.toString() : ""; 1052 return result; 1053 } 1054 1055 // two or more elements 1056 final StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small 1057 if (first != null) { 1058 buf.append(first); 1059 } 1060 1061 while (iterator.hasNext()) { 1062 buf.append(separator); 1063 final Object obj = iterator.next(); 1064 if (obj != null) { 1065 buf.append(obj); 1066 } 1067 } 1068 1069 return buf.toString(); 1070 } 1071 1072 /** 1073 * <p>Joins the elements of the provided {@code Iterator} into 1074 * a single String containing the provided elements.</p> 1075 * 1076 * <p>No delimiter is added before or after the list. 1077 * A {@code null} separator is the same as an empty String ("").</p> 1078 * 1079 * <p>See the examples here: {@link #join(Object[],String)}. </p> 1080 * 1081 * @param iterator the {@code Iterator} of values to join together, may be null 1082 * @param separator the separator character to use, null treated as "" 1083 * @return the joined String, {@code null} if null iterator input 1084 */ 1085 public static String join(final Iterator<?> iterator, final String separator) { 1086 1087 // handle null, zero and one elements before building a buffer 1088 if (iterator == null) { 1089 return null; 1090 } 1091 if (!iterator.hasNext()) { 1092 return EMPTY; 1093 } 1094 final Object first = iterator.next(); 1095 if (!iterator.hasNext()) { 1096 final String result = first != null ? first.toString() : ""; 1097 return result; 1098 } 1099 1100 // two or more elements 1101 final StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small 1102 if (first != null) { 1103 buf.append(first); 1104 } 1105 1106 while (iterator.hasNext()) { 1107 if (separator != null) { 1108 buf.append(separator); 1109 } 1110 final Object obj = iterator.next(); 1111 if (obj != null) { 1112 buf.append(obj); 1113 } 1114 } 1115 return buf.toString(); 1116 } 1117 1118 /** 1119 * <p>Joins the elements of the provided {@code Iterable} into 1120 * a single String containing the provided elements.</p> 1121 * 1122 * <p>No delimiter is added before or after the list. Null objects or empty 1123 * strings within the iteration are represented by empty strings.</p> 1124 * 1125 * <p>See the examples here: {@link #join(Object[],char)}. </p> 1126 * 1127 * @param iterable the {@code Iterable} providing the values to join together, may be null 1128 * @param separator the separator character to use 1129 * @return the joined String, {@code null} if null iterator input 1130 * @since 2.3 1131 */ 1132 public static String join(final Iterable<?> iterable, final char separator) { 1133 if (iterable == null) { 1134 return null; 1135 } 1136 return join(iterable.iterator(), separator); 1137 } 1138 1139 /** 1140 * <p>Joins the elements of the provided {@code Iterable} into 1141 * a single String containing the provided elements.</p> 1142 * 1143 * <p>No delimiter is added before or after the list. 1144 * A {@code null} separator is the same as an empty String ("").</p> 1145 * 1146 * <p>See the examples here: {@link #join(Object[],String)}. </p> 1147 * 1148 * @param iterable the {@code Iterable} providing the values to join together, may be null 1149 * @param separator the separator character to use, null treated as "" 1150 * @return the joined String, {@code null} if null iterator input 1151 * @since 2.3 1152 */ 1153 public static String join(final Iterable<?> iterable, final String separator) { 1154 if (iterable == null) { 1155 return null; 1156 } 1157 return join(iterable.iterator(), separator); 1158 } 1159 1160 1161 /** 1162 * <p>Checks if the CharSequence contains only Unicode digits. 1163 * A decimal point is not a Unicode digit and returns false.</p> 1164 * 1165 * <p>{@code null} will return {@code false}. 1166 * An empty CharSequence (length()=0) will return {@code false}.</p> 1167 * 1168 * <p>Note that the method does not allow for a leading sign, either positive or negative. 1169 * Also, if a String passes the numeric test, it may still generate a NumberFormatException 1170 * when parsed by Integer.parseInt or Long.parseLong, e.g. if the value is outside the range 1171 * for int or long respectively.</p> 1172 * 1173 * <pre> 1174 * StringUtils.isNumeric(null) = false 1175 * StringUtils.isNumeric("") = false 1176 * StringUtils.isNumeric(" ") = false 1177 * StringUtils.isNumeric("123") = true 1178 * StringUtils.isNumeric("\u0967\u0968\u0969") = true 1179 * StringUtils.isNumeric("12 3") = false 1180 * StringUtils.isNumeric("ab2c") = false 1181 * StringUtils.isNumeric("12-3") = false 1182 * StringUtils.isNumeric("12.3") = false 1183 * StringUtils.isNumeric("-123") = false 1184 * StringUtils.isNumeric("+123") = false 1185 * </pre> 1186 * 1187 * @param cs the CharSequence to check, may be null 1188 * @return {@code true} if only contains digits, and is non-null 1189 * @since 3.0 Changed signature from isNumeric(String) to isNumeric(CharSequence) 1190 * @since 3.0 Changed "" to return false and not true 1191 */ 1192 public static boolean isNumeric(final CharSequence cs) { 1193 if (cs == null || cs.length() == 0) { 1194 return false; 1195 } 1196 final int sz = cs.length(); 1197 for (int i = 0; i < sz; i++) { 1198 if (!Character.isDigit(cs.charAt(i))) { 1199 return false; 1200 } 1201 } 1202 return true; 1203 } 1204 1205 1206 // startsWith 1207 //----------------------------------------------------------------------- 1208 1209 /** 1210 * <p>Check if a CharSequence starts with a specified prefix.</p> 1211 * 1212 * <p>{@code null}s are handled without exceptions. Two {@code null} 1213 * references are considered to be equal. The comparison is case sensitive.</p> 1214 * 1215 * <pre> 1216 * StringUtils.startsWith(null, null) = true 1217 * StringUtils.startsWith(null, "abc") = false 1218 * StringUtils.startsWith("abcdef", null) = false 1219 * StringUtils.startsWith("abcdef", "abc") = true 1220 * StringUtils.startsWith("ABCDEF", "abc") = false 1221 * </pre> 1222 * 1223 * @see java.lang.String#startsWith(String) 1224 * @param str the CharSequence to check, may be null 1225 * @param prefix the prefix to find, may be null 1226 * @return {@code true} if the CharSequence starts with the prefix, case sensitive, or 1227 * both {@code null} 1228 * @since 2.4 1229 * @since 3.0 Changed signature from startsWith(String, String) to startsWith(CharSequence, CharSequence) 1230 */ 1231 public static boolean startsWith(final CharSequence str, final CharSequence prefix) { 1232 return startsWith(str, prefix, false); 1233 } 1234 1235 /** 1236 * <p>Case insensitive check if a CharSequence starts with a specified prefix.</p> 1237 * 1238 * <p>{@code null}s are handled without exceptions. Two {@code null} 1239 * references are considered to be equal. The comparison is case insensitive.</p> 1240 * 1241 * <pre> 1242 * StringUtils.startsWithIgnoreCase(null, null) = true 1243 * StringUtils.startsWithIgnoreCase(null, "abc") = false 1244 * StringUtils.startsWithIgnoreCase("abcdef", null) = false 1245 * StringUtils.startsWithIgnoreCase("abcdef", "abc") = true 1246 * StringUtils.startsWithIgnoreCase("ABCDEF", "abc") = true 1247 * </pre> 1248 * 1249 * @see java.lang.String#startsWith(String) 1250 * @param str the CharSequence to check, may be null 1251 * @param prefix the prefix to find, may be null 1252 * @return {@code true} if the CharSequence starts with the prefix, case insensitive, or 1253 * both {@code null} 1254 * @since 2.4 1255 * @since 3.0 Changed signature from startsWithIgnoreCase(String, String) to startsWithIgnoreCase(CharSequence, CharSequence) 1256 */ 1257 public static boolean startsWithIgnoreCase(final CharSequence str, final CharSequence prefix) { 1258 return startsWith(str, prefix, true); 1259 } 1260 1261 /** 1262 * <p>Check if a CharSequence starts with a specified prefix (optionally case insensitive).</p> 1263 * 1264 * @see java.lang.String#startsWith(String) 1265 * @param str the CharSequence to check, may be null 1266 * @param prefix the prefix to find, may be null 1267 * @param ignoreCase indicates whether the compare should ignore case 1268 * (case insensitive) or not. 1269 * @return {@code true} if the CharSequence starts with the prefix or 1270 * both {@code null} 1271 */ 1272 private static boolean startsWith(final CharSequence str, final CharSequence prefix, final boolean ignoreCase) { 1273 if (str == null || prefix == null) { 1274 return str == null && prefix == null; 1275 } 1276 if (prefix.length() > str.length()) { 1277 return false; 1278 } 1279 return regionMatches(str, ignoreCase, 0, prefix, 0, prefix.length()); 1280 } 1281 1282 /** 1283 * Green implementation of regionMatches. 1284 * 1285 * @param cs the {@code CharSequence} to be processed 1286 * @param ignoreCase whether or not to be case insensitive 1287 * @param thisStart the index to start on the {@code cs} CharSequence 1288 * @param substring the {@code CharSequence} to be looked for 1289 * @param start the index to start on the {@code substring} CharSequence 1290 * @param length character length of the region 1291 * @return whether the region matched 1292 */ 1293 static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart, 1294 final CharSequence substring, final int start, final int length) { 1295 if (cs instanceof String && substring instanceof String) { 1296 return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); 1297 } 1298 int index1 = thisStart; 1299 int index2 = start; 1300 int tmpLen = length; 1301 1302 // Extract these first so we detect NPEs the same as the java.lang.String version 1303 final int srcLen = cs.length() - thisStart; 1304 final int otherLen = substring.length() - start; 1305 1306 // Check for invalid parameters 1307 if (thisStart < 0 || start < 0 || length < 0) { 1308 return false; 1309 } 1310 1311 // Check that the regions are long enough 1312 if (srcLen < length || otherLen < length) { 1313 return false; 1314 } 1315 1316 while (tmpLen-- > 0) { 1317 final char c1 = cs.charAt(index1++); 1318 final char c2 = substring.charAt(index2++); 1319 1320 if (c1 == c2) { 1321 continue; 1322 } 1323 1324 if (!ignoreCase) { 1325 return false; 1326 } 1327 1328 // The same check as in String.regionMatches(): 1329 if (Character.toUpperCase(c1) != Character.toUpperCase(c2) 1330 && Character.toLowerCase(c1) != Character.toLowerCase(c2)) { 1331 return false; 1332 } 1333 } 1334 1335 return true; 1336 } 1337 1338 /** 1339 * The index value when an element is not found in a list or array: <code>-1</code>. 1340 * This value is returned by methods in this class and can also be used in comparisons with values returned by 1341 * various method from {@link java.util.List}. 1342 */ 1343 public static final int INDEX_NOT_FOUND = -1; 1344 1345 // IndexOf search 1346 // ---------------------------------------------------------------------- 1347 1348 // Object IndexOf 1349 //----------------------------------------------------------------------- 1350 /** 1351 * <p>Finds the index of the given object in the array.</p> 1352 * 1353 * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p> 1354 * 1355 * @param array the array to search through for the object, may be <code>null</code> 1356 * @param objectToFind the object to find, may be <code>null</code> 1357 * @return the index of the object within the array, 1358 * {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input 1359 */ 1360 public static int indexOf(Object[] array, Object objectToFind) { 1361 return indexOf(array, objectToFind, 0); 1362 } 1363 1364 /** 1365 * <p>Finds the index of the given object in the array starting at the given index.</p> 1366 * 1367 * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p> 1368 * 1369 * <p>A negative startIndex is treated as zero. A startIndex larger than the array 1370 * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p> 1371 * 1372 * @param array the array to search through for the object, may be <code>null</code> 1373 * @param objectToFind the object to find, may be <code>null</code> 1374 * @param startIndex the index to start searching at 1375 * @return the index of the object within the array starting at the index, 1376 * {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input 1377 */ 1378 public static int indexOf(Object[] array, Object objectToFind, int startIndex) { 1379 if (array == null) { 1380 return INDEX_NOT_FOUND; 1381 } 1382 if (startIndex < 0) { 1383 startIndex = 0; 1384 } 1385 if (objectToFind == null) { 1386 for (int i = startIndex; i < array.length; i++) { 1387 if (array[i] == null) { 1388 return i; 1389 } 1390 } 1391 } else { 1392 for (int i = startIndex; i < array.length; i++) { 1393 if (objectToFind.equals(array[i])) { 1394 return i; 1395 } 1396 } 1397 } 1398 return INDEX_NOT_FOUND; 1399 } 1400}