Guía de la clase StringUtils de Apache Commons en Java

En esta guía, repasaremos las funcionalidades importantes de la clase StringUtils de Apache Commons en Java, con tutoriales y ejemplos de todo lo que necesita saber.

Introducción

La biblioteca Apache Commons proporciona muchas nuevas interfaces, implementaciones y clases que amplían el núcleo de Java Framework. Es una de las principales bibliotecas de terceros y está presente en muchos proyectos.

En este artículo, hemos compilado una Guía para la clase StringUtils de Apache Commons, que proporciona algunas utilidades y herramientas muy buenas para trabajar con cadenas, ampliando la funcionalidad de la clase principal - java.lang.String .

StringUtils es probablemente la clase más utilizada de Apache Commons, y contiene varios métodos de utilidad y conveniencia que permiten a los desarrolladores evitar escribir código repetitivo o simplemente engorroso para operaciones básicas.

¿Por qué usar StringUtils en lugar de métodos de cadena? {#por qué usar herramientas de cadena en lugar de métodos de cadena}

Muchos de los métodos en la clase StringUtils tienen sus equivalentes en java.lang.String, pero los que se encuentran en StringUtils son seguros contra nulos. Esto significa que NullPointerExceptions no se lanzan en los casos en los que no se espera que lo hagan.

Como se mencionó anteriormente, Apache Commons contiene varios métodos y cubriremos algunos de los más utilizados:

Primeros pasos con Apache Commons

Para poder usar la biblioteca de Apache Commons, primero debemos importarla a nuestro proyecto.

Si estás usando Maven, importa la última dependencia a tu archivo pom.xml:

1
2
3
4
5
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>

Alternativamente, si estás usando Gradle:

1
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'

Con la dependencia commons-lang3 en nuestro proyecto, podemos pasar a discutir algunos de los métodos más utilizados de StringUtils. ¡Empecemos!

Comparación de cadenas con Apache Commons

Comparar cadenas, verificar si están vacías o en blanco, o simplemente verificar si son iguales son operaciones bastante comunes.

Comencemos con algunos métodos relacionados con la comparación.

StringUtils.isEmpty() y StringUtils.isBlank()

Estos dos métodos se explican por sí mismos: ambos se usan para verificar si una Cadena contiene algún texto. Ambos devuelven ‘verdadero’ si la ‘Cadena’ está realmente vacía. Además, isBlank() también devolverá true si una String contiene solo espacios en blanco.

También tienen sus métodos inversos: isNotEmpty() y isNotBlank().

Veamos cómo podemos usar isEmpty() junto con su equivalente java.lang.String.isEmpty(), así como isBlank():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
String nullString = null;
String emptyString = "";
String blankString = "\n \t   \n";

if(!nullString.isEmpty()) {
    System.out.println("nullString isn't null");
}

if(StringUtils.isEmpty(emptyString)) {
    System.out.println("emptyString is empty");
}

if(StringUtils.isBlank(blankString)) {
    System.out.println("blankString is blank");
}

Tenemos tres cadenas aquí. Uno apunta a null, el segundo no es nulo, pero no tiene ningún contenido (está vacío), y el tercero no está vacío, pero producirá un *vacío * resultado si está impreso.

Ejecutar este código da como resultado:

1
Exception in thread "main" java.lang.NullPointerException

El método isEmpty() que está integrado en java.lang.String no es seguro frente a valores nulos. Lanzará una NullPointerException si intenta verificar si está vacío, ya que está llamando a un método en una referencia null. Deberá verificar si la referencia es nula de antemano:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
String nullString = null;
String emptyString = "";
String blankString = "\n \t   \n";

if(nullString != null && !nullString.isEmpty()) {
    System.out.println("nullString isn't null");
}

if(StringUtils.isEmpty(emptyString)) {
    System.out.println("emptyString is empty");
}

if(StringUtils.isBlank(blankString)) {
    System.out.println("blankString is blank");
}

Ahora, esto resulta en:

1
2
emptyString is empty
blankString is blank

Y si probamos estos métodos en nullString:

1
2
3
4
5
6
7
if(StringUtils.isEmpty(nullString)) {
    System.out.println("emptyString is empty");
}

if(StringUtils.isBlank(nullString)) {
    System.out.println("blankString is blank");
}

Esto resulta en:

1
2
emptyString is empty
blankString is blank

Los métodos StringUtils son a prueba de nulos y producen el resultado que esperaría que estos métodos devolvieran al encontrar una referencia null.

StringUtils.equals()

Este hace exactamente lo que crees que hace: compara dos cadenas y devuelve verdadero, si son idénticos o si ambas referencias apuntan a nulo, pero ten en cuenta que este método es sensible a mayúsculas y minúsculas .

Veamos cómo funciona este método:

1
2
3
4
5
System.out.println(StringUtils.equals(null, null));
System.out.println(StringUtils.equals(null, "some string"));
System.out.println(StringUtils.equals("some string", null));
System.out.println(StringUtils.equals("some string", "some string"));
System.out.println(StringUtils.equals("some other string", "some string"));

Esto generará:

1
2
3
4
5
true
false
false
true
false

En aras de comparar el método equals() de StringUtils con java.lang.String.equals(), vamos a probarlos:

1
2
3
4
5
6
7
String nullString = null;

System.out.println(StringUtils.equals(nullString, null));
System.out.println(StringUtils.equals(nullString, "string"));

System.out.println(nullString.equals(null));
System.out.println(nullString.equals("string"));

Esto resulta en:

1
2
3
true
false
Exception in thread "main" java.lang.NullPointerException

Nuevamente, invocar un método en una referencia null da como resultado una NullPointerException, tendríamos que verificar si la variable de referencia es null antes de usarla.

StringUtils.compare()

La declaración de este método es la siguiente:

1
public static int compare(CharSequence str1, CharSequence str2)

Este método compara lexicográficamente dos Strings, de la misma manera que lo hace java.lang.String.compareTo(), devolviendo:

  • 0 si str1 es igual a str2 (o ambos son nulos)
  • Un valor menor que 0 si str1 es menor que str2
  • Un valor mayor que 0 si str1 es mayor que str2

En este artículo no discutiremos lo que exactamente significa comparar lexicográficamente dos Strings, así que si está interesado en leer más sobre eso, consulte [este](https://docs.oracle. com/javase/7/docs/api/java/lang/String.html#compareTo(java.lang.String)).

Ahora, veamos cómo podemos usarlo en nuestro programa:

1
2
3
4
5
System.out.println(StringUtils.compare(null, null));
System.out.println(StringUtils.compare(null , "a"));
System.out.println(StringUtils.compare("a", null));
System.out.println(StringUtils.compare("a", "A"));
System.out.println(StringUtils.compare("a", "a"));

Esto a su vez producirá:

1
2
3
4
5
0
-1
1
32
0

Nota: un valor nulo se considera menor que un valor no nulo. Dos valores nulos se consideran iguales.

Indexación de secuencias de búsqueda con Apache Commons

Ahora, echemos un vistazo a un grupo de métodos que se ocupan de las comprobaciones de índice, por supuesto, de una manera segura contra nulos. Todos estos métodos tienen múltiples variantes sobrecargadas, pero las más generales son:

1
2
3
public static int indexOf(CharSequence seq, CharSequence searchSeq)
public static int lastIndexOf(CharSequence seq, CharSequence searchSeq)
public static boolean contains(CharSequence seq, CharSequence searchSeq)

Hay una cosa que todos tienen en común: todos usan sus variantes seguras no null de java.lang.String si es posible hacerlo. Vamos a explicar esto con un poco más de detalle.

StringUtils.indexOf()

Este método, al igual que el integrado, buscará el índice de la primera aparición de una secuencia dentro de otra secuencia. Si el método incorporado java.lang.String.indexOf() no produce una NullPointerException, se usará. Si no, la implementación de Apache Commons se hace cargo.

El valor de retorno es el primer índice encontrado, o -1 si no hay ninguna coincidencia o la cadena de entrada es nula.

Vamos a escribir algo de código ahora:

1
2
3
4
5
6
String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.indexOf(null, "a"));
System.out.println(StringUtils.indexOf(s, "general"));
System.out.println(StringUtils.indexOf(s, "l"));
System.out.println(StringUtils.indexOf(s, "lan"));

Ejecutar el código anterior dará como resultado el siguiente resultado:

1
2
3
4
-1
10
16
38

StringUtils.lastIndexOf()

El método lastIndexOf() funciona de la misma manera que indexOf(), pero devuelve la última ocurrencia, no la primera de la secuencia de búsqueda.

Ejecutemos el mismo código de antes:

1
2
3
4
5
6
String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.lastIndexOf(null, "a"));
System.out.println(StringUtils.lastIndexOf(s, "general"));
System.out.println(StringUtils.lastIndexOf(s, "l"));
System.out.println(StringUtils.lastIndexOf(s, "lan"));

