Java: функция для массивов, таких как PHP join()?
Я хочу присоединиться к String[]
с помощью клеевой нити. Есть ли функция для этого?
24 ответа
Начиная с Java8 можно использовать String.join()
,
String.join(", ", new String[]{"Hello", "World", "!"})
Формирует:
Hello, World, !
В противном случае Apache Commons Lang имеет StringUtils
класс, который имеет join
функция, которая объединит массивы вместе, чтобы сделать String
,
Например:
StringUtils.join(new String[] {"Hello", "World", "!"}, ", ")
Создает следующее String
:
Hello, World, !
Если вы искали, что использовать в Android, это:
String android.text.TextUtils.join(CharSequence delimiter, Object[] tokens)
например:
String joined = TextUtils.join(";", MyStringArray);
В Java 8 вы можете использовать
1) Stream API:
String[] a = new String[] {"a", "b", "c"};
String result = Arrays.stream(a).collect(Collectors.joining(", "));
2) новый метод String.join: /questions/10109601/java-ekvivalentyi-c-stringformat-i-stringjoin/10109631#10109631
3) класс java.util.StringJoiner: http://docs.oracle.com/javase/8/docs/api/java/util/StringJoiner.html
Вы можете легко написать такую функцию примерно в десяти строках кода:
String combine(String[] s, String glue)
{
int k = s.length;
if ( k == 0 )
{
return null;
}
StringBuilder out = new StringBuilder();
out.append( s[0] );
for ( int x=1; x < k; ++x )
{
out.append(glue).append(s[x]);
}
return out.toString();
}
Небольшой мод вместо использования substring():
//join(String array,delimiter)
public static String join(String r[],String d)
{
if (r.length == 0) return "";
StringBuilder sb = new StringBuilder();
int i;
for(i=0;i<r.length-1;i++){
sb.append(r[i]);
sb.append(d);
}
sb.append(r[i]);
return sb.toString();
}
Как и многие вопросы в последнее время, Java 8 на помощь:
Java 8 добавил новый статический метод java.lang.String
который делает именно то, что вы хотите:
public static String join(CharSequence delimeter, CharSequence... elements);
Используй это:
String s = String.join(", ", new String[] {"Hello", "World", "!"});
Результаты в:
"Hello, World, !"
Библиотека Google Guava также имеет такую возможность. Вы можете увидеть пример String[] также из API.
Как уже описано в API, остерегайтесь неизменности методов компоновщика.
Он может принимать массив объектов, поэтому он будет работать в вашем случае. В моем предыдущем опыте я попытался присоединиться к стеку, который является итеративным, и он отлично работает.
Образец от меня:
Deque<String> nameStack = new ArrayDeque<>();
nameStack.push("a coder");
nameStack.push("i am");
System.out.println("|" + Joiner.on(' ').skipNulls().join(nameStack) + "|");
распечатывает: |i am a coder|
Если вы используете Spring Framework, то у вас есть класс StringUtils:
import static org.springframework.util.StringUtils.arrayToDelimitedString;
arrayToDelimitedString(new String[] {"A", "B", "C"}, "\n");
Дано:
String[] a = new String[] { "Hello", "World", "!" };
Тогда в качестве альтернативы ответу coobird, где клей ", ":
Arrays.asList(a).toString().replaceAll("^\\[|\\]$", "")
Или объединить с другой строкой, такой как " & amp;".
Arrays.asList(a).toString().replaceAll(", ", " & ").replaceAll("^\\[|\\]$", "")
Однако... это ТОЛЬКО работает, если вы знаете, что значения в массиве или списке НЕ содержат символьную строку ",".
Не в основном, нет. Поиск "склеивания строки присоединения массива Java" даст вам некоторые фрагменты кода о том, как этого добиться.
например
public static String join(Collection s, String delimiter) {
StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
while (iter.hasNext()) {
buffer.append(iter.next());
if (iter.hasNext()) {
buffer.append(delimiter);
}
}
return buffer.toString();
}
Если вы попали сюда в поисках быстрого преобразования массива в строку, попробуйте Arrays.toString ().
Создает строковое представление
Object[]
прошло. Результат заключен в квадратные скобки ("[]"
), каждый элемент преобразуется в строку черезString.valueOf(Object)
и разделены", "
, Если массивnull
, затем"null"
возвращается
Просто для задания "У меня самый короткий", вот мины;)
Повторяющийся:
public static String join(String s, Object... a) {
StringBuilder o = new StringBuilder();
for (Iterator<Object> i = Arrays.asList(a).iterator(); i.hasNext();)
o.append(i.next()).append(i.hasNext() ? s : "");
return o.toString();
}
Рекурсивный:
public static String join(String s, Object... a) {
return a.length == 0 ? "" : a[0] + (a.length == 1 ? "" : s + join(s, Arrays.copyOfRange(a, 1, a.length)));
}
Вот как я это делаю.
private String join(String[] input, String delimiter)
{
StringBuilder sb = new StringBuilder();
for(String value : input)
{
sb.append(value);
sb.append(delimiter);
}
int length = sb.length();
if(length > 0)
{
// Remove the extra delimiter
sb.setLength(length - delimiter.length());
}
return sb.toString();
}
Ничего встроенного, что я знаю.
Apache Commons Lang имеет класс под названием StringUtils
который содержит много функций соединения.
Аналогичная альтернатива
/**
* @param delimiter
* @param inStr
* @return String
*/
public static String join(String delimiter, String... inStr)
{
StringBuilder sb = new StringBuilder();
if (inStr.length > 0)
{
sb.append(inStr[0]);
for (int i = 1; i < inStr.length; i++)
{
sb.append(delimiter);
sb.append(inStr[i]);
}
}
return sb.toString();
}
Мой спин
public static String join(Object[] objects, String delimiter) {
if (objects.length == 0) {
return "";
}
int capacityGuess = (objects.length * objects[0].toString().length())
+ ((objects.length - 1) * delimiter.length());
StringBuilder ret = new StringBuilder(capacityGuess);
ret.append(objects[0]);
for (int i = 1; i < objects.length; i++) {
ret.append(delimiter);
ret.append(objects[i]);
}
return ret.toString();
}
public static String join(Object... objects) {
return join(objects, "");
}
Вам нравится мой трехстрочный способ, использующий только методы класса String?
static String join(String glue, String[] array) {
String line = "";
for (String s : array) line += s + glue;
return (array.length == 0) ? line : line.substring(0, line.length() - glue.length());
}
Какой бы подход вы ни выбрали, помните о нулевых значениях в массиве. Их строковое представление является «нулевым», поэтому, если это нежелательное поведение, пропустите нулевые элементы.
String[] parts = {"Hello", "World", null, "!"};
Stream.of(parts)
.filter(Objects::nonNull)
.collect(Collectors.joining(" "));
Чтобы получить "str1, str2" из "str1", "str2", "":
Stream.of("str1", "str2", "").filter(str -> !str.isEmpty()).collect(Collectors.joining(", "));
Также вы можете добавить дополнительную нулевую проверку
Как уже было сказано, классStringJoiner
также доступен вариант с Java 8:
@NotNull
String stringArrayToCsv(@NotNull String[] data) {
if (data.length == 0) {return "";}
StringJoiner joiner = new StringJoiner(", ");
Iterator<String> itr = Arrays.stream(data).iterator();
while (itr.hasNext()) {joiner.add(itr.next());}
return joiner.toString();
}
Однако традиционныеString.join()
меньше импорта и меньше кода:
@NotNull
String stringArrayToCsv(@NotNull String[] data) {
if (data.length == 0) {return "";}
return String.join(", ", data);
}
Если вы используете функциональную библиотеку Java и по какой-то причине не можете использовать потоки из Java 8 (что может иметь место при использовании плагина Android + Retrolambda), вот функциональное решение для вас:
String joinWithSeparator(List<String> items, String separator) {
return items
.bind(id -> list(separator, id))
.drop(1)
.foldLeft(
(result, item) -> result + item,
""
);
}
Обратите внимание, что это не самый эффективный подход, но он хорошо работает для небольших списков.
Я делаю это таким образом, используя StringBuilder:
public static String join(String[] source, String delimiter) {
if ((null == source) || (source.length < 1)) {
return "";
}
StringBuilder stringbuilder = new StringBuilder();
for (String s : source) {
stringbuilder.append(s + delimiter);
}
return stringbuilder.toString();
} // join((String[], String)
В большинстве случаев я использую простую технику записи.
String op = new String;
for (int i : is)
{
op += candidatesArr[i-1]+",";
}
op = op.substring(0, op.length()-1);
У java.util.Arrays есть метод asList. Вместе с API java.util.List/ArrayList это дает вам все необходимое:;
private static String[] join(String[] array1, String[] array2) {
List<String> list = new ArrayList<String>(Arrays.asList(array1));
list.addAll(Arrays.asList(array2));
return list.toArray(new String[0]);
}