В вопросе о функции apache против средства форматирования строк нет никаких сомнений в том, что функция apache более понятна и проста для чтения. Обертывание форматера в именах функций не идеально.
Но, пожалуйста, обратите внимание, что - как уже упоминалось и продемонстрировано в этом ответе - String.format()и Formatterклассы в JDK являются лучшими вариантами. Используйте их поверх общего кода.
java.util.Formatter (и String.format ()) делает это. Всегда предпочитайте JDK внешней библиотеке, если версия JDK выполняет свою работу (что она и делает).
@Jonik Не могли бы вы перечислить некоторые из ваших причин? API выглядят практически одинаково.
glen3b
3
@ glen3b: Для отдельной утилиты, такой как эти помощники заполнения строк, действительно не имеет значения, какую библиотеку использовать. Тем не менее, Guava в целом является более современной, более чистой и лучше документированной библиотекой, чем ее аналоги в различных проектах Apache Commons (Commons Lang, Commons Collections, Commons IO и т. Д.). Он также построен по-настоящему умными парнями (Кевин Бурриллион и др.), Многие из которых работают в SO . Я сам закончил тем, что заменил различные библиотеки Apache Commons только на Guava несколько лет назад, и не пожалел.
@ Nullw0rm, если вы имеете в виду rgagnon.com, имейте в виду, что RealHowTo также является автором rgagnon.com, поэтому он будет приписывать себе ...
Колин Пикард
3
по крайней мере на моей JVM, "#" не работает, "-" в порядке. (Просто удалите #). Это может не соответствовать документации форматера, я не знаю; он говорит: "#". \ u0023 'Требует, чтобы выходные данные использовали альтернативную форму. Определение формы определяется преобразованием. "
gatoatigrado
6
Спасибо за отличный ответ. Хотя у меня есть сомнения, для чего 1$? @leo сделал очень похожий ответ, который не использует, 1$и он, очевидно, имеет тот же эффект. Есть ли разница?
Фабрисио Мате
257
Заполнение до 10 символов:
String.format("%10s","foo").replace(' ','*');String.format("%-10s","bar").replace(' ','*');String.format("%10s","longer than 10 chars").replace(' ','*');
Так же, как мы все помним, чтобы не передавать в строку с пробелами ...: D
leviathanbadger
4
Я с @ aboveyou00 - это ужасное решение для строк с пробелами, включая пример, предоставленный leo. Решение для заполнения строки слева или справа не должно изменять входную строку так, как она появляется в выходных данных, если только исходное заполнение входной строки не приводит к превышению указанной длины заполнения.
Брайан Уоршоу
3
Признать космический вопрос. .replace(' ', '*')скорее был предназначен, чтобы показать эффект заполнения. Выражение сокрытия пароля не имеет этой проблемы в любом случае ... Для лучшего ответа на настройку левой и правой строки дополнения с использованием встроенной функции Java см. Мой другой ответ.
Лев
Если строка содержит только один пробел, и вы хотите заполнить разными символами, вы можете использовать регулярное выражение заменять взглядом вперед / вперед: String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")илиString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
Обратите внимание: вы инвертировали имена функций; если вы запустите его, вы увидите.
голубоватое
плюс, если оригинальная строка содержит пробелы, это не сработает
Стивен Шоу
@ StevenShaw Если я не ошибаюсь, замена не нацелена на оригинал str, так что это правильно.
Мафу
3
По соглашению вы не должны использовать заглавную букву для имен функций.
главный-идеальный домен
Отсутствует ли условное возвращение строки как есть, когда (length - str.length())есть 0? Форматировщик выдает, FormatFlagsConversionMismatchExceptionкогда %0sэто строка формата.
Девин Уолтерс
7
Это заняло у меня некоторое время, чтобы понять. Настоящим ключом является чтение этой документации Formatter.
// Get your data from wherever.finalbyte[] data = getData();// Get the digest engine.finalMessageDigest md5=MessageDigest.getInstance("MD5");// Send your data through it.
md5.update(data);// Parse the data as a positive BigInteger.finalBigInteger digest =newBigInteger(1,md5.digest());// Pad the digest with blanks, 32 wide.String hex =String.format(// See: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html// Format: %[argument_index$][flags][width]conversion// Conversion: 'x', 'X' integral The result is formatted as a hexadecimal integer"%1$32x",
digest
);// Replace the blank padding with 0s.
hex = hex.replace(" ","0");System.out.println(hex);
Зачем делать конец так сложно? Вы могли просто сделать String hex = String.format ("% 032x", дайджест); и имели те же самые результаты, только без ненужной replace () и необходимости использовать $ для доступа к определенным переменным (в конце концов, есть только одна.)
ArtOfWarfare
@ArtOfWarfare Fair point. Кто-то изначально просил заполнить шестнадцатеричные значения в другом вопросе, я увидел, что у меня есть ссылка на документацию по форматированию. Это сложно для полноты.
Nthalk
6
я знаю, что эта ветка довольно старая, и первоначальный вопрос был для простого решения, но если он должен быть очень быстрым, вы должны использовать массив символов.
Если StringBufferневозможно получить доступ к нескольким потокам одновременно (что в данном случае верно), вы должны использовать StringBuilder(в JDK1.5 +), чтобы избежать накладных расходов на синхронизацию.
glen3b
5
Вот еще один способ подправить вправо:
// put the number of spaces, or any character you like, in your paddedStringString paddedString ="--------------------";String myStringToBePadded ="I like donuts";
myStringToBePadded = myStringToBePadded + paddedString.substring(myStringToBePadded.length());//result:
myStringToBePadded ="I like donuts-------";
В качестве альтернативы вы можете сделать длину результата параметром pad(...)метода. В этом случае выполните настройку скрытого заполнения в этом методе, а не в конструкторе.
(Подсказка: для дополнительного кредита, сделайте это поточно-ориентированным! ;-)
Это потокобезопасно, за исключением небезопасной публикации (сделайте ваши поля окончательными, как само собой разумеющееся). Я думаю, что производительность можно улучшить, выполнив подстроку перед +, которую следует заменить на concat (как ни странно).
Это заполнит вашу строку XXX до 9 символов пробелами. После этого все пробелы будут заменены на 0. Вы можете изменить пробелы и 0 на все, что вы хотите ...
Вы должны вызывать staticметод, String.format(…)вместо того, чтобы злоупотреблять пустой строкой. Сохранение четырех символов в исходном коде, безусловно, не стоит потери читабельности.
Хольгер
2
publicstaticString padLeft(String in,int size,char padChar){if(in.length()<= size){char[] temp =newchar[size];/* Llenado Array con el padChar*/for(int i =0;i<size;i++){
temp[i]= padChar;}int posIniTemp = size-in.length();for(int i=0;i<in.length();i++){
temp[posIniTemp]=in.charAt(i);
posIniTemp++;}returnnewString(temp);}return"";}
Позвольте мне оставить ответ для некоторых случаев, когда вам нужно задать левый / правый отступ (или строку префикса / суффикса, или пробелы) перед тем, как объединить другую строку, и вы не хотите проверять длину или любое условие if.
То же самое к выбранному ответу, я бы предпочел StringUtilsApache Commons, но используя этот способ:
Ответы @ck и @Marlon Tarak - единственные, которые используют a char[], который является лучшим подходом для приложений, которые имеют несколько вызовов методов заполнения в секунду. Тем не менее, они не пользуются какой-либо оптимизацией манипулирования массивами и немного перезаписаны на мой вкус; это можно сделать без каких-либо петель .
publicstaticvoid main(String... args){System.out.println("012345678901234567890123456789");System.out.println(pad("cats",' ',30,true));System.out.println(pad("cats",' ',30,false));System.out.println(pad("cats",' ',20,false));System.out.println(pad("cats",'$',30,true));System.out.println(pad("too long for your own good, buddy",'#',30,true));}
Выходы:
012345678901234567890123456789
cats
cats
cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too longfor your own good, buddy
Вы можете использовать, getCharsчтобы позволить Stringкопировать его содержимое непосредственно в outмассив вместо вызова source.toCharArray(), а затем System.arraycopy. Я бы даже подумал упростить реализацию до char[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);; в то время как это похоже на fillвыполнение дополнительной работы, на самом деле JVM позволяет исключить заполнение нулями по умолчанию.
Хольгер
1
java.util.Formatterсделаю левый и правый отступ. Нет необходимости в нечетных сторонних зависимостях (вы хотите добавить их для чего-то такого тривиального).
[Я упустил детали и сделал этот пост «вики-сообществом», так как он мне не нужен.]
Я не согласен. В любом более крупном Java-проекте вы, как правило, будете выполнять так много манипуляций со строками, что повышение читабельности и избежание ошибок стоит использовать Apache Commons Lang. Вы все знаете код вроде someString.subString (someString.indexOf (startCharacter), someString.lastIndexOf (endCharacter)), которого можно легко избежать с помощью StringUtils.
Bananeweizen
1
Все операции со строками обычно должны быть очень эффективными, особенно если вы работаете с большими наборами данных. Я хотел что-то быстрое и гибкое, похожее на то, что вы получите в команде plsql pad. Кроме того, я не хочу включать огромную библиотеку только для одной маленькой вещи. С учетом этих соображений ни одно из этих решений не было удовлетворительным. Это решения, которые я придумал, которые дали лучшие результаты тестирования, если кто-то может улучшить его, пожалуйста, добавьте свой комментарий.
обратите внимание, что он вызывается с помощью String.toCharArray (), и результат может быть преобразован в строку с новым результатом String ((char [])). Причина этого в том, что если вы применяете несколько операций, вы можете выполнять их все на char [] и не продолжать конвертацию между форматами - за кулисами String сохраняется как char []. Если бы эти операции были включены в сам класс String, он был бы в два раза эффективнее - по скорости и по памяти.
Вот параллельная версия для тех из вас, у кого очень длинные строки :-)
int width =100;String s ="129018";CharSequence padded =IntStream.range(0,width).parallel().map(i->i-(width-s.length())).map(i->i<0?'0':s.charAt(i)).collect(StringBuilder::new,(sb,c)-> sb.append((char)c),(sb1,sb2)->sb1.append(sb2));
Ответы:
Apache
StringUtils
имеет несколько методов:leftPad
,rightPad
,center
иrepeat
.Но, пожалуйста, обратите внимание, что - как уже упоминалось и продемонстрировано в этом ответе -
String.format()
иFormatter
классы в JDK являются лучшими вариантами. Используйте их поверх общего кода.источник
Начиная с Java 1.5,
String.format()
может использоваться для левой / правой панели заданной строки.И вывод:
источник
1$
? @leo сделал очень похожий ответ, который не использует,1$
и он, очевидно, имеет тот же эффект. Есть ли разница?Заполнение до 10 символов:
вывод:
Выведите «*» для символов пароля:
длина вывода равна длине строки пароля:
источник
.replace(' ', '*')
скорее был предназначен, чтобы показать эффект заполнения. Выражение сокрытия пароля не имеет этой проблемы в любом случае ... Для лучшего ответа на настройку левой и правой строки дополнения с использованием встроенной функции Java см. Мой другой ответ.String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
илиString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
В Гуаве это легко:
источник
Нечто простое:
Значение должно быть строкой. преобразовать его в строку, если это не так. Нравится
"" + 123
илиInteger.toString(123)
Начало подстроки от индекса длины значения до конечной длины дополнения:
Точнее
колодка справа:
накладка слева:
источник
Посмотрите на
org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.Но алгоритм очень прост (дополняет до размера символов):
источник
Помимо Apache Commons, также посмотрите,
String.format
какие из них должны быть в состоянии позаботиться о простом заполнении (например, пробелами).источник
источник
str
, так что это правильно.(length - str.length())
есть0
? Форматировщик выдает,FormatFlagsConversionMismatchException
когда%0s
это строка формата.Это заняло у меня некоторое время, чтобы понять. Настоящим ключом является чтение этой документации Formatter.
источник
я знаю, что эта ветка довольно старая, и первоначальный вопрос был для простого решения, но если он должен быть очень быстрым, вы должны использовать массив символов.
решение для форматирования не является оптимальным. просто построение строки формата создает 2 новые строки.
Решение Apache может быть улучшено путем инициализации sb с целевым размером, поэтому замените ниже
с
будет препятствовать росту внутреннего буфера sb.
источник
StringBuffer
невозможно получить доступ к нескольким потокам одновременно (что в данном случае верно), вы должны использоватьStringBuilder
(в JDK1.5 +), чтобы избежать накладных расходов на синхронизацию.Вот еще один способ подправить вправо:
источник
Начиная с Java 11, String.repeat (int) может использоваться для левой / правой панели заданной строки.
Вывод:
источник
Вы можете уменьшить накладные расходы на вызов, сохранив данные заполнения, вместо того, чтобы каждый раз перестраивать их:
В качестве альтернативы вы можете сделать длину результата параметром
pad(...)
метода. В этом случае выполните настройку скрытого заполнения в этом методе, а не в конструкторе.(Подсказка: для дополнительного кредита, сделайте это поточно-ориентированным! ;-)
источник
Нашел это на Dzone
Накладка с нулями:
источник
Вы можете использовать встроенные методы StringBuilder append () и insert () для заполнения переменных строк:
Например:
источник
Это работает:
Это заполнит вашу строку XXX до 9 символов пробелами. После этого все пробелы будут заменены на 0. Вы можете изменить пробелы и 0 на все, что вы хотите ...
источник
static
метод,String.format(…)
вместо того, чтобы злоупотреблять пустой строкой. Сохранение четырех символов в исходном коде, безусловно, не стоит потери читабельности.источник
Позвольте мне оставить ответ для некоторых случаев, когда вам нужно задать левый / правый отступ (или строку префикса / суффикса, или пробелы) перед тем, как объединить другую строку, и вы не хотите проверять длину или любое условие if.
То же самое к выбранному ответу, я бы предпочел
StringUtils
Apache Commons, но используя этот способ:Объясните:
myString
: строка, которую я ввожу, может быть нулевойStringUtils.leftPad(myString, 1)
: если строка равна нулю, этот оператор также будет возвращать нольdefaultString
чтобы дать пустую строку, чтобы предотвратить конкатенацию нольисточник
Ответы @ck и @Marlon Tarak - единственные, которые используют a
char[]
, который является лучшим подходом для приложений, которые имеют несколько вызовов методов заполнения в секунду. Тем не менее, они не пользуются какой-либо оптимизацией манипулирования массивами и немного перезаписаны на мой вкус; это можно сделать без каких-либо петель .Простой метод испытаний:
Выходы:
источник
getChars
чтобы позволитьString
копировать его содержимое непосредственно вout
массив вместо вызоваsource.toCharArray()
, а затемSystem.arraycopy
. Я бы даже подумал упростить реализацию доchar[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);
; в то время как это похоже наfill
выполнение дополнительной работы, на самом деле JVM позволяет исключить заполнение нулями по умолчанию.java.util.Formatter
сделаю левый и правый отступ. Нет необходимости в нечетных сторонних зависимостях (вы хотите добавить их для чего-то такого тривиального).[Я упустил детали и сделал этот пост «вики-сообществом», так как он мне не нужен.]
источник
Все операции со строками обычно должны быть очень эффективными, особенно если вы работаете с большими наборами данных. Я хотел что-то быстрое и гибкое, похожее на то, что вы получите в команде plsql pad. Кроме того, я не хочу включать огромную библиотеку только для одной маленькой вещи. С учетом этих соображений ни одно из этих решений не было удовлетворительным. Это решения, которые я придумал, которые дали лучшие результаты тестирования, если кто-то может улучшить его, пожалуйста, добавьте свой комментарий.
источник
Используйте эту функцию.
как пользоваться?
выход: 01 02 03 04 .. 11 12
источник
У многих людей есть несколько очень интересных техник, но мне нравится быть проще, поэтому я продолжаю:
источник
Простое решение без какого-либо API будет следующим:
источник
Java oneliners, никакой необычной библиотеки.
Pad Left, не ограничивать
Pad Right, не ограничивайте
Pad Left, ограничение по длине площадки
Pad Right, ограничение длины площадки
источник
Как насчет использования рекурсии? Приведенное ниже решение совместимо со всеми версиями JDK и не требует никаких внешних библиотек :)
ПРИМЕЧАНИЕ . Это решение добавит заполнение, с небольшим изменением, которое вы можете добавить к значению дополнения.
источник
Вот параллельная версия для тех из вас, у кого очень длинные строки :-)
источник
Примеры заполнения в Гуаве:
Примеры заполнения в Apache Commons:
Примеры заполнения в JDK:
источник
Простое решение будет:
источник
Как это
Строка "hello" и требуемый отступ равен 15 с "0" left pad
источник