Ejecutar el código anterior dará como resultado el siguiente resultado:

1
2
3
4
-1
10
38
38

Comprobar si la cadena contiene otra cadena con Apache Commons

StringUtils.contains()

El método contains() devuelve verdadero o falso en función de si una secuencia de búsqueda está contenida dentro de otra secuencia o no.

Si tiene éxito, este método también usa java.lang.String.indexOf(String). En el caso de null como entrada, se devuelve false:

1
2
3
4
5
6
String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.contains(null, "a"));
System.out.println(StringUtils.contains(s, "Java"));
System.out.println(StringUtils.contains(s, "Python"));
System.out.println(StringUtils.contains(s, "pRoGrAmMinG"));

El método, por supuesto, si distingue entre mayúsculas y minúsculas, por lo que la última llamada también devolverá falso:

1
2
3
4
false
true
false
false

StringUtils.containsIgnoreCase()

El método containsIgnoreCase() funciona de la misma manera que el método contains(), pero no distingue entre mayúsculas y minúsculas:

1
2
3
4
5
6
String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.containsIgnoreCase(null, "a"));
System.out.println(StringUtils.containsIgnoreCase(s, "Java"));
System.out.println(StringUtils.containsIgnoreCase(s, "Python"));
System.out.println(StringUtils.containsIgnoreCase(s, "pRoGrAmMinG"));

