【发布时间】:2016-11-20 09:44:45
【问题描述】:
假设,我有一个数组:
int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
我需要使用分隔符连接它的元素,例如," - ",所以结果我应该得到这样的字符串:
"1 - 2 - 3 - 4 - 5 - 6 - 7"
我该怎么做?
【问题讨论】:
标签: java arrays join separator
假设,我有一个数组:
int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
我需要使用分隔符连接它的元素,例如," - ",所以结果我应该得到这样的字符串:
"1 - 2 - 3 - 4 - 5 - 6 - 7"
我该怎么做?
【问题讨论】:
标签: java arrays join separator
这就是我想出的。有几种方法可以做到这一点,它们取决于您使用的工具。
使用来自Common Lang 的StringUtils 和ArrayUtils:
int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
String result = StringUtils.join(ArrayUtils.toObject(arr), " - ");
您不能只使用StringUtils.join(arr, " - ");,因为StringUtils 没有该方法的重载版本。不过,它有方法StringUtils.join(int[], char)。
适用于任何 Java 版本,从 1.2 开始。
使用 Java 8 流:
类似这样的:
int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
String result = Arrays.stream(arr)
.mapToObj(String::valueOf)
.collect(Collectors.joining(" - "));
事实上,使用流来实现结果有很多变化。
Java 8 的方法String.join() 仅适用于字符串,因此要使用它,您仍然需要将int[] 转换为String[]。
String[] sarr = Arrays.stream(arr).mapToObj(String::valueOf).toArray(String[]::new);
String result = String.join(" - ", sarr);
如果您坚持使用没有库的 Java 7 或更早版本,您可以编写自己的实用程序方法:
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();
}
比你能做的:
int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
String result = myJoin(arr, " - ");
【讨论】:
.collect(Collectors.joining(","))代替临时字符串数组。
Arrays.stream(arr) 产生一个 IntStream 并且其中没有这样的 collect() 方法。
您可以使用 Guava 来连接元素。您可以在此处找到更多示例和文档。 https://github.com/google/guava/wiki/StringsExplained
Joiner.on("-")
.join(texts);
更准确地说,您应该首先将数组包装成 List 和 Arrays.asList() 或 Guava 的 primitive-friendly 等效项。
Joiner.on("-")
.join(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
Joiner.on("-")
.join(Ints.asList(arr));
【讨论】:
.asList() 方法,例如Ints.asList() - 您不能将 Array.asList() 与原始数组一起使用。
Arrays.asList(arr) 将生成一个大小为 1 的 List =) 这就是我们的原始数组中的一个元素。
在 Java 8+ 中,您可以使用 IntStream 和 StringJoiner。类似的,
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());
输出是(按要求)
1 - 2 - 3 - 4 - 5 - 6 - 7
【讨论】:
我确信在 Kotlin/Scala 或其他 JVM 语言中也有一种方法可以做到这一点,但您始终可以坚持让事情变得简单,就像上面一样:
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() );
【讨论】:
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7 };
IntStream.of(arr).mapToObj(i -> String.valueOf(i)).collect(Collectors.joining(",")) ;
【讨论】:
我一直在寻找一种在流中加入基元的方法,而无需先为每个基元实例化字符串。我已经解决了这个问题,但它仍然需要对它们进行拳击。
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));
【讨论】:
Java 8 解决方案是这样的:
Stream.of(1,2,3,4).map(String::valueOf).collect(Collectors.joining("-"))
【讨论】:
适用于 Java 7 或更早版本。
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("]"));
}
输出:
1 - 2 - 3 - 4
[1 - 2 - 3 - 4]
【讨论】:
如果您的分隔符是单个字符,您可以使用 Common Lang 中的StringUtils:
int[] arr = {1, 2, 3, 4, 5, 6, 7};
String result = StringUtils.join(arr, '-');
但是,如果分隔符是字符串,您应该使用替代方法,因为 StringUtils 的行为很糟糕 (see this ticket)。
【讨论】: