1717package io .microsphere .util ;
1818
1919import io .microsphere .annotation .Immutable ;
20+ import io .microsphere .annotation .Nonnull ;
2021import io .microsphere .annotation .Nullable ;
2122
22- import java .util .StringTokenizer ;
23+ import java .util .ArrayList ;
24+ import java .util .Collection ;
25+ import java .util .List ;
2326
24- import static io .microsphere .util .ArrayUtils .asArray ;
27+ import static io .microsphere .collection .CollectionUtils .isEmpty ;
28+ import static io .microsphere .util .ArrayUtils .ofArray ;
2529import static io .microsphere .util .CharSequenceUtils .isEmpty ;
2630import static io .microsphere .util .CharSequenceUtils .length ;
2731import static java .lang .Character .isDigit ;
2832import static java .lang .Character .isWhitespace ;
2933import static java .lang .Character .toLowerCase ;
3034import static java .lang .Character .toUpperCase ;
31- import static java .lang .String .valueOf ;
3235
3336/**
3437 * The utilities class for {@link String}
@@ -127,8 +130,29 @@ public static boolean isNotBlank(String value) {
127130 * @param delimiter the char used as a delimiter to split the String
128131 * @return an array of Strings, split by the delimiter; never null
129132 */
130- public static String [] split (String value , char delimiter ) {
131- return split (value , valueOf (delimiter ));
133+ @ Nonnull
134+ public static String [] split (@ Nullable String value , char delimiter ) {
135+ int length = length (value );
136+ if (length < 1 ) {
137+ return EMPTY_STRING_ARRAY ;
138+ }
139+
140+ List <String > result = new ArrayList <>();
141+
142+ int startIndex = 0 ;
143+ int endIndex ;
144+
145+ while ((endIndex = value .indexOf (delimiter , startIndex )) > -1 ) {
146+ String part = value .substring (startIndex , endIndex );
147+ result .add (part );
148+ startIndex = endIndex + 1 ;
149+ }
150+ if (startIndex <= length ) {
151+ // Add rest of String, but not in case of empty input.
152+ result .add (value .substring (startIndex ));
153+ }
154+
155+ return toStringArray (result );
132156 }
133157
134158 /**
@@ -140,7 +164,9 @@ public static String[] split(String value, char delimiter) {
140164 * <h3>Example Usage</h3>
141165 * <pre>{@code
142166 * StringUtils.split(null, ",") = []
167+ * StringUtils.split("", null) = []
143168 * StringUtils.split("", ";") = []
169+ * StringUtils.split("abc", "") = ["a", "b", "c"]
144170 * StringUtils.split("a,b,c", ",") = ["a", "b", "c"]
145171 * StringUtils.split("a;b;c", ",") = ["a;b;c"]
146172 * StringUtils.split("a,,b,c", ",") = ["a", "", "b", "c"]
@@ -150,12 +176,41 @@ public static String[] split(String value, char delimiter) {
150176 * @param delimiter the String used as a delimiter to split the String, may be null or empty
151177 * @return an array of Strings, split by the delimiter; never null
152178 */
153- public static String [] split (String value , String delimiter ) {
154- if (isEmpty (value ) || isEmpty (delimiter )) {
179+ @ Nonnull
180+ public static String [] split (@ Nullable String value , @ Nullable String delimiter ) {
181+ int length = length (value );
182+ if (length < 1 ) {
155183 return EMPTY_STRING_ARRAY ;
156184 }
157- StringTokenizer stringTokenizer = new StringTokenizer (value , delimiter );
158- return (String []) asArray (stringTokenizer , String .class );
185+
186+ if (delimiter == null ) {
187+ return ofArray (value );
188+ }
189+
190+ int delimiterLength = delimiter .length ();
191+
192+ List <String > result = new ArrayList <>();
193+
194+ if (delimiterLength == 0 ) {
195+ for (int i = 0 ; i < value .length (); i ++) {
196+ result .add (value .substring (i , i + 1 ));
197+ }
198+ } else {
199+ int startIndex = 0 ;
200+ int endIndex ;
201+
202+ while ((endIndex = value .indexOf (delimiter , startIndex )) > -1 ) {
203+ String part = value .substring (startIndex , endIndex );
204+ result .add (part );
205+ startIndex = endIndex + delimiterLength ;
206+ }
207+ if (startIndex <= length ) {
208+ // Add rest of String, but not in case of empty input.
209+ result .add (value .substring (startIndex ));
210+ }
211+ }
212+
213+ return toStringArray (result );
159214 }
160215
161216 /**
@@ -780,6 +835,26 @@ public static String uncapitalize(String str) {
780835 return changeFirstCharacter (str , false );
781836 }
782837
838+ /**
839+ * Convert the given {@link Collection} into a {@code String} array.
840+ * <p>The {@code Collection} must contain {@code String} elements only.
841+ *
842+ * <h3>Example Usage</h3>
843+ * <pre>{@code
844+ * StringUtils.toStringArray(null) = []
845+ * StringUtils.toStringArray(new ArrayList<>()) = []
846+ * StringUtils.toStringArray(Arrays.asList("a", "b", "c")) = ["a", "b", "c"]
847+ * }</pre>
848+ *
849+ * @param collection the {@code Collection} to convert
850+ * (potentially {@code null} or empty)
851+ * @return the resulting {@code String} array
852+ */
853+ @ Nonnull
854+ public static String [] toStringArray (@ Nullable Collection <String > collection ) {
855+ return (!isEmpty (collection ) ? collection .toArray (EMPTY_STRING_ARRAY ) : EMPTY_STRING_ARRAY );
856+ }
857+
783858 static String changeFirstCharacter (String str , boolean capitalize ) {
784859 int len = length (str );
785860 if (len < 1 ) {
0 commit comments