Есть ли простой способ дополнить строки в Java?
Похоже на то, что должно быть в каком-то StringUtil-подобном API, но я не могу найти ничего, что делает это.
Есть ли простой способ дополнить строки в Java?
Похоже на то, что должно быть в каком-то StringUtil-подобном API, но я не могу найти ничего, что делает это.
Apache _1 _ имеет несколько методов: _ 2_, _ 3_, _ 4_ и repeat
.
Но обратите внимание, что - как другие уже упоминали и демонстрировали в этом ответе - String.format()
и Formatter
классы в JDK являются лучшими вариантами . Используйте их поверх общего кода.
Начиная с Java 1.5, _ 1_ можно использовать для заполнения заданной строки влево / вправо.
public static String padRight(String s, int n) {
return String.format("%-" + n + "s", s);
}
public static String padLeft(String s, int n) {
return String.format("%" + n + "s", s);
}
...
public static void main(String args[]) throws Exception {
System.out.println(padRight("Howto", 20) + "*");
System.out.println(padLeft("Howto", 20) + "*");
}
И вывод:
Howto *
Howto*
1$
? @leo дал очень похожий ответ, который не использует 1$
и, по-видимому, имеет тот же эффект. Есть ли разница?
- person Fabrício Matté; 08.03.2013
:P
Я полагаю, что даже в этом случае он практически бесполезен.
- person Fabrício Matté; 08.03.2013
n
должен быть больше 0
.
- person Ky Leggiero; 21.09.2015
Заполнение до 10 символов:
String.format("%10s", "foo").replace(' ', '*');
String.format("%-10s", "bar").replace(' ', '*');
String.format("%10s", "longer than 10 chars").replace(' ', '*');
выход:
*******foo
bar*******
longer*than*10*chars
Отображайте '*' для символов пароля:
String password = "secret123";
String padded = String.format("%"+password.length()+"s", "").replace(' ', '*');
вывод имеет ту же длину, что и строка пароля:
secret123
*********
.replace(' ', '*')
был скорее предназначен для демонстрации эффекта заполнения. Выражение, скрывающее пароль, в любом случае не имеет этой проблемы ... Чтобы получить лучший ответ о настройке левой и правой строки заполнения с использованием встроенной функции Java, см. Мой другой ответ.
- person leo; 01.09.2017
String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
или String.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
- person Jaroslaw Pawlak; 26.06.2018
В Guava это просто:
Strings.padStart("string", 10, ' ');
Strings.padEnd("string", 10, ' ');
Что-нибудь простое:
Значение должно быть строкой. преобразуйте его в строку, если это не так. Как "" + 123
или Integer.toString(123)
// let's assume value holds the String we want to pad
String value = "123";
Подстрока начинается с индекса длины значения char до конечной длины дополненной строки:
String padded="00000000".substring(value.length()) + value;
// now padded is "00000123"
Точнее
площадка справа:
String padded = value + ("ABCDEFGH".substring(value.length()));
// now padded is "123DEFGH"
панель слева:
String padString = "ABCDEFGH";
String padded = (padString.substring(0, padString.length() - value.length())) + value;
// now padded is "ABCDE123"
Взгляните на org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.
Но алгоритм очень прост (заполните до символов размера):
public String pad(String str, int size, char padChar)
{
StringBuilder padded = new StringBuilder(str);
while (padded.length() < size)
{
padded.append(padChar);
}
return padded.toString();
}
Помимо Apache Commons, также см. String.format
, который должен иметь возможность позаботиться о простом заполнении (например, с пробелами).
Начиная с Java 11, String.repeat (int) может использоваться для заполнения заданной строки влево / вправо.
System.out.println("*".repeat(5)+"apple");
System.out.println("apple"+"*".repeat(5));
Выход:
*****apple
apple*****
Я знаю, что этот поток довольно старый, и исходный вопрос был для простого решения, но если он должен быть очень быстрым, вы должны использовать массив символов.
public static String pad(String str, int size, char padChar)
{
if (str.length() < size)
{
char[] temp = new char[size];
int i = 0;
while (i < str.length())
{
temp[i] = str.charAt(i);
i++;
}
while (i < size)
{
temp[i] = padChar;
i++;
}
str = new String(temp);
}
return str;
}
решение форматтера не оптимально. просто построение строки формата создает 2 новые строки.
Решение apache можно улучшить, инициализировав sb с целевым размером, заменив ниже
StringBuffer padded = new StringBuffer(str);
с участием
StringBuffer padded = new StringBuffer(pad);
padded.append(value);
предотвратит рост внутреннего буфера sb.
StringBuffer
не могут получить доступ сразу несколько потоков (что в данном случае верно), вы должны использовать StringBuilder
(в JDK1.5 +), чтобы избежать накладных расходов на синхронизацию.
- person glen3b; 21.05.2014
Мне потребовалось некоторое время, чтобы понять. Настоящий ключ - прочитать эту документацию Formatter.
// Get your data from wherever.
final byte[] data = getData();
// Get the digest engine.
final MessageDigest md5= MessageDigest.getInstance("MD5");
// Send your data through it.
md5.update(data);
// Parse the data as a positive BigInteger.
final BigInteger digest = new BigInteger(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);
Вот еще один способ сдвинуть вправо:
// put the number of spaces, or any character you like, in your paddedString
String paddedString = "--------------------";
String myStringToBePadded = "I like donuts";
myStringToBePadded = myStringToBePadded + paddedString.substring(myStringToBePadded.length());
//result:
myStringToBePadded = "I like donuts-------";
Нашел это на Dzone
Pad с нулями:
String.format("|%020d|", 93); // prints: |00000000000000000093|
Вы можете уменьшить накладные расходы на вызовы, сохранив данные заполнения, а не перестраивая их каждый раз:
public class RightPadder {
private int length;
private String padding;
public RightPadder(int length, String pad) {
this.length = length;
StringBuilder sb = new StringBuilder(pad);
while (sb.length() < length) {
sb.append(sb);
}
padding = sb.toString();
}
public String pad(String s) {
return (s.length() < length ? s + padding : s).substring(0, length);
}
}
В качестве альтернативы вы можете сделать длину результата параметром метода pad(...)
. В этом случае настройте скрытые отступы в этом методе, а не в конструкторе.
(Подсказка: для дополнительного удобства сделайте его потокобезопасным! ;-)
вы можете использовать встроенные методы StringBuilder append () и insert () для заполнения строк переменной длины:
AbstractStringBuilder append(CharSequence s, int start, int end) ;
Например:
private static final String MAX_STRING = " "; //20 spaces
Set<StringBuilder> set= new HashSet<StringBuilder>();
set.add(new StringBuilder("12345678"));
set.add(new StringBuilder("123456789"));
set.add(new StringBuilder("1234567811"));
set.add(new StringBuilder("12345678123"));
set.add(new StringBuilder("1234567812234"));
set.add(new StringBuilder("1234567812222"));
set.add(new StringBuilder("12345678122334"));
for(StringBuilder padMe: set)
padMe.append(MAX_STRING, padMe.length(), MAX_STRING.length());
Это работает:
"".format("%1$-" + 9 + "s", "XXX").replaceAll(" ", "0")
Он заполнит вашу строку XXX до 9 символов пробелом. После этого все пробелы будут заменены на 0. Вы можете изменить пробелы и 0 на все, что захотите ...
static
как String.format(…)
вместо того, чтобы злоупотреблять пустой строкой. Сохранение четырех символов в исходном коде, безусловно, не стоит потери читабельности.
- person Holger; 01.04.2019
Позвольте мне оставить ответ для некоторых случаев, когда вам нужно указать левое / правое заполнение (или строку префикса / суффикса или пробелы) перед объединением с другой строкой, и вы не хотите проверять длину или какое-либо условие if.
Как и в случае с выбранным ответом, я бы предпочел StringUtils
из Apache Commons, но используя этот способ:
StringUtils.defaultString(StringUtils.leftPad(myString, 1))
Объяснять:
myString
: строка, которую я ввожу, может быть нулевойStringUtils.leftPad(myString, 1)
: если строка имеет значение null, этот оператор также вернет nulldefaultString
, чтобы дать пустую строку, чтобы предотвратить конкатенацию null@ck и @ Ответы Марлона Тарака - единственные, в которых используется char[]
, что для приложений, которые имеют несколько вызовов методов заполнения в секунду, является лучшим подходом. Однако они не используют никаких оптимизаций для манипуляций с массивами и немного перезаписаны на мой вкус; это можно сделать без циклов вообще.
public static String pad(String source, char fill, int length, boolean right){
if(source.length() > length) return source;
char[] out = new char[length];
if(right){
System.arraycopy(source.toCharArray(), 0, out, 0, source.length());
Arrays.fill(out, source.length(), length, fill);
}else{
int sourceOffset = length - source.length();
System.arraycopy(source.toCharArray(), 0, out, sourceOffset, source.length());
Arrays.fill(out, 0, sourceOffset, fill);
}
return new String(out);
}
Простой метод проверки:
public static void 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 long for your own good, buddy
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 исключить заполнение нулями по умолчанию.
- person Holger; 01.04.2019
java.util.Formatter
будет делать отступы слева и справа. Нет необходимости в странных сторонних зависимостях (не хотите ли вы добавить их для чего-то столь тривиального).
[Я опустил детали и сделал этот пост «вики-сообществом», так как это не то, в чем я нуждаюсь.]
Все строковые операции обычно должны быть очень эффективными, особенно если вы работаете с большими наборами данных. Я хотел что-то быстрое и гибкое, подобное тому, что вы получите в команде plsql pad. Кроме того, я не хочу включать огромную библиотеку только для одной мелочи. С учетом этих соображений ни одно из этих решений не было удовлетворительным. Это решения, которые я придумал, у которых были лучшие результаты тестирования, если кто-то может их улучшить, пожалуйста, добавьте свой комментарий.
public static char[] lpad(char[] pStringChar, int pTotalLength, char pPad) {
if (pStringChar.length < pTotalLength) {
char[] retChar = new char[pTotalLength];
int padIdx = pTotalLength - pStringChar.length;
Arrays.fill(retChar, 0, padIdx, pPad);
System.arraycopy(pStringChar, 0, retChar, padIdx, pStringChar.length);
return retChar;
} else {
return pStringChar;
}
}
Воспользуйтесь этой функцией.
private String leftPadding(String word, int length, char ch) {
return (length > word.length()) ? leftPadding(ch + word, length, ch) : word;
}
как использовать?
leftPadding(month, 2, '0');
вывод: 01 02 03 04 .. 11 12
У многих людей есть очень интересные техники, но я предпочитаю, чтобы они были простыми, поэтому я придерживаюсь следующего:
public static String padRight(String s, int n, char padding){
StringBuilder builder = new StringBuilder(s.length() + n);
builder.append(s);
for(int i = 0; i < n; i++){
builder.append(padding);
}
return builder.toString();
}
public static String padLeft(String s, int n, char padding) {
StringBuilder builder = new StringBuilder(s.length() + n);
for(int i = 0; i < n; i++){
builder.append(Character.toString(padding));
}
return builder.append(s).toString();
}
public static String pad(String s, int n, char padding){
StringBuilder pad = new StringBuilder(s.length() + n * 2);
StringBuilder value = new StringBuilder(n);
for(int i = 0; i < n; i++){
pad.append(padding);
}
return value.append(pad).append(s).append(pad).toString();
}
Этот служебный класс полезен для левой панели и нулевого заполнения строк. Надеюсь, это кому-то поможет!
package your.package.name;
/**
* Utility class for left pad and zero fill of Strings.
*
*/
public class LeftPad {
public static String lpad(String string, int length, char fill) {
return new String(lpad(string.toCharArray(), length, fill));
}
public static String zerofill(String string, int length) {
return new String(zerofill(string.toCharArray(), length));
}
private static char[] lpad(char[] chars, int length, char fill) {
int delta = 0;
int limit = 0;
if (length > chars.length) {
delta = length - chars.length;
limit = length;
} else {
delta = 0;
limit = chars.length;
}
char[] output = new char[chars.length + delta];
for (int i = 0; i < limit; i++) {
if (i < delta) {
output[i] = fill;
} else {
output[i] = chars[i - delta];
}
}
return output;
}
private static char[] zerofill(char[] chars, int length) {
return lpad(chars, length, '0');
}
/**
* For tests!
*/
public static void main(String[] args) {
String string = "123";
char pad = ' ';
System.out.println("left pad blank: " + string);
System.out.println("Result: [" + LeftPad.lpad(string, 10, pad) + "]");
System.out.println();
System.out.println("zero fill: " + string);
System.out.println("Result: [" + LeftPad.zerofill(string, 10) + "]");
}
}
Это результат:
left pad blank: 123
Result: [ 123]
zero fill: 123
Result: [0000000123]
Простое решение без какого-либо API будет следующим:
public String pad(String num, int len){
if(len-num.length() <=0) return num;
StringBuffer sb = new StringBuffer();
for(i=0; i<(len-num.length()); i++){
sb.append("0");
}
sb.append(num);
return sb.toString();
}
Конструкторы Java, никакой необычной библиотеки.
// 6 characters padding example
String pad = "******";
// testcases for 0, 4, 8 characters
String input = "" | "abcd" | "abcdefgh"
Pad Left, не ограничивайте
result = pad.substring(Math.min(input.length(),pad.length())) + input;
results: "******" | "**abcd" | "abcdefgh"
Pad Right, не ограничивайте
result = input + pad.substring(Math.min(input.length(),pad.length()));
results: "******" | "abcd**" | "abcdefgh"
Пэд слева, ограничение по длине пэда
result = (pad + input).substring(input.length(), input.length() + pad.length());
results: "******" | "**abcd" | "cdefgh"
Пэд вправо, ограничение по длине пэда
result = (input + pad).substring(0, pad.length());
results: "******" | "abcd**" | "abcdef"
Как насчет рекурсии? Приведенное ниже решение совместимо со всеми версиями JDK и не требует внешних библиотек :)
private static String addPadding(final String str, final int desiredLength, final String padBy) {
String result = str;
if (str.length() >= desiredLength) {
return result;
} else {
result += padBy;
return addPadding(result, desiredLength, padBy);
}
}
ПРИМЕЧАНИЕ. Это решение добавит заполнение, с небольшой настройкой вы можете добавить префикс значения заполнения.
Вот параллельная версия для тех из вас, у кого очень длинные строки :-)
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));
Простое решение:
package nl;
public class Padder {
public static void main(String[] args) {
String s = "123" ;
System.out.println("#"+(" " + s).substring(s.length())+"#");
}
}
Как это
Строка - "привет", а обязательное заполнение - 15 с левым отступом "0".
String ax="Hello";
while(ax.length() < 15) ax="0"+ax;
str
, так что это правильно.
- person mafu; 23.06.2014
(length - str.length())
было 0
? Средство форматирования выдает FormatFlagsConversionMismatchException
, когда %0s
является строкой формата.
- person Devin Walters; 08.06.2018