Un String representa una cadena de caracteres (texto). Aunque en Java es un objeto, conceptualmente se comporta como una secuencia de caracteres inmutable y de tamaño fijo.
// Inicialización directa (literal)
String nombre = "Ana";
// Mediante la palabra clave new (crea un objeto explícito en memoria)
String apellido = new String("García");
Una propiedad fundamental de los String es que son inmutables: una vez creada la cadena en memoria, su contenido no se puede modificar.
Cualquier método que apliquemos sobre un String (convertir a mayúsculas, reemplazar letras, etc.) no modifica el texto original, sino que devuelve un nuevo String con la transformación.
String texto = "hola"; texto.toUpperCase(); // NO modifica la variable 'texto' IO.println(texto); // Muestra "hola" // Para conservar el resultado, debemos reasignarlo a la variable: texto = texto.toUpperCase(); IO.println(texto); // Muestra "HOLA"
A diferencia de los arrays donde usamos corchetes [] y la propiedad .length, en los String utilizamos métodos:
cadena.length() (devuelve el número de caracteres).cadena.charAt(posición) (las posiciones van desde 0 hasta length() - 1).
String mensaje = "Java";
IO.println("Longitud: " + mensaje.length()); // Muestra 4
IO.println("Primer carácter: " + mensaje.charAt(0)); // Muestra 'J'
IO.println("Último carácter: " + mensaje.charAt(mensaje.length() - 1)); // Muestra 'a'
En Java NUNCA debemos usar el operador == para comparar el contenido de dos cadenas. El operador == comprueba si ambas variables apuntan a la misma posición de memoria, no si contienen las mismas letras.
Para comparar texto debemos usar el método .equals() o .equalsIgnoreCase() (para ignorar mayúsculas y minúsculas):
String texto1 = IO.readln("Introduce una palabra: "); // Ejemplo: "hola"
String texto2 = "hola";
// INCORRECTO: Compara referencias de memoria (daría false casi siempre)
if (texto1 == texto2) {
IO.println("Apuntan al mismo objeto en memoria");
}
// CORRECTO: Compara el contenido de las cadenas
if (texto1.equals(texto2)) {
IO.println("El texto es exactamente igual");
}
// Compara ignorando mayúsculas y minúsculas
if (texto1.equalsIgnoreCase("HOLA")) {
IO.println("Coinciden sin importar mayúsculas/minúsculas");
}
La clase String dispone de multitud de métodos para manipular texto de forma sencilla:
| Método | Descripción | Ejemplo | Resultado |
|---|---|---|---|
contains(texto) | Comprueba si contiene una subcadena | “Programación”.contains(“grama”) | true |
indexOf(texto) | Devuelve la posición de la primera aparición (o -1 si no existe) | “Java”.indexOf(“v”) | 2 |
substring(inicio, fin) | Extrae el texto desde inicio hasta fin - 1 | “Elefante”.substring(0, 3) | “Ele” |
toLowerCase() / toUpperCase() | Convierte todo el texto a minúsculas / mayúsculas | “Java”.toLowerCase() | “java” |
replace(viejo, nuevo) | Reemplaza un texto por otro | “Casa”.replace(“a”, “o”) | “Coso” |
trim() | Elimina espacios en blanco al inicio y al final | “ Hola ”.trim() | “Hola” |
Podemos recorrer un String carácter a carácter utilizando un bucle for con charAt(), o convirtiéndolo directamente a un array de caracteres (char[]):
String palabra = "Algoritmo";
// Opción 1: Recorrido con bucle for tradicional y charAt()
for (int i = 0; i < palabra.length(); i++) {
char letra = palabra.charAt(i);
IO.println("Posición " + i + ": " + letra);
}
// Opción 2: Convertir a char[] y recorrer con for-each
char[] letras = palabra.toCharArray();
for (char letra : letras) {
IO.print(letra + " ");
}
IO.println("");
Los array permiten almacenar un conjunto finito de elementos del mismo tipo con un tamaño fijo asignado desde su creación.
tipo[] nombre;nombre = new tipo[tamaño];
Las posiciones se numeran desde la 0 hasta tamaño - 1. Para acceder o modificar un valor usamos los corchetes [].
int[] numbers;
numbers = new int[10];
//int[] numbers = new int[10];
Para almacenar valores en cada una de las posiciones del array, usamos corchetes ([]) indicando en su interior la posición en la que queremos leer o escribir.
numbers[3] = 10;
Para acceder a los datos de un array accedemos mediante nombre[posicion].
int number;
number = numbers[3];
La propiedad length nos devuelve el número total de elementos. Podemos recorrer el array mediante un bucle for convencional o con un bucle for-each:
// Recorrido con for tradicional
for (int i = 0; i < numbers.length; i++) {
IO.println("Índice " + i + ": " + numbers[i]);
}
// Recorrido con for-each (más limpio para lectura)
for (int number : numbers) {
IO.println(number);
}
Inicializar array:
int[] numbers = new int[5];
for(int i=0; i<numbers.length; i++) {
numbers[i] = Integer.parseInt(IO.readln("Introduce un número entero: "));
}
Otra forma de inicializar un array es definiendo sus valores como una lista separada por comas encerrada entre llaves. Ésto lo debemos hacer a la hora de la declaración del array, y no hace falta indicarle la longitud, ya que se lo indicamos con el número de elementos que le pasemos:
int[] numbers = {1, 3, 312, 15, 69, 7, 8, 9, 0, 1};
Podemos declarar un array de más de una dimensión (como tablas o matrices):
// Inicialización directa
int[][] table = {
{3, 5, 6},
{2, 4, 9}
};
// Recorrido con bucles anidados
for (int[] row : table) {
for (int cell : row) {
IO.print(cell + " ");
}
IO.println("");
}
A diferencia de los tipos primitivos, los arrays son objetos. Al pasarlos como parámetro a un método, se copia la referencia a la memoria original. Por tanto, cualquier cambio dentro del método modificará el array original.
static void main() {
int[] numbers = {1, 2, 3};
updateFirst(numbers);
IO.println(numbers[0]); // Muestra 99
}
static void updateFirst(int[] data) {
data[0] = 99; // Modifica el array original
}