En este artículo, le ayudaremos a entender las subcadenas en Java. No sólo le daremos una explicación teórica, sino que también le daremos ejemplos de código reales para ayudarle a visualizarlos. Le enseñaremos a crear subcadenas y le ayudaremos a encontrar subcadenas dentro de una cadena.

Pero antes de aprenderlos, debemos conocer los conceptos básicos de las subcadenas.

¿Qué son las cadenas y las subcadenas?

En el contexto de Java, una cadena representa una secuencia de caracteres. Toda cadena en Java es un objeto. Una cadena en Java puede contener caracteres, símbolos e incluso espacios en blanco. Por otro lado, una subcadena en Java es una porción o un subconjunto de una cadena Java.

substring-in-java

Por ejemplo, «Geek» es una subcadena de «GeekFlare». Las subcadenas le ayudan a obtener una parte específica de una cadena.

Si tiene el nombre «John Doe» y sólo quiere el nombre de pila «John», puede obtenerlo fácilmente con las subcadenas. Además, si tiene una lista de nombres «John, Jack, Jolly» y quiere averiguar si «John» está en ella, también puede hacerlo con subcadenas. Estos son sólo meros ejemplos. Podemos utilizar las subcadenas en diversas operaciones una vez que las comprendamos.

Como ya conocemos el concepto de subcadenas en Java, ahora, vamos a conocer cómo crear y trabajar con subcadenas en Java.

Extracción de una subcadena

#1. Utilizando el método ‘substring()

El método ‘substring()’ nos permite crear subcadenas muy fácilmente. Toma hasta dos parámetros como entrada – startIndex o ambos startIndex y endIndex y nos devuelve la subcadena que queramos.

Dependiendo del número de parámetros, podemos utilizarlo de dos formas. Vamos a conocerlas en detalle.

substring(int inicioIndice)

Para empezar, podemos utilizar el método en la forma ‘substring(startIndex)’. Aquí, este método toma un valor entero como entrada, donde la entrada es la posición inicial de la subcadena. Devuelve una cadena que comienza en el índice de inicio proporcionado hasta el final de la cadena original.

Como ejemplo, veamos el siguiente código:

public class Subcadenas{    
    public static void main(String args[]){    
    String str="GeekFlare";    
    System.out.println("Cadena dada: " str);  
    System.out.println("Subcadena: " str.substring(4)); //el índice de las cadenas empieza por 0
    }  
   }

SALIDA:

Cadena dada: GeekFlare
Subcadena: Flare

A partir de la salida, vemos que la cadena de entrada es «GeekFlare», y el valor de retorno es la subcadena «Flare». Hace una subcadena a partir del índice dado (4), es decir, desde la posición 5 hasta el final de la cadena.

substring(int inicioÍndice, int finÍndice)

Esta es otra forma de utilizar el método substring de la clase String. Podemos pasar dos enteros al método substring. Un índice inicial y un índice final. Para utilizar esto, tenemos que usar el método en el formato ‘substring(startIndex,endIndex)’.

Para entenderlo mejor, veamos un código de ejemplo:

public class Subcadenas{    
    public static void main(String args[]){    
    String str="GeekFlareFans";    
    System.out.println("Cadena dada: " str);  
    System.out.println("Subcadena: " str.substring(4,9)); //Obtiene una subcadena que comienza en el índice nº 4 hasta el índice 8.

    }  
   }

SALIDA:

Cadena dada: GeekFlareFans
Subcadena: Bengala

Como podemos ver, dada la cadena «GeekFlareFans», da como salida la subcadena «Flare». Le hemos dado el índice inicial de 4 y el índice final de 9. Empieza por el elemento con índice 4 y termina antes del 9. Debemos observar que no imprime el elemento con el índice final. Nos da una subcadena que incluye todos los elementos hasta el índice final pero excluye el elemento con el índice final.

#2. Utilizando el método ‘split()

El método ‘split()’ es otro método de la clase String en Java que nos ayuda a crear una subcadena. Es útil cuando se almacenan varias piezas de información dentro de una cadena con un carácter separador común.

La sintaxis menciona el término «regex» que puede parecerle un poco intimidante, así que entendamos qué es regex antes de continuar. Regex es la abreviatura de «Expresiones Regulares». Una regex es una secuencia de caracteres que describe un patrón dentro de una cadena o texto. En el contexto del método split, la regex es nuestro separador.

El método ‘split()’ puede tomar hasta dos variables como entrada, son una cadena regex y un entero límite. El regex es el separador, que, cuando se encuentra, resulta en la división de la cadena original en 2 partes – la parte antes del regex y la parte después del regex.

Por ejemplo, supongamos que intenta dividir la cadena «abcdef» con «bcd» como regex. Obtendríamos las subcadenas «a» y «ef» como resultado.

El método devuelve un array con las cadenas separadas. Podemos especificar sólo el regex o tanto el regex como el límite. Conozcamos una a una las múltiples formas de llamar a este método.

split(Cadena regex)

El primer método recibe sólo la cadena regex en el formato ‘split(regex)’. No tiene variable límite, por lo que devuelve todas las subcadenas separadas en un array.

