viernes, 27 de febrero de 2026

■ StringBuilder la alternativa a String

El problema de String

En Java, las variables de tipo String son como una foto, una vez que la tomas no la puedes cambiar, por ejemplo si hacemos esto:

String frase = "Hola";
frase = frase + " mundo"; //o frase += "mundo";


Parece que modificamos "frase", pero en realidad Java hizo esto:
1. Creó el objeto "Hola".
2. Creó el objeto "mundo".
3. Creó un tercer objeto "Hola mundo".

¿Y los primeros dos?, quedan huérfanos en la memoria y eventualmente son eliminados por el garbage collector, es decir, existen pero ya no se usan, por lo tanto "frase" no cambia  solo es sustituida por un nuevo objeto.

Ahora imagina si hacemos esto en un ciclo que se repita muchas veces, lo único que conseguiríamos es saturar la memoria RAM. Entonces ¿cúal es la solución?, aquí es donde entra StringBuilder.


■ StringBuilder

StringBuilder es como escribir a lápiz, podemos anotar, añadir, borrar y volver a anotar, todo sobre el mismo medio, en este caso la variable si cambia y no se destruye cada vez.

¿Cómo funciona?, mantiene un espacio en memoria que puede cambiar, ya sea crecer o reducirse según se necesite, pero ¿cómo se logra esto?, usando los métodos propios de esta clase, estos son los siguientes.

Primero creamos el objeto, a diferencia de la variable String que se crea así:
String texto = "";

El objeto StringBuilder debe crearse como tal, es decir:
StringBuilder sb = new StringBuilder();

Donde "sb" es el nombre que queramos darle.

Una vez creado ya podemos trabajar con él y esto se hace de la siguiente forma:

■ Métodos

append(texto): Inserta un texto al final.

Este método nos sirve para inicializar nuestro objeto o bien para anexarle más texto al final del mismo.

Inicializar:
sb.append("Haz el bien");
System.out.println(sb); // Imprimirá "Haz el bien"


Insertar texto al final:
sb.append(" sin mirar a quién");
System.out.println(sb); // Imprimirá "Haz el bien sin mirar a quién"


Nótese que al anexar la segunda parte la iniciamos con un espacio en blanco, esto para que el texto no quede pegado, de lo contrario diría:
"Haz el biensin mirar a quién"

insert(pos, texto): Inserta texto en determinada posición.
Si queremos insertar al inicio, indicamos en la posición 0:
sb.insert(0, "Hey tú! ");
System.out.println(sb); // Imprime "Hey tú! Haz el bien sin mirar a quién
"

Si queremos insertar algo a media frase, calculamos la posición y la indicamos:
sb.insert(19, ","); // Insertamos una coma
System.out.println(sb); // Imprime: "Hey tú! Haz el bien, sin mirar a quién"

delete(inicio, fin): Elimina un rango del texto.
Recibe dos parámetros, el primero es la posición de la cadena donde inicia el texto a eliminar y el segundo es la posición donde termina, por ejemplo si queremos eliminar la primera parte de la frase:
sb.delete(0, 8);
System.out.println(sb); // Imprime: "Haz el bien, sin mirar a quién"

deleteCharAt(pos): Elimina el caracter de eterminada posición.
Indicamos la posición y elimina el caracter que ahí se encuentre:
sb.deleteCharAt(29);
System.out.println(sb); // Imprime: "Haz el bien, sin mirar a quié"


Es decir, se eliminó el último caracter, otra forma de hacerlo para no tener que contar cuántos caracteres son y saber cuál es el último, es pasándole length como posición menos 1, ya que devuelve la longitud de la cadena pero dado que los índices inician en 0 hay que restar 1:
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb);
 // Imprime: "Haz el bien, sin mirar a quié"

replace(inicio, fin, texto): Remplaza un rango de texto con el proporcionado.

El primer parametro es la posición a partir de la cual queremos insertar el texto, el segundo parámetro es la longitud a partir de la posición inicial que elegimos que sustituirá el nuevo texto de la frase original.

Por ejemplo si queremos sustituir, de la frase anterior "quié" por "quiénes", lo haríamos así:
sb.replace(25, 29, "quiénes");
System.out.println(sb); // Imprime: "Haz el bien, sin mirar a quiénes"


Donde:
25 es la posición donde inicia la palabra "quié".
29 es la posición final de la frase.
Con esto decimos que se va sustituir el texto desde la posición 25 hasta la 29.

Por lo que si quisiéramos insertar un texto sin alterar la frase, le pasaríamos la misma posición inicial como final:
sb.replace(11, 11, " hoy");
System.out.println(sb); // Imprime "Haz el bien hoy, sin mirar a quiénes"
Al decirle que la posición inicial es la misma que la final, el texto nuevo se inserta ahí mismo y empuja al resto, por lo que la frase restante no se ve alterada.

reverse(): Invierte el texto.

Esta es muy simple, solo invierte los caracteres del texto, el primero será el último, el segundo el penúltimo, el tercero el antepenúltimo y así sucesivamente:
sb.reverse();
System.out.println(sb); // Imprime  "senéiuq a rarim nis ,yoh neib le zaH"


