Sobre el tema de la función apache frente al formateador de cadenas hay pocas dudas de que la función apache es más clara y fácil de leer. Ajustar el formateador en nombres de funciones no es ideal.
Pero tenga en cuenta que, como otros han mencionado y demostrado en esta respuesta , String.format()y las Formatterclases en el JDK son mejores opciones. Úselos sobre el código común.
@ Jonik, ¿te gustaría enumerar algunas de tus razones? Las API se ven más o menos igual.
glen3b
3
@ glen3b: Para una utilidad individual, como estos ayudantes de relleno de cadenas, realmente no importa qué lib usar. Dicho esto, la guayaba es en general una biblioteca más moderna, más limpia y mejor documentada que sus contrapartes en varios proyectos de Apache Commons (Commons Lang, Commons Collections, Commons IO, etc.). También está construido por tipos realmente inteligentes (Kevin Bourrillion et al), muchos de los cuales están activos en SO . Yo mismo terminé reemplazando las diversas librerías de Apache Commons con solo Guava hace años, y no me arrepiento.
@ Nullw0rm, si te refieres a rgagnon.com, ten en cuenta que RealHowTo también es el autor de rgagnon.com, por lo que se acreditaría a sí mismo ...
Colin Pickard el
3
al menos en mi JVM, el "#" no funciona, el "-" está bien. (Solo borra el #). Esto puede ser consistente con la documentación del formateador, no sé; dice "'#' '\ u0023' Requiere que la salida use un formulario alternativo. La definición del formulario se especifica mediante la conversión".
gatoatigrado
66
Gracias por la increíble respuesta. Sin embargo, tengo una duda, ¿ 1$para qué sirve ? @leo ha hecho una respuesta muy similar que no usa 1$y aparentemente tiene el mismo efecto. ¿Hace alguna diferencia?
Fabrício Matté
257
Relleno a 10 caracteres:
String.format("%10s","foo").replace(' ','*');String.format("%-10s","bar").replace(' ','*');String.format("%10s","longer than 10 chars").replace(' ','*');
Siempre y cuando todos recordemos no pasar una cadena con espacios ...: D
leviathanbadger
44
Estoy con @ aboveyou00: esta es una solución horrenda para cadenas con espacios, incluido el ejemplo proporcionado por leo. Una solución para rellenar una cadena a la izquierda o la derecha no debería alterar la cadena de entrada como aparece en la salida, a menos que el relleno original de la cadena de entrada haga que exceda la longitud de relleno especificada.
Brian Warshaw
3
Reconocer la cuestión del espacio. .replace(' ', '*')estaba más bien destinado a mostrar el efecto del relleno. La expresión de ocultación de contraseña no tiene este problema de todos modos ... Para obtener una mejor respuesta sobre la personalización de la cadena de relleno izquierda y derecha utilizando la función nativa de Java, consulte mi otra respuesta.
leo
Si la cadena contiene solo espacios individuales y desea rellenar con diferentes caracteres, puede usar regex replace con mirar hacia atrás / adelante: String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")oString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
Presta atención: invertiste nombres de funciones; si lo ejecutas lo verás.
azulado
Además, si la cadena original contiene espacios, entonces esto no funciona
Steven Shaw
@StevenShaw Si no me equivoco, el reemplazo no está dirigido al original str, por lo que esto es correcto.
mafu
3
Por convención, no debe usar una letra mayúscula para los nombres de las funciones.
principal-ideal-domain
¿Hay una condicional faltante en devolver la cadena como es cuando (length - str.length())es 0? El formateador arroja un FormatFlagsConversionMismatchExceptioncuando %0ses la cadena de formato.
Devin Walters
7
Esto me llevó un tiempo darme cuenta. La clave real es leer la documentación de 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);
¿Por qué hacer el final tan complicado? Podrías haber hecho String hex = String.format ("% 032x", digest); y tenía exactamente los mismos resultados, sólo que sin una innecesaria replace () y tener que utilizar el acceso a las variables $ específicos (sólo hay una, después de todo.)
ArtOfWarfare
@ArtOfWarfare punto justo. Originalmente, alguien solicitó valores hexadecimales de relleno en otra pregunta, vi que tenía un enlace a la documentación del formateador. Es complicado por lo completo.
Nthalk
6
Sé que este hilo es un poco viejo y la pregunta original era para una solución fácil, pero si se supone que es realmente rápido, debe usar una matriz de caracteres.
Si StringBufferno se puede acceder a varios subprocesos a la vez (lo que en este caso es cierto), debe usar un StringBuilder(en JDK1.5 +) para evitar la sobrecarga de la sincronización.
glen3b
5
Aquí hay otra forma de desplazarse hacia la derecha:
// 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-------";
Como alternativa, puede hacer que la longitud del resultado sea un parámetro para el pad(...)método. En ese caso, realice el ajuste del relleno oculto en ese método en lugar de hacerlo en el constructor.
(Sugerencia: para obtener crédito adicional, ¡haga que sea seguro para subprocesos! ;-)
Eso es seguro para subprocesos, excepto para publicaciones inseguras (haga que sus campos sean finales, como es natural). Creo que el rendimiento podría mejorarse haciendo una subcadena antes del + que debería reemplazarse por concat (curiosamente).
Llenará su String XXX hasta 9 caracteres con un espacio en blanco. Después de eso, todos los espacios en blanco se reemplazarán con un 0. Puede cambiar el espacio en blanco y el 0 a lo que desee ...
Debe invocar el staticmétodo como en String.format(…)lugar de abusar de una cadena vacía. Guardar cuatro caracteres en el código fuente seguramente no vale la pérdida de legibilidad.
Holger
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"";}
Permítame dejar una respuesta para algunos casos en los que necesita dar relleno izquierdo / derecho (o cadena o espacios de prefijo / sufijo) antes de concatenar a otra cadena y no desea probar la longitud ni ninguna condición.
Al igual que con la respuesta seleccionada, preferiría el StringUtilsde Apache Commons, pero de esta manera:
Las respuestas de @ck y @Marlon Tarak son las únicas que utilizan a char[], lo que es mejor para las aplicaciones que tienen varias llamadas a métodos de relleno por segundo. Sin embargo, no aprovechan las optimizaciones de manipulación de matriz y están un poco sobrescritos para mi gusto; Esto se puede hacer sin bucles .
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));}
Salidas:
012345678901234567890123456789
cats
cats
cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too longfor your own good, buddy
Puede usar getCharspara permitir que la Stringcopia de su contenido directamente en la outmatriz, en lugar de llamar source.toCharArray(), seguido de System.arraycopy. Incluso consideraría simplificar la implementación a 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);; Si bien parece que fillesto haría más trabajo, en realidad permite que la JVM elimine el relleno cero predeterminado.
Holger
1
java.util.Formatterhará relleno izquierdo y derecho. No es necesario contar con dependencias de terceros extrañas (desearía agregarlas para algo tan trivial).
[He omitido los detalles e hice esta publicación 'wiki de la comunidad' ya que no es algo que necesito.]
Estoy en desacuerdo. En cualquier proyecto de Java más grande, normalmente realizarás tanta manipulación de String que vale la pena usar Apache Commons Lang para mejorar la legibilidad y evitar errores. Todos ustedes conocen códigos como someString.subString (someString.indexOf (startCharacter), someString.lastIndexOf (endCharacter)), que se pueden evitar fácilmente con StringUtils.
Bananeweizen
1
Toda operación de cadena generalmente debe ser muy eficiente , especialmente si está trabajando con grandes conjuntos de datos. Quería algo que fuera rápido y flexible, similar a lo que obtendrás en el comando plsql pad. Además, no quiero incluir una gran lib para una pequeña cosa. Con estas consideraciones, ninguna de estas soluciones fue satisfactoria. Estas son las soluciones que se me ocurrieron, que tuvieron los mejores resultados de evaluación comparativa, si alguien puede mejorarlo, agregue su comentario.
tenga en cuenta que se llama con String.toCharArray () y el resultado se puede convertir a String con un nuevo String ((char []) result). La razón de esto es que si aplica varias operaciones, puede hacerlas todas en char [] y no seguir convirtiendo entre formatos: detrás de escena, String se almacena como char []. Si estas operaciones se incluyeran en la clase String, habría sido dos veces más eficiente: velocidad y memoria.
Aquí hay una versión paralela para aquellos de ustedes que tienen cadenas muy largas :-)
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));
Respuestas:
Apache
StringUtils
tiene varios métodos:leftPad
,rightPad
,center
yrepeat
.Pero tenga en cuenta que, como otros han mencionado y demostrado en esta respuesta ,
String.format()
y lasFormatter
clases en el JDK son mejores opciones. Úselos sobre el código común.fuente
Desde Java 1.5,
String.format()
se puede usar para rellenar a la izquierda / derecha una cadena dada.Y la salida es:
fuente
1$
para qué sirve ? @leo ha hecho una respuesta muy similar que no usa1$
y aparentemente tiene el mismo efecto. ¿Hace alguna diferencia?Relleno a 10 caracteres:
salida:
Muestra '*' para los caracteres de la contraseña:
la salida tiene la misma longitud que la cadena de contraseña:
fuente
.replace(' ', '*')
estaba más bien destinado a mostrar el efecto del relleno. La expresión de ocultación de contraseña no tiene este problema de todos modos ... Para obtener una mejor respuesta sobre la personalización de la cadena de relleno izquierda y derecha utilizando la función nativa de Java, consulte mi otra respuesta.String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
oString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
En guayaba , esto es fácil:
fuente
Algo sencillo:
El valor debe ser una cadena. conviértalo a cadena, si no lo es. Me gusta
"" + 123
oInteger.toString(123)
El inicio de la subcadena desde el índice de caracteres de la longitud del valor hasta la longitud final del relleno:
Más preciso
almohadilla derecha:
almohadilla izquierda:
fuente
Echa un vistazo a
org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.Pero el algoritmo es muy simple (pad hasta caracteres de tamaño):
fuente
Además de Apache Commons, también vea
String.format
cuáles deberían ser capaces de encargarse del relleno simple (por ejemplo, con espacios).fuente
fuente
str
, por lo que esto es correcto.(length - str.length())
es0
? El formateador arroja unFormatFlagsConversionMismatchException
cuando%0s
es la cadena de formato.Esto me llevó un tiempo darme cuenta. La clave real es leer la documentación de Formatter.
fuente
Sé que este hilo es un poco viejo y la pregunta original era para una solución fácil, pero si se supone que es realmente rápido, debe usar una matriz de caracteres.
La solución del formateador no es óptima. solo construir la cadena de formato crea 2 nuevas cadenas.
La solución de Apache se puede mejorar inicializando el SB con el tamaño objetivo, reemplazando a continuación
con
evitaría que el búfer interno del SB crezca.
fuente
StringBuffer
no se puede acceder a varios subprocesos a la vez (lo que en este caso es cierto), debe usar unStringBuilder
(en JDK1.5 +) para evitar la sobrecarga de la sincronización.Aquí hay otra forma de desplazarse hacia la derecha:
fuente
Desde Java 11, String.repeat (int) se puede usar para rellenar a la izquierda / derecha una cadena dada.
Salida:
fuente
Puede reducir la sobrecarga por llamada reteniendo los datos de relleno, en lugar de reconstruirlos cada vez:
Como alternativa, puede hacer que la longitud del resultado sea un parámetro para el
pad(...)
método. En ese caso, realice el ajuste del relleno oculto en ese método en lugar de hacerlo en el constructor.(Sugerencia: para obtener crédito adicional, ¡haga que sea seguro para subprocesos! ;-)
fuente
Encontré esto en Dzone
Almohadilla con ceros:
fuente
puede usar los métodos incorporados StringBuilder append () e insert (), para el relleno de longitudes de cadena variables:
Por ejemplo:
fuente
Esto funciona:
Llenará su String XXX hasta 9 caracteres con un espacio en blanco. Después de eso, todos los espacios en blanco se reemplazarán con un 0. Puede cambiar el espacio en blanco y el 0 a lo que desee ...
fuente
static
método como enString.format(…)
lugar de abusar de una cadena vacía. Guardar cuatro caracteres en el código fuente seguramente no vale la pérdida de legibilidad.fuente
Permítame dejar una respuesta para algunos casos en los que necesita dar relleno izquierdo / derecho (o cadena o espacios de prefijo / sufijo) antes de concatenar a otra cadena y no desea probar la longitud ni ninguna condición.
Al igual que con la respuesta seleccionada, preferiría el
StringUtils
de Apache Commons, pero de esta manera:Explique:
myString
: la cadena que ingresé, puede ser nulaStringUtils.leftPad(myString, 1)
: si la cadena es nula, esta declaración también devolverá nulodefaultString
para dar una cadena vacía para evitar concatenar nulofuente
Las respuestas de @ck y @Marlon Tarak son las únicas que utilizan a
char[]
, lo que es mejor para las aplicaciones que tienen varias llamadas a métodos de relleno por segundo. Sin embargo, no aprovechan las optimizaciones de manipulación de matriz y están un poco sobrescritos para mi gusto; Esto se puede hacer sin bucles .Método de prueba simple:
Salidas:
fuente
getChars
para permitir que laString
copia de su contenido directamente en laout
matriz, en lugar de llamarsource.toCharArray()
, seguido deSystem.arraycopy
. Incluso consideraría simplificar la implementación achar[] 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);
; Si bien parece quefill
esto haría más trabajo, en realidad permite que la JVM elimine el relleno cero predeterminado.java.util.Formatter
hará relleno izquierdo y derecho. No es necesario contar con dependencias de terceros extrañas (desearía agregarlas para algo tan trivial).[He omitido los detalles e hice esta publicación 'wiki de la comunidad' ya que no es algo que necesito.]
fuente
Toda operación de cadena generalmente debe ser muy eficiente , especialmente si está trabajando con grandes conjuntos de datos. Quería algo que fuera rápido y flexible, similar a lo que obtendrás en el comando plsql pad. Además, no quiero incluir una gran lib para una pequeña cosa. Con estas consideraciones, ninguna de estas soluciones fue satisfactoria. Estas son las soluciones que se me ocurrieron, que tuvieron los mejores resultados de evaluación comparativa, si alguien puede mejorarlo, agregue su comentario.
fuente
Usa esta función.
¿cómo utilizar?
salida: 01 02 03 04 .. 11 12
fuente
Mucha gente tiene algunas técnicas muy interesantes, pero me gusta que sea simple, así que sigo con esto:
fuente
Una solución simple sin ninguna API será la siguiente:
fuente
Oneliners de Java, no hay una biblioteca elegante.
Pad Left, no limite
Pad Right, no limites
Almohadilla izquierda, límite a la longitud de la almohadilla
Almohadilla derecha, límite a la longitud de la almohadilla
fuente
¿Qué hay de usar la recursividad? La solución dada a continuación es compatible con todas las versiones de JDK y no requiere bibliotecas externas :)
NOTA : Esta solución agregará el relleno, con un pequeño ajuste puede prefijar el valor del pad.
fuente
Aquí hay una versión paralela para aquellos de ustedes que tienen cadenas muy largas :-)
fuente
Ejemplos de relleno en guayaba:
Ejemplos de relleno en Apache Commons:
Ejemplos de relleno en JDK:
fuente
Una solución simple sería:
fuente
Cómo es esto
La cadena es "hola" y el relleno requerido es 15 con el pad izquierdo "0"
fuente