Entendámoslo claramente con un poco de código:

public class Subcadenas{    
    public static void main(String args[]){    
    String str="Geek%Flare";
    String[] substrings=str.split("%");
    System.out.println("Cadena dada: " str);
    System.out.println("Primera subcadena: " substrings[0]);
    System.out.println("Segunda subcadena: " subcadenas[1]);
     
    }  
}

SALIDA:

Cadena dada: Geek%Flare
Primera subcadena: Geek
Segunda subcadena: Flare

Como observamos en el código, la cadena dada tiene un separador regex «%». No tiene por qué ser un único carácter, puede ser cualquier cadena con cualquier número de caracteres. El método ‘split()’ ignora este regex y nos da todas las cadenas que estaban separadas por este regex. Las subcadenas se almacenan dentro de una matriz.

En el código, la cadena dada es «Geek%Flare». Así, obtenemos un array con dos elementos en él, que son «Geek» y «Flare». Después accedemos a ellos con sus respectivos índices, que son 0,1 respectivamente, e imprimimos «Geek» y «Flare» en la consola.

Aquí también debemos tener en cuenta que si no se pasan parámetros al método, éste simplemente lanzará un error. Pero si le damos una cadena vacía (ââ) como regex, obtendremos cada carácter individual como una subcadena. Veamos el ejemplo para visualizarlo.

import java.util.Arrays;

