@@ -504,6 +504,18 @@ public static String appendIfMissingIgnoreCase(final String str, final CharSeque
504504 return Strings .CI .appendIfMissing (str , suffix , suffixes );
505505 }
506506
507+ /**
508+ * Computes the capacity required for a StringBuilder to hold {@code items} of {@code maxElementChars} characters plus the separators between them. The
509+ * separator is assumed to be 1 character.
510+ *
511+ * @param count The number of items.
512+ * @param maxElementChars The maximum number of characters per item.
513+ * @return A StringBuilder with the appropriate capacity.
514+ */
515+ private static StringBuilder capacity (final int count , final byte maxElementChars ) {
516+ return new StringBuilder (count * maxElementChars + count - 1 );
517+ }
518+
507519 /**
508520 * Capitalizes a String changing the first character to title case as per {@link Character#toTitleCase(int)}. No other characters are changed.
509521 *
@@ -3854,19 +3866,21 @@ public static String join(final boolean[] array, final char delimiter) {
38543866 * @since 3.12.0
38553867 */
38563868 public static String join (final boolean [] array , final char delimiter , final int startIndex , final int endIndex ) {
3869+ // See StringUtilsJoinBenchmark
38573870 if (array == null ) {
38583871 return null ;
38593872 }
3860- if (endIndex - startIndex <= 0 ) {
3873+ final int count = endIndex - startIndex ;
3874+ if (count <= 0 ) {
38613875 return EMPTY ;
38623876 }
3863- final StringBuilder stringBuilder = new StringBuilder ( array . length * 5 + array . length - 1 );
3864- for ( int i = startIndex ; i < endIndex ; i ++) {
3865- stringBuilder
3866- . append ( array [ i ])
3867- .append (delimiter );
3877+ final byte maxElementChars = 5 ; // "false"
3878+ final StringBuilder stringBuilder = capacity ( count , maxElementChars );
3879+ stringBuilder . append ( array [ startIndex ]);
3880+ for ( int i = startIndex + 1 ; i < endIndex ; i ++) {
3881+ stringBuilder .append (delimiter ). append ( array [ i ] );
38683882 }
3869- return stringBuilder .substring ( 0 , stringBuilder . length () - 1 );
3883+ return stringBuilder .toString ( );
38703884 }
38713885
38723886 /**
@@ -3929,19 +3943,21 @@ public static String join(final byte[] array, final char delimiter) {
39293943 * @since 3.2
39303944 */
39313945 public static String join (final byte [] array , final char delimiter , final int startIndex , final int endIndex ) {
3946+ // See StringUtilsJoinBenchmark
39323947 if (array == null ) {
39333948 return null ;
39343949 }
3935- if (endIndex - startIndex <= 0 ) {
3950+ final int count = endIndex - startIndex ;
3951+ if (count <= 0 ) {
39363952 return EMPTY ;
39373953 }
3938- final StringBuilder stringBuilder = new StringBuilder ();
3939- for ( int i = startIndex ; i < endIndex ; i ++) {
3940- stringBuilder
3941- . append ( array [ i ])
3942- .append (delimiter );
3954+ final byte maxElementChars = 4 ; // "-128"
3955+ final StringBuilder stringBuilder = capacity ( count , maxElementChars );
3956+ stringBuilder . append ( array [ startIndex ]);
3957+ for ( int i = startIndex + 1 ; i < endIndex ; i ++) {
3958+ stringBuilder .append (delimiter ). append ( array [ i ] );
39433959 }
3944- return stringBuilder .substring ( 0 , stringBuilder . length () - 1 );
3960+ return stringBuilder .toString ( );
39453961 }
39463962
39473963 /**
@@ -4004,19 +4020,21 @@ public static String join(final char[] array, final char delimiter) {
40044020 * @since 3.2
40054021 */
40064022 public static String join (final char [] array , final char delimiter , final int startIndex , final int endIndex ) {
4023+ // See StringUtilsJoinBenchmark
40074024 if (array == null ) {
40084025 return null ;
40094026 }
4010- if (endIndex - startIndex <= 0 ) {
4027+ final int count = endIndex - startIndex ;
4028+ if (count <= 0 ) {
40114029 return EMPTY ;
40124030 }
4013- final StringBuilder stringBuilder = new StringBuilder ( array . length * 2 - 1 ) ;
4014- for ( int i = startIndex ; i < endIndex ; i ++) {
4015- stringBuilder
4016- . append ( array [ i ])
4017- .append (delimiter );
4031+ final byte maxElementChars = 1 ;
4032+ final StringBuilder stringBuilder = capacity ( count , maxElementChars );
4033+ stringBuilder . append ( array [ startIndex ]);
4034+ for ( int i = startIndex + 1 ; i < endIndex ; i ++) {
4035+ stringBuilder .append (delimiter ). append ( array [ i ] );
40184036 }
4019- return stringBuilder .substring ( 0 , stringBuilder . length () - 1 );
4037+ return stringBuilder .toString ( );
40204038 }
40214039
40224040 /**
@@ -4079,19 +4097,21 @@ public static String join(final double[] array, final char delimiter) {
40794097 * @since 3.2
40804098 */
40814099 public static String join (final double [] array , final char delimiter , final int startIndex , final int endIndex ) {
4100+ // See StringUtilsJoinBenchmark
40824101 if (array == null ) {
40834102 return null ;
40844103 }
4085- if (endIndex - startIndex <= 0 ) {
4104+ final int count = endIndex - startIndex ;
4105+ if (count <= 0 ) {
40864106 return EMPTY ;
40874107 }
4088- final StringBuilder stringBuilder = new StringBuilder ();
4089- for ( int i = startIndex ; i < endIndex ; i ++) {
4090- stringBuilder
4091- . append ( array [ i ])
4092- .append (delimiter );
4108+ final byte maxElementChars = 22 ; // "1.7976931348623157E308"
4109+ final StringBuilder stringBuilder = capacity ( count , maxElementChars );
4110+ stringBuilder . append ( array [ startIndex ]);
4111+ for ( int i = startIndex + 1 ; i < endIndex ; i ++) {
4112+ stringBuilder .append (delimiter ). append ( array [ i ] );
40934113 }
4094- return stringBuilder .substring ( 0 , stringBuilder . length () - 1 );
4114+ return stringBuilder .toString ( );
40954115 }
40964116
40974117 /**
@@ -4154,19 +4174,21 @@ public static String join(final float[] array, final char delimiter) {
41544174 * @since 3.2
41554175 */
41564176 public static String join (final float [] array , final char delimiter , final int startIndex , final int endIndex ) {
4177+ // See StringUtilsJoinBenchmark
41574178 if (array == null ) {
41584179 return null ;
41594180 }
4160- if (endIndex - startIndex <= 0 ) {
4181+ final int count = endIndex - startIndex ;
4182+ if (count <= 0 ) {
41614183 return EMPTY ;
41624184 }
4163- final StringBuilder stringBuilder = new StringBuilder ();
4164- for ( int i = startIndex ; i < endIndex ; i ++) {
4165- stringBuilder
4166- . append ( array [ i ])
4167- .append (delimiter );
4185+ final byte maxElementChars = 12 ; // "3.4028235E38"
4186+ final StringBuilder stringBuilder = capacity ( count , maxElementChars );
4187+ stringBuilder . append ( array [ startIndex ]);
4188+ for ( int i = startIndex + 1 ; i < endIndex ; i ++) {
4189+ stringBuilder .append (delimiter ). append ( array [ i ] );
41684190 }
4169- return stringBuilder .substring ( 0 , stringBuilder . length () - 1 );
4191+ return stringBuilder .toString ( );
41704192 }
41714193
41724194 /**
@@ -4229,19 +4251,21 @@ public static String join(final int[] array, final char separator) {
42294251 * @since 3.2
42304252 */
42314253 public static String join (final int [] array , final char delimiter , final int startIndex , final int endIndex ) {
4254+ // See StringUtilsJoinBenchmark
42324255 if (array == null ) {
42334256 return null ;
42344257 }
4235- if (endIndex - startIndex <= 0 ) {
4258+ final int count = endIndex - startIndex ;
4259+ if (count <= 0 ) {
42364260 return EMPTY ;
42374261 }
4238- final StringBuilder stringBuilder = new StringBuilder ();
4239- for ( int i = startIndex ; i < endIndex ; i ++) {
4240- stringBuilder
4241- . append ( array [ i ])
4242- .append (delimiter );
4262+ final byte maxElementChars = 11 ; // "-2147483648"
4263+ final StringBuilder stringBuilder = capacity ( count , maxElementChars );
4264+ stringBuilder . append ( array [ startIndex ]);
4265+ for ( int i = startIndex + 1 ; i < endIndex ; i ++) {
4266+ stringBuilder .append (delimiter ). append ( array [ i ] );
42434267 }
4244- return stringBuilder .substring ( 0 , stringBuilder . length () - 1 );
4268+ return stringBuilder .toString ( );
42454269 }
42464270
42474271 /**
@@ -4467,19 +4491,21 @@ public static String join(final long[] array, final char separator) {
44674491 * @since 3.2
44684492 */
44694493 public static String join (final long [] array , final char delimiter , final int startIndex , final int endIndex ) {
4494+ // See StringUtilsJoinBenchmark
44704495 if (array == null ) {
44714496 return null ;
44724497 }
4473- if (endIndex - startIndex <= 0 ) {
4498+ final int count = endIndex - startIndex ;
4499+ if (count <= 0 ) {
44744500 return EMPTY ;
44754501 }
4476- final StringBuilder stringBuilder = new StringBuilder ();
4477- for ( int i = startIndex ; i < endIndex ; i ++) {
4478- stringBuilder
4479- . append ( array [ i ])
4480- .append (delimiter );
4502+ final byte maxElementChars = 20 ; // "-9223372036854775808"
4503+ final StringBuilder stringBuilder = capacity ( count , maxElementChars );
4504+ stringBuilder . append ( array [ startIndex ]);
4505+ for ( int i = startIndex + 1 ; i < endIndex ; i ++) {
4506+ stringBuilder .append (delimiter ). append ( array [ i ] );
44814507 }
4482- return stringBuilder .substring ( 0 , stringBuilder . length () - 1 );
4508+ return stringBuilder .toString ( );
44834509 }
44844510
44854511 /**
@@ -4661,19 +4687,21 @@ public static String join(final short[] array, final char delimiter) {
46614687 * @since 3.2
46624688 */
46634689 public static String join (final short [] array , final char delimiter , final int startIndex , final int endIndex ) {
4690+ // See StringUtilsJoinBenchmark
46644691 if (array == null ) {
46654692 return null ;
46664693 }
4667- if (endIndex - startIndex <= 0 ) {
4694+ final int count = endIndex - startIndex ;
4695+ if (count <= 0 ) {
46684696 return EMPTY ;
46694697 }
4670- final StringBuilder stringBuilder = new StringBuilder ();
4671- for ( int i = startIndex ; i < endIndex ; i ++) {
4672- stringBuilder
4673- . append ( array [ i ])
4674- .append (delimiter );
4698+ final byte maxElementChars = 6 ; // "-32768"
4699+ final StringBuilder stringBuilder = capacity ( count , maxElementChars );
4700+ stringBuilder . append ( array [ startIndex ]);
4701+ for ( int i = startIndex + 1 ; i < endIndex ; i ++) {
4702+ stringBuilder .append (delimiter ). append ( array [ i ] );
46754703 }
4676- return stringBuilder .substring ( 0 , stringBuilder . length () - 1 );
4704+ return stringBuilder .toString ( );
46774705 }
46784706
46794707 /**
0 commit comments