Skip to content

Commit

Permalink
[LANG-1290] StringUtils.join() with support for List<?> with
Browse files Browse the repository at this point in the history
configurable start/end indices.
  • Loading branch information
joschi authored and garydgregory committed May 22, 2018
1 parent 09ef69c commit 87937b2
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/main/java/org/apache/commons/lang3/StringUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4721,6 +4721,82 @@ public static String join(final Iterable<?> iterable, final String separator) {
return join(iterable.iterator(), separator);
}

/**
* <p>Joins the elements of the provided {@code List} into a single String
* containing the provided list of elements.</p>
*
* <p>No delimiter is added before or after the list.
* Null objects or empty strings within the array are represented by
* empty strings.</p>
*
* <pre>
* StringUtils.join(null, *) = null
* StringUtils.join([], *) = ""
* StringUtils.join([null], *) = ""
* StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
* StringUtils.join(["a", "b", "c"], null) = "abc"
* StringUtils.join([null, "", "a"], ';') = ";;a"
* </pre>
*
* @param list the {@code List} of values to join together, may be null
* @param separator the separator character to use
* @param startIndex the first index to start joining from. It is
* an error to pass in an end index past the end of the list
* @param endIndex the index to stop joining from (exclusive). It is
* an error to pass in an end index past the end of the list
* @return the joined String, {@code null} if null list input
* @since 3.8
*/
public static String join(final List<?> list, final char separator, final int startIndex, final int endIndex) {
if (list == null) {
return null;
}
final int noOfItems = endIndex - startIndex;
if (noOfItems <= 0) {
return EMPTY;
}
final List<?> subList = list.subList(startIndex, endIndex);
return join(subList.iterator(), separator);
}

/**
* <p>Joins the elements of the provided {@code List} into a single String
* containing the provided list of elements.</p>
*
* <p>No delimiter is added before or after the list.
* Null objects or empty strings within the array are represented by
* empty strings.</p>
*
* <pre>
* StringUtils.join(null, *) = null
* StringUtils.join([], *) = ""
* StringUtils.join([null], *) = ""
* StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
* StringUtils.join(["a", "b", "c"], null) = "abc"
* StringUtils.join([null, "", "a"], ';') = ";;a"
* </pre>
*
* @param list the {@code List} of values to join together, may be null
* @param separator the separator character to use
* @param startIndex the first index to start joining from. It is
* an error to pass in an end index past the end of the list
* @param endIndex the index to stop joining from (exclusive). It is
* an error to pass in an end index past the end of the list
* @return the joined String, {@code null} if null list input
* @since 3.8
*/
public static String join(final List<?> list, final String separator, final int startIndex, final int endIndex) {
if (list == null) {
return null;
}
final int noOfItems = endIndex - startIndex;
if (noOfItems <= 0) {
return EMPTY;
}
final List<?> subList = list.subList(startIndex, endIndex);
return join(subList.iterator(), separator);
}

/**
* <p>Joins the elements of the provided varargs into a
* single String containing the provided elements.</p>
Expand Down
38 changes: 38 additions & 0 deletions src/test/java/org/apache/commons/lang3/StringUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.PatternSyntaxException;
Expand Down Expand Up @@ -100,6 +101,11 @@ public String toString() {
private static final char[] CHAR_PRIM_LIST = {'1', '2'};
private static final float[] FLOAT_PRIM_LIST = {1, 2};
private static final double[] DOUBLE_PRIM_LIST = {1, 2};
private static final List<String> MIXED_STRING_LIST = Arrays.asList(null, "", "foo");
private static final List<Object> MIXED_TYPE_OBJECT_LIST = Arrays.<Object>asList("foo", Long.valueOf(2L));
private static final List<String> STRING_LIST = Arrays.asList("foo", "bar", "baz");
private static final List<String> EMPTY_STRING_LIST = Collections.emptyList();
private static final List<String> NULL_STRING_LIST = Collections.singletonList(null);

private static final String SEPARATOR = ",";
private static final char SEPARATOR_CHAR = ';';
Expand Down Expand Up @@ -366,6 +372,38 @@ public void testJoin_ArrayString() {
assertEquals("", StringUtils.join(MIXED_TYPE_LIST, "/", 2, 1));
}

@Test
public void testJoin_List() {
assertNull(StringUtils.join((List<String>) null, null));
assertEquals(TEXT_LIST_NOSEP, StringUtils.join(STRING_LIST, null));
assertEquals(TEXT_LIST_NOSEP, StringUtils.join(STRING_LIST, ""));

assertEquals("", StringUtils.join(NULL_STRING_LIST, null));

assertEquals("", StringUtils.join(EMPTY_STRING_LIST, null));
assertEquals("", StringUtils.join(EMPTY_STRING_LIST, ""));
assertEquals("", StringUtils.join(EMPTY_STRING_LIST, SEPARATOR));

assertEquals(TEXT_LIST, StringUtils.join(STRING_LIST, SEPARATOR));
assertEquals(",,foo", StringUtils.join(MIXED_STRING_LIST, SEPARATOR));
assertEquals("foo,2", StringUtils.join(MIXED_TYPE_OBJECT_LIST, SEPARATOR));

assertEquals("/", StringUtils.join(MIXED_STRING_LIST, "/", 0, MIXED_STRING_LIST.size() - 1));
assertEquals("", StringUtils.join(MIXED_STRING_LIST, "", 0, MIXED_STRING_LIST.size()- 1));
assertEquals("foo", StringUtils.join(MIXED_TYPE_OBJECT_LIST, "/", 0, 1));
assertEquals("foo/2", StringUtils.join(MIXED_TYPE_OBJECT_LIST, "/", 0, 2));
assertEquals("2", StringUtils.join(MIXED_TYPE_OBJECT_LIST, "/", 1, 2));
assertEquals("", StringUtils.join(MIXED_TYPE_OBJECT_LIST, "/", 2, 1));
assertNull(null, StringUtils.join((List) null, "/", 0, 1));

assertEquals("/", StringUtils.join(MIXED_STRING_LIST, '/', 0, MIXED_STRING_LIST.size() - 1));
assertEquals("foo", StringUtils.join(MIXED_TYPE_OBJECT_LIST, '/', 0, 1));
assertEquals("foo/2", StringUtils.join(MIXED_TYPE_OBJECT_LIST, '/', 0, 2));
assertEquals("2", StringUtils.join(MIXED_TYPE_OBJECT_LIST, '/', 1, 2));
assertEquals("", StringUtils.join(MIXED_TYPE_OBJECT_LIST, '/', 2, 1));
assertNull(null, StringUtils.join((List) null, '/', 0, 1));
}

@Test
public void testJoin_IteratorChar() {
assertNull(StringUtils.join((Iterator<?>) null, ','));
Expand Down

0 comments on commit 87937b2

Please sign in to comment.