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