43

Suppose, I have an array:

int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};

And I need to join its elements using separator, for example, " - ", so as the result I should get string like this:

"1 - 2 - 3 - 4 - 5 - 6 - 7"

How could I do this?

PS: yes, I know about this and this posts, but its solutions won't work with an array of primitives.

Community
  • 1
  • 1
spirit
  • 3,265
  • 2
  • 14
  • 29

9 Answers9

88

Here's what I came up with. There are several ways to do this and they depend on the tools you are using.


Using StringUtils and ArrayUtils from Commons Lang:

int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
String result = StringUtils.join(ArrayUtils.toObject(arr), " - ");

You can't just use StringUtils.join(arr, " - "); because StringUtils doesn't have that overloaded version of method. Though, it has method StringUtils.join(int[], char).

Works at any Java version, from 1.2.


Using Java 8 streams:

Something like this:

int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
String result = Arrays.stream(arr)
        .mapToObj(String::valueOf)
        .collect(Collectors.joining(" - "));

In fact, there are lot of variations to achieve it using streams.

Java 8's method String.join() works only with strings, so to use it you still have to convert int[] to String[].

String[] sarr = Arrays.stream(arr).mapToObj(String::valueOf).toArray(String[]::new);
String result = String.join(" - ", sarr);

If you're stuck using Java 7 or earlier with no libraries, you could write your own utility method:

public static String myJoin(int[] arr, String separator) {
    if (null == arr || 0 == arr.length) return "";

    StringBuilder sb = new StringBuilder(256);
    sb.append(arr[0]);

    //if (arr.length == 1) return sb.toString();

    for (int i = 1; i < arr.length; i++) sb.append(separator).append(arr[i]);

    return sb.toString();
}

Then you can do:

int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
String result = myJoin(arr, " - ");
Pang
  • 9,564
  • 146
  • 81
  • 122
spirit
  • 3,265
  • 2
  • 14
  • 29
  • 4
    You can `.collect(Collectors.joining(","))` instead of the temp string array. – shmosel Jul 17 '16 at 20:29
  • 2
    Nice overview! For the java 1.7 version: Technically you wont need the arr.length == 1 check before the loop but this works perfectly as well. – n247s Jul 17 '16 at 20:33
  • @shmosel, nope. `Arrays.stream(arr)` produces an `IntStream` and in it there is no such `collect()` method. – spirit Jul 17 '16 at 20:34
15

Java 8 Solution would be like this:

Stream.of(1,2,3,4).map(String::valueOf).collect(Collectors.joining("-"))
Denis Sablukov
  • 3,360
  • 2
  • 26
  • 31
user2935131
  • 157
  • 1
  • 4
12

In Java 8+ you could use an IntStream and a StringJoiner. Something like,

int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7 };
StringJoiner sj = new StringJoiner(" - ");
IntStream.of(arr).forEach(x -> sj.add(String.valueOf(x)));
System.out.println(sj.toString());

Output is (as requested)

1 - 2 - 3 - 4 - 5 - 6 - 7
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
5

You can use Guava for joining elements. More examples and docs you can find there. https://github.com/google/guava/wiki/StringsExplained

Joiner.on("-")
      .join(texts);

To be more precise you should firstly wrap your array into a List with Arrays.asList() or Guava's primitive-friendly equivalents.

Joiner.on("-")
      .join(Arrays.asList(1, 2, 3, 4, 5, 6, 7));

Joiner.on("-")
      .join(Ints.asList(arr));
dimo414
  • 47,227
  • 18
  • 148
  • 244
RMachnik
  • 3,598
  • 1
  • 34
  • 51
  • 2
    For primitive arrays Gava provides primitive `.asList()` methods, e.g. [`Ints.asList()`](https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/primitives/Ints.html#asList(int...)) - you can't use `Array.asList()` with primitive arrays. – dimo414 Jul 17 '16 at 20:38
  • yep, `Arrays.asList(arr)` will produce a `List` with size of 1 =) And that's one element will be our primitive array. – spirit Jul 17 '16 at 20:42
2

I'm sure there's a way to do this in Kotlin/Scala or other JVM languages as well but you could always stick to keeping things simple for a small set of values like you have above:

int i, arrLen = arr.length;
 StringBuilder tmp = new StringBuilder();
 for (i=0; i<arrLen-1; i++)
    tmp.append(arr[i] +" - ");
 tmp.append(arr[arrLen-1]);

 System.out.println( tmp.toString() );
engAnt
  • 151
  • 8
2
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7 };

IntStream.of(arr).mapToObj(i -> String.valueOf(i)).collect(Collectors.joining(",")) ;
azro
  • 53,056
  • 7
  • 34
  • 70
Lin W
  • 289
  • 4
  • 4
2

If your delimiter is a single char you can use StringUtils from Common Lang:

int[] arr = {1, 2, 3, 4, 5, 6, 7};
String result = StringUtils.join(arr, '-');

However, if the delimiter is a String, you should use an alternative because StringUtils is behaving badly (see this ticket).

spirit
  • 3,265
  • 2
  • 14
  • 29
Kiruahxh
  • 1,276
  • 13
  • 30
1

I've been looking for a way to join primitives in a Stream without first instantiating strings for each one of them. I've come to this but it still requires boxing them.

LongStream.range(0, 500).boxed().collect(Collector.of(StringBuilder::new, (sb, v) -> {
    if (sb.length() != 0)
        sb.append(',');
    sb.append(v.longValue());
}, (a, b) -> a.length() == 0 ? b : b.length() != 0 ? a.append(',').append(b) : a, StringBuilder::toString));
bourne2program
  • 121
  • 1
  • 5
1

For Java 7 or earlier.

public static StringBuilder join(CharSequence delimiter, int... arr) {
    if (null == delimiter || null == arr) throw new NullPointerException();

    StringBuilder sb = new StringBuilder(String.valueOf(arr[0]));
    for (int i = 1; i < arr.length; i++) sb.append(delimiter).append(arr[i]);

    return sb;
}

public static void main(String[] args) {
    StringBuilder sb = join(" - ", 1, 2, 3, 4);
    System.out.println(sb.toString());//you could pass sb also coz println automatically call toString method within it
    System.out.println(sb.insert(0, "[").append("]"));
}

Output:

1 - 2 - 3 - 4

[1 - 2 - 3 - 4]

Mehdi
  • 3,795
  • 3
  • 36
  • 65