public class Subcadenas{    
    public static void main(String args[]){    
    String str="Geek%Flare";
    String[] substrings=str.split("");
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SALIDA:

[G, e, e, k, %, F, l, a, r, e]

Del ejemplo se desprende que como el parámetro regex es una cadena vacÃa, devuelve todos los caracteres como subcadenas separadas, y podemos verlo claramente imprimiendo la matriz de salida del método âsplit()â.

split(Cadena regex,int límite)

Con la segunda variante de este método, obtenemos más control sobre la salida, y podemos afinar aún más la salida del método ‘split()’. Aquí, el método ‘split()’ toma dos variables como entrada. En este caso, junto con el regex, también damos un parámetro de límite en el formato especificado de ‘split(regex, limit)’.

El ‘límite’ es el número de cadenas resultantes que se emiten. Según el valor del límite, puede haber tres posibilidades:

Caso 1: Si límite>0, la matriz resultante contendría la salida, pero aplicaría la división (límite-1) veces como máximo. En este caso, la matriz resultante no contendría más elementos que el límite especificado, y toda la cadena sobrante que no se dividiera se almacenaría tal cual. Hagamos que sea más fácil de entender con algo de código.

import java.util.Arrays;

public class Subcadenas{    
    public static void main(String args[]){    
    String str="Geek%Flare%es%el¾st";
    String[] substrings=str.split("%",2);
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SALIDA:

[Geek, Flare%is%the¾st]

Observe en la salida cómo sólo hay dos elementos en la matriz de resultados, que es el número dado en el parámetro límite. Observe también que la división sólo se aplica una vez, es decir, (límite-1) veces.

Sin embargo, si la regex estuviera dos veces seguidas (â%%â), tendría subcadenas vacías. Mire este trozo de código para entenderlo mejor.

import java.util.Arrays;

public class Subcadenas{    
    public static void main(String args[]){    
    String str="Geek%Flare%is%%the¾st%%%";
    String[] substrings=str.split("%",5);
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SALIDA:

[Geek, Flare, is, , the¾st%%%]

Básicamente, si â%â va seguido de otro â%â o del final de la cadena, se transforma en una subcadena vacía.


Caso 2: Si limit<0, la acción de división se aplicaría tantas veces como fuera posible sin límite en el tamaño del array, pero el array contendría subcadenas vacías si la regex está ahí dos veces seguidas (â%%â).

import java.util.Arrays;

public class Subcadenas{    
    public static void main(String args[]){    
    String str="Geek%Flare%is%%the¾st%%%";
    String[] substrings=str.split("%",-1);
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SALIDA:

[Geek, Flare, es, , el, mejor, , , ]

De la salida se desprende que la división se aplica tantas veces como es posible, y también hay subcadenas vacías presentes.


Caso 3: Si limit=0, la acción de división también se aplicaría tantas veces como fuera posible, pero aquí todas las subcadenas vacías al final de la cadena se descartarían del array.

import java.util.Arrays;

public class Subcadenas{    
    public static void main(String args[]){    
    String str="Geek%Flare%is%%the¾st%%%";
    String[] substrings=str.split("%",0);
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SALIDA:

[Geek, Flare, es, , el, mejor]

Podemos ver que la salida es bastante similar entre cuando limit=-1 y cuando limit=0, pero no hay subcadenas vacías al final. En otras palabras, las subcadenas vacías al final de la matriz de subcadenas se ignoran.

Observe también que si la expresión regular no está presente en la cadena, devuelve como resultado la cadena original entera.

Buscar si una cadena contiene una subcadena

Además de crear subcadenas a partir de cadenas existentes, también podemos especificar una subcadena y averiguar si esa subcadena existe dentro de una cadena. Esta es una forma rápida y sencilla de consultar una subcadena, y resulta útil en muchos casos de uso. Pero, ¿cómo lo hacemos? Varios métodos pueden ayudarnos a conseguirlo. Repasémoslos uno a uno.

Utilizando el método ‘contains()

Podemos encontrar muy fácilmente la existencia de una subcadena con el método ‘contains()’. Este método de la clase String toma como entrada una cadena, que es nuestra subcadena, y devuelve un valor booleano que comprueba si la subcadena está dentro de la cadena o no. Este método se puede utilizar dentro de bloques if-else, operadores unarios, y varios otros lugares para implementar lógica compleja.

Conozcamos un poco más este método.

public class Subcadenas{    
    public static void main(String args[]){    
    String str="GeekFlare";    
    System.out.println("¿Contiene Flare? \n" str.contains("Flare"));  
    }  
}

SALIDA:

¿Contiene Flare? 
verdadero

El código comprueba la cadena «GeekFlare» en busca de la palabra «Flare», y al encontrarla con éxito, devuelve un booleano «true», confirmando así la existencia de la subcadena.

public class Subcadenas{    
    public static void main(String args[]){    
    String str="GeekFlare";    
    System.out.println("¿Contiene Flare? \n" str.contains("Flare1"));  
    }  
}

OUTPUT:

¿Contiene Flare? 
falso

A partir del ejemplo, entendemos que si la subcadena no está dentro de la cadena, el método devolverá false para significar su no existencia. Así podemos estar seguros fácilmente de si la subcadena existe.

Encontrar la posición de una subcadena

#1. Utilizando ‘indexOf()’:

El método ‘indexOf()’ se puede utilizar para encontrar la existencia de una subcadena y también para encontrar su índice. El método toma como entrada una cadena o un carácter y nos da la posición de su primera aparición. Pero sólo es capaz de darnos el índice de la primera ocurrencia y no puede confirmar si existen otras ocurrencias de ésta. Otra cosa a tener en cuenta aquí, si la subcadena no existe, el método devuelve -1.

Así que exploremos un poco más este método.

public class Subcadenas{    
    public static void main(String args[]){    
    String str="GeekFlareGeekFlare";    
    System.out.println("Índice de Flare: " str.indexOf("Flare"));  
    }  
}

SALIDA:

Índice de Flare: 4

Aquí en el ejemplo, la primera aparición de la subcadena «Flare» comienza a partir del índice 4 en la cadena «GeekFlareGeekFlare». Así que, como era de esperar, la función devolvió el índice

#2. Utilizando ‘lastIndexOf()’:

‘lastIndexOf()’ es muy similar a ‘indexOf()’. Ambos métodos toman como entrada la subcadena y devuelven el índice de su posición. Incluso tiene el mismo valor de retorno cuando no puede encontrar la subcadena en la cadena especificada. Ambos métodos devuelven -1 en caso de búsqueda fallida.

Pero mientras que ‘indexOf()’ devuelve el índice de la primera aparición de la subcadena, ‘lastIndexOf()’ devuelve la última aparición.

Veámoslo en acción mediante código:

public class Subcadenas{    
    public static void main(String args[]){    
    String str="GeekFlareGeekFlare";    
    System.out.println("Último índice de Flare: " str.lastIndexOf("Flare"));  
    }  
}

SALIDA:

Último índice de Bengala:13

Observando esta salida, entendemos que el método ‘lastIndexOf()’ se comporta como se esperaba y obtenemos el índice de la última aparición de la subcadena «Flare» en la cadena «GeekFlareGeekFlare».

Preguntas frecuentes

¿Cómo utilizar el método ‘split()’ para crear subcadenas no vacías?

Si hay varias instancias regex de la cadena regex en la cadena principal una tras otra(«Hola%%Hola», donde regex es «%»), el método ‘split()’ considera la primera instancia como un carácter de ruptura, y el resto da como salida una cadena vacía. Para mitigar esto, podemos especificar el parámetro límite como 0. De este modo, sólo dará como salida cadenas no vacías.

¿’indexOf()’ devuelve los índices de todas las instancias de una subcadena?

No, ‘indexOf()’ no devuelve los índices de todas las instancias de una subcadena. Con ‘indexOf()’, obtenemos un valor entero de retorno que contiene el índice de la primera aparición de la subcadena. Pero si no encuentra la subcadena, el método devolverá -1.

¿Qué devuelve el método ‘substring()’ si los índices dados no existen en la cadena?

Si el índice inicial y el índice final dados no existen en la cadena, el compilador lanzará un error. El error debería tener «java.lang.StringIndexOutOfBoundsException: » y simplemente no se ejecutará.

Conclusión

En este artículo, hemos discutido varios métodos y elementos esenciales para empezar con las subcadenas. Hemos discutido la creación de una subcadena y la comprobación de la existencia de una subcadena dentro de una cadena. Esto le permitirá comprender mejor cómo trabajar con subcadenas. Siga los ejemplos y practique más para comprender a fondo las subcadenas.