Esto resulta en:

1
2
3
4
false
true
false
true

StringUtils.containsAny()

La comprobación del método containsAny() acepta un vararg, además de la cadena en la que estamos buscando. Devuelve true si la secuencia buscada contiene cualquier elemento del vararg:

1
2
3
String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.containsAny(s, "general", "python", "something", "javascript"));

Esto resulta en:

1
true

Este método también distingue entre mayúsculas y minúsculas, así que asegúrese de tenerlo en cuenta.

StringUtils.containsNone()

En lugar de crear casos extremos con el método anterior, simplemente puede usar containsNone() si quiere asegurarse de que una cadena no contenga ninguno de los elementos que puso como vararg:

1
2
3
String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.containsNone(s, "general", "python", "something", "javascript"));

Esto resulta en:

1
false

StringUtils.containsOnly()

O, si desea verificar si una cadena contiene solo los contenidos que predefinió, puede usar el método containsOnly():

1
2
3
String s = "Java";

System.out.println(StringUtils.containsOnly(s, "Java"));

Esto resulta en:

1
true

Métodos de subcadena de Apache Commons

StringUtils.subcadena()

Entre muchas de las variantes sobrecargadas disponibles de este método, discutiremos dos de ellas:

  1. subcadena(String str, int start)
  2. subcadena(String str, int start, int end)

Este método devuelve una subcadena que comienza en start y va hasta el final de String o el índice end.

También podemos usar un número negativo para el parámetro start, que nos dará una subcadena que comienza con n caracteres desde el final de String.

Si hay una entrada null, el valor devuelto será simplemente null.

Veamos cómo podemos usarlo:

1
2
3
System.out.println(StringUtils.substring("a random string", 4, 8));
System.out.println(StringUtils.substring("a random string", -7));
System.out.println(StringUtils.substring(null, 5));

Ejecutar el código anterior nos da:

1
2
3
ndom
 string
null

StringUtils.split()

Provisto de una ‘Cadena’ y un carácter separador, este método dividirá la ‘Cadena’ y la colocará en una matriz.

Los elementos de la matriz resultante son subcadenas que están delimitadas por separadores en la ‘Cadena’ original. El separador no está incluido en la matriz final después de la división.

Al igual que con los otros métodos en StringUtils, devuelve null si la entrada es null.

Veamos un poco de código y cómo funciona este método:

