Java: объединить массив примитивов с разделителем
Предположим, у меня есть массив:
int[] arr = new int[] {1, 2, 3, 4, 5, 6, 7};
И мне нужно объединить его элементы с помощью разделителя, например, " - "
в результате я должен получить строку вроде этой:
"1 - 2 - 3 - 4 - 5 - 6 - 7"
Как я мог это сделать?
PS: да, я знаю об этом и этом постах, но его решения не будут работать с массивом примитивов.
6 ответов
Вот что я придумала. Есть несколько способов сделать это, и они зависят от инструментов, которые вы используете.
С помощью 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, " - ");
Решение Java 8 будет выглядеть так:
Stream.of(1,2,3,4).map(String::valueOf).collect(Collectors.joining("-"))
В 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
Вы можете использовать гуаву для соединения элементов. Больше примеров и документов вы можете найти там. https://github.com/google/guava/wiki/StringsExplained
Joiner.on("-")
.join(texts);
Чтобы быть более точным, вы должны сначала обернуть ваш массив в List
с Arrays.asList()
или примитивно-дружественные эквиваленты Гуавы.
Joiner.on("-")
.join(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
Joiner.on("-")
.join(Ints.asList(arr));
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7 };
IntStream.of(arr).mapToObj(i -> String.valueOf(i)).collect(Collectors.joining(",")) ;
Я уверен, что есть способ сделать это на 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() );
Если ваш разделитель представляет собой один символ, вы можете использовать StringUtils из Common Lang:
int[] arr = {1, 2, 3, 4, 5, 6, 7};
String result = StringUtils.join(arr, '-');
Однако, если разделителем является строка, вы должны использовать альтернативу, потому что StringUtils ведет себя плохо (см. Этот билет).
Для 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]
Я искал способ присоединения примитивов в потоке без предварительного создания строк для каждого из них. Я пришел к этому, но он все еще требует бокса их.
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));
В java8 вы можете использовать класс String как:
String joined = String.join(",", name);