Este cambio no es solo visual sino permanente, por lo que si queremos devolver a la frase a su estado original haríamos nuevamente lo mismo:
sb.reverse();
System.out.println(sb); // Imprime "Haz el bien hoy, sin mirar a quiénes"

substring(inicio, fin): Devuelve el texto del rango indicado.

A diferencia de los métodos anteriores, este no modifica la frase, solo regresa parte de ella, por lo que si hacemos esto:
System.out.println(sb.substring(7, 11)); // Imprime "bien"
System.out.println(sb); // Imprime "Haz el bien hoy, sin mirar a quiénes"

La frase original sigue intacta.

charAt(pos): Obtiene el caracter de la posición indicada.

Igual que el caso anterior (substring), este método no cambia la frase, solo obtiene el caracter de la posición que le indiquemos:
System.out.println(sb.charAt(7)); // Imprime "b"
System.out.println(sb); // Imprime "Haz el bien hoy, sin mirar a quiénes"

La frase original sigue intacta.

length(): Devuelve la longitud del texto.
Simplemente devuelve un entero equivalente a la longitud de la cadena de texto que almacena el objeto:
System.out.println(sb); // Imprime 36

setLength(tamaño): Corta o expande el tamaño del texto.
Acorta el texto hasta el tamaño indicado, es decir, si le pasamos un 11, entonces esta será la nueva longitud del texto y se eliminará el resto:
sb.setLength(11);
System.out.println(sb); // Imprime: "Haz el bien"

toString(): Convierte el objeto a tipo String.
String texto = sb.toString(); // Asignar el objeto a una variable String
System.out.println(sb); // Imprime "Haz el bien"
System.out.println(texto); // Imprime "Haz el bien"

capacity(): Devuelve el espacio reservado.
System.out.println(sb.capacity()); // Imprime (en mi caso) 70


Sabiendo esto y dependiendo de lo que necesites hacer, ahora podrás elegir entre String o StringBuilder para trabajar con cadenas de texto, ninguno es mejor que el otro, simplemente se comportan diferente y uno se adapta mejor que el otro en diferentes escenarios.

jueves, 7 de noviembre de 2024

Java 032 ► Contar las vocales y consonantes de un String

Ejercicio 032: Contar cuántas vocales y consonantes tiene un String. (No se consideran vocales acentuadas ni caracteres que no sean letras ni la "ñ").

Entrada: "Una frase cualquiera"

Salida: Vocales: 10
           Consonantes: 8

import java.util.*;

public class Java_032 {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        String frase = "";
        int vocal = 0, consonante = 0;
      
        System.out.println("Ingresa la frase");
        frase = sc.nextLine();
        
        frase = frase.toLowerCase();
        
        for (int i=0; i < frase.length(); i++) {
            if ((frase.charAt(i) == 'a') ||
                (frase.charAt(i) == 'e') ||
                (frase.charAt(i) == 'i') ||
                (frase.charAt(i) == 'o') ||
                (frase.charAt(i) == 'u')) {
                vocal++;
            } else if (frase.charAt(i) != ' ') {
                consonante++;
            }
        }
        
        System.out.println();
        System.out.println("Vocales:\t " + vocal);
        System.out.println("Consonantes: " + consonante);
    }
}


Explicación:

Dado que no estamos considerando caracteres especiales como vocales acentuadas o símbolos suponemos que el String de entrada solo contendrá letras, lo primero que hacemos es convertir todo el String a minúsculas (con el método toLowerCase) para que al revisarlo letra por letra no tengamos que evaluar si es minúscula o mayúscula.

Luego recorremos el String como si de un arreglo se tratara con un for y por cada uno de sus caracteres preguntamos si es igual a las letras "a", "e", "i", "o" o "u", en cualquiera de esos casos contabilizamos una vocal.

Si la posición actual del String no es ninguna de las anteriores y sabiendo que el String solo contiene vocales y consonantes, sabemos que si no es vocal y omitiendo los espacios significa que es consonante y por lo tanto en el else se contabilizan las consonantes. Al final solo se muestran los resultados.

miércoles, 2 de octubre de 2024

■ Estructura visual del sitio web con HTML y CSS

■ Principales elementos de la estructura de un sitio web

• Header

El header es el encabezado de la página, se situa en la parte superior y es lo primero que ve el usuario al entrar al sitio web, generalmente en el header se colocan cosas como el logo de la página, el título, el menú de navegación, las opciones de inicio de sesión, entre otras cosas.

• Main

El main es el cuerpo de sitio web, situado abajo del header, el main alberga el contenido principal de la página, puede estar dividido en varias secciones como una columna de menus nav, una columna más amplia central que es donde se presenta el contenido principal que bien puede ser un section un div, y una columna para mostrar contenidos adicionales llamada aside. Estas secciones no son obligatorias, dependen del tipo de sitio web y de lo que se quiera mostrar en el mismo.

• Footer

Es el pie de página, es la sección localizada en la parte inferior de la página web que contiene información menos importante que las secciones anteriores, en él se pueden poner información relacionada con la página web, sus autores, datos de contacto, entre otros.