1
2
3
4
5
String csvString = "Id, Name, Age, Location";
        
System.out.println(Arrays.toString(StringUtils.split(csvString, ',')));
System.out.println(Arrays.toString(StringUtils.split(null, '.')));
System.out.println(Arrays.toString(StringUtils.split("", '.')));

Después de ejecutar el código, obtenemos:

1
2
3
[Id,  Name,  Age,  Location]
null
[]

StringUtils.join()

Este método representa el opuesto directo del método split().

Después de dividir un String con un carácter separador, podemos unirlo fácilmente con el método join(), proporcionando una lista o una matriz de elementos. Devuelve un String creado pegando los elementos provistos usando el separador. Si la entrada es null, el método devuelve null.

Veamos este ejemplo básico:

1
2
3
4
String csvString = "Id, Name, Age, Location";
        
String[] myStr =  StringUtils.split(csvString, ',');
System.out.println(StringUtils.join(myStr, ';'));

Ejecutar el código anterior nos da:

1
Id; Name; Age; Location

StringUtils.remove()

Hay dos variantes de este método que queremos ver:

1
2
public static String remove(String str, char remove)
public static String remove(String str, String remove)

Ambos hacen lo mismo, con la excepción de que el segundo elimina todas las apariciones de una subcadena, mientras que el primero elimina todas las apariciones de un carácter de la Cadena dada.

Si la entrada es null, el método devuelve null.

Para este, dividiremos los ejemplos en dos bloques de código separados, porque puede ser un poco difícil diferenciarlos a primera vista. Empecemos con remove(String str, char remove):

1
2
3
4
5
6
7
8
System.out.println(StringUtils.remove(null, 'a'));
System.out.println(StringUtils.remove("", 'a'));
System.out.println(StringUtils.remove("queued", 'u'));

System.out.println(StringUtils.remove(null, "abc"));
System.out.println(StringUtils.remove("", "abc"));
System.out.println(StringUtils.remove("abc", null));
System.out.println(StringUtils.remove("queued", "ue"));

Ejecutemos esto y veamos qué produce:

1
2
3
4
5
6
7
null // Returned null
     // Removed 'a' from ""
qeed // Removed 'u' characters
null // Returned null
     // Removed "abc" from ""
abc  // Removed null from "abc"
qd   // Removed "ue" from "queued"

Debemos tener en cuenta una cosa aquí, ya que puede pasarse por alto fácilmente: cuando el parámetro remove tiene un valor null, se devuelve la cadena de origen.

StringUtils.reemplazar()

Como la mayoría de los métodos que hemos cubierto, este también se explica por sí mismo: busca una ‘Cadena’ dentro de una ‘Cadena’, la encuentra si existe y reemplaza todas sus ocurrencias con una nueva Cadena.

La declaración de este método es la siguiente:

1
public static String replace(String text, String searchString, String replacement)

Si searchString no se encuentra dentro de text, no pasa nada y nuestro texto permanece igual. Siguiendo la misma lógica, si text es null, este método devuelve null.

Si searchString o replacement tienen el valor null, el método devuelve su fuente, que es texto.

Probemos este método:

1
2
String string = "a simple sentence";
System.out.println(StringUtils.replace(string, "simple", "complicated"));

Esto dará como resultado:

1
a complicated sentence

StringUtils.countMatches()

countMatches() cuenta cuántas veces aparece un carácter específico (o una subcadena) dentro de la Cadena dada. Una entrada null o vacía devuelve 0.

Veamos cómo funciona esto en el código:

1
2
3
4
5
6
7
String string = "I'm blue Da ba dee da ba di, Da ba dee da ba di";

System.out.println(StringUtils.countMatches(null, 'd'));
System.out.println(StringUtils.countMatches(string, 'd'));

System.out.println(StringUtils.countMatches(null, "da"));
System.out.println(StringUtils.countMatches(string, "da"));

Ejecutar el código anterior nos da:

1
2
3
4
0
6
0
2

Conclusión

En este artículo hemos cubierto algunos de los métodos más utilizados y conocidos dentro de la clase Apache Commons' StringUtils.

Los métodos que se encuentran en la clase StringUtils son a prueba de nulos y proporcionan funciones básicas y ampliadas a los métodos String incorporados.