Estos elementos vistos en la página web lucen de esta forma:

Figura 1

Esta solo es una 'plantilla' típica de cómo estructurar el sitio, ya que puede hacerse de muchas formas dependiendo de lo que se quiera mostrar y cómo se quiera mostrar, algunas plantillas son más acordes para ciertas cosas y otras plantillas son más adecuadas para otras.


■ Pasando a HTML

Para crear un sitio como el de la imagen anterior es necesario agregar los elementos contenedores en la sección del body del HTML, éstos contenedores son: header, main, nav, section, aside y footer.

Un elemento contenedor como los mencionados y como article o div, son áreas definidas de la página web que nos permiten acomodar otros elementos en ellas, elementos como textos, botones, campos de entrada, imágenes, animaciones, etc., y por ello es que primero debemos estructurar la página web con ellos para después cargarlos de información.

La estructura anterior en HTML (omitiendo el contenido del <head>) quedaría de la siguiente forma:

<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- Metadatos, hojas de estilo y scripts -->
    </head>
    <body>
        <header>
            <h1>HEADER</h1>
        </header>
        <main>
            <nav>
                <h1>NAV</h1>
            </nav>
            <section>
                <h1>SECTION</h1>
            </section>
            <aside>
                <h1>ASIDE</h1>
            </aside>
        </main>
        <footer>
            <h1>FOOTER</h1>
        </footer>
    </body>
</html>

Pero si nos limitamos solo al HTML el sitio no tendría estilos viendose así:


■ CSS

Ahí es donde entra el uso de CSS, ya que aunque es posible darle estilo al sitio en el mismo HTML mediante los llamados "estilos en línea", que no es más que un "CSS" incrustado en los elementos diciéndoles cómo queremos que se vean, esta no es la mejor forma de hacerlo ya que nos obliga a reescribir las reglas para cada elemento y esto hace que el HTML se vaya volviendo ilegible o difícil de entender, por ejemplo para lograr que sitio se vea como la figura 1 sin usar archivos CSS, el HTML severía así:

<!DOCTYPE html>
<html lang="en">
    <head>
</head>
    <body>
        <header style="
            background-color: darkorchid;
            text-align: center;
            height: 100px;
            margin:  5px;
        ">
            <h1 style="
                color: white;
                padding-top: 20px;
            ">HEADER</h1>
        </header>
        <main style="display: flex;">
            <nav style="
                background-color: darkorchid;
                text-align: center;
                height: 380px;
                margin:  5px;
                width: 200px;
            ">
                <h1 style="
                    color: white;
                    padding-top: 150px;">NAV</h1>
            </nav>
            <section style="
                background-color: darkorchid;
                text-align: center;
                height: 380px;
                margin:  5px;
                width: 505px;
            ">
                <h1 style="
                    color: white;
                    padding-top: 150px;">SECTION</h1>
            </section>
            <aside style="
                background-color: darkorchid;
                text-align: center;
                height: 380px;
                margin:  5px;
                width: 250px;
            ">
                <h1 style="
                    color: white;
                    padding-top: 150px;">ASIDE</h1>
            </aside>
        </main>
        <footer style="
            background-color: darkorchid;
            text-align: center;
            height: 100px;
            margin:  5px;
        ">
            <h1 style="
                color: white;
                padding-top: 20px;
            ">FOOTER</h1>
        </footer>
    </body>
</html>
HTML con estilos en línea

Mientras que si usamos un archivo para el CSS, el código HTML no se vería afectado, solo se enlazaría en el <head> la hoja de estilos (archivo .css):


<link type="text/css" rel="stylesheet" href="css/estilos.css">


 Y los estilos quedarían en ella de la siguiente forma:

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

header,
footer {
    background-color: darkorchid;
    text-align: center;
    height: 100px;
    margin:  5px;
}

header h1,
footer h1 {
    color: white;
    padding-top: 20px;
}

main {
    display: flex;
}

main nav,
main section,
main aside {
    background-color: darkorchid;
    text-align: center;
    height: 380px;
    margin:  5px;
}

main nav {
    width: 200px;
}

main section {
    width: 505px;
}

main aside {
    width: 250px;
}

main nav h1,
main section h1,
main aside h1 {
    color: white;
    padding-top: 150px;
}

Dejando el HTML como lo teníamos originalmente y solo con en link a la hoja de estilos:

<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- Se enlaza la hoja de estilos -->
        <link type="text/css" rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
        <header>
            <h1>HEADER</h1>
        </header>
        <main>
            <nav>
                <h1>NAV</h1>
            </nav>
            <section>
                <h1>SECTION</h1>
            </section>
            <aside>
                <h1>ASIDE</h1>
            </aside>
        </main>
        <footer>
            <h1>FOOTER</h1>
        </footer>
    </body>
</html>
HTML sin estilos en línea

Haciendo que el código sea más claro y legible, ya que lo tendríamos seccionado y para realizar modificaciones simplemente iríamos al archivo donde esté el elemento a modificar, ya sea el HTML o el CSS por separado.