Prog Estructuras de almacenamiento

De MediaWiki
Ir a la navegación Ir a la búsqueda

Introducción

  • En lo que llevamos de curso ya hemos visto varias estructuras de almacenamiento: clases y arrays.
  • Para almacenar información no siempre llega guardar datos en tipo de datos simples, como un entero, una cadena, o un float.
Muchas veces es necesario guardar información de varios tipos o guardar un conjunto de datos del mismo tipo.
  • Vimos que podemos guardar información de diferentes tipos de datos formando 'un todo' en una clase. Por ejemplo, si quiero guardar la información de un empleado, con su nombre, edad, años de antigüedad...
Cuando definimos una clase indicamos con sus atributos (tipos de datos simples o compuestos) que información va a guardar.
Otras veces, la información que queremos guardar necesita una estructura de datos que permite guardar múltiples valores del mismo tipo, por ejemplo, un conjunto de notas de un alumno.
Esto ya vimos que lo podíamos guardar utilizando arrays.


  • Las estructuras de datos en base a diferentes criterios las podemos clasificar de varias formas.
  • En función de los diferentes tipos de datos que puedan guardar:
  • Que puedan guardar tipos de datos del mismo tipo. Ejemplo de este tipo de estructuras son las cadenas de caracteres (guardan múltiples caracteres), los arrays (ya vistos), las listas y los conjuntos.
  • Que puedan guardar tipos de datos diferentes. Por ejemplo las clases.
  • En función de si se puede modificar o no el número de elementos que conforman el array (su tamaño):
  • Que no se puedan modificar su tamaño una vez creada (estructuras estáticas). Por ejemplo, los arrays.
  • Que se pueda modificar su tamaño en tiempo de ejecución de forma dinámica (aumentar y disminuir de tamaño). Se conocen como estructuras dinámicas. Por ejemplo las listas, árboles, conjuntos y algunas clases que manejan caracteres.
  • En función de si los datos guardados en la estructura pueden estar ordenados:
  • Que no puedan estar ordenados. Por ejemplo los arrays. Debe ser el programador el que modifique los datos guardados para ordenarlos.
  • Que se puedan ordenar en base a diferentes criterios.



Cadena de caracteres

Existe otro método, el método compareTo. A diferencia del anterior, compara las dos cadenas lexicográficamente.
Disponemos de dos variantes en las que se ignora el hecho de que las letras estén en mayúsculas o en minúsculas:
  • Métodos usados habitualmente:

Strings dinámicos

  • Cada vez que usamos una cadena estamos creando un objeto de una clase String, cogiendo memoria. Esa memoria se reserva 'consecutivamente' y no puede variarse su tamaño, por lo que si queremos concatenar otra cadena, necesitamos utilizar otra zona de memoria donde quepa la cadena al completo.
Además las cadenas son 'inmutables' en el sentido que no podemos 'acortalas' o 'ampliarlas', ya que estaríamos creando una nueva cadena.
  • Por estos problemas, Java dispone de dos clases que permiten crear cadenas dinámicas, a las que vamos a poder ampliar o reducir su contenido.
  • StringBuilder.
  • StringBuffer: Esta es igual a la anterior pero está optimizada para ser usada por aplicaciones multihilo (multi-threads)
  • Dentro de la clase StringBuilder disponemos de los métodos:




Ejercicios cadenas

Básicos

  • Indica cuantas instancias de clase String se crean en cada una de las instrucciones:
  • String cad = "Hola" + "Mundo";
  • String cad = new String("Hola Mundo");
  • String cad = new String("Hola Mundo") + ". Bienvenido" + new String(" a casa");
Lo mismo pasaría si usamos el método concat:
  • String cad = "Hola".concat("Mundo");
  • String cad = 10+5 + " no es igual " + 12+3;
¿ Cual es el resultado ?
  • Crea un objeto de cada una de las clases envoltorio de los tipos de datos numéricos primitivos (Integer, Float, Byte, Decimal) y imprímelos (sin necesidad de convertirlos) con el siguiente formato, haciendo uso del método printf:

Byte: ZZ SHORT: GG Integer: XX Long: DDDDD Float: YY.YY (dos dígitos para los decimales) Double: DD.DDD (tres dígitos para los decimales)

Haz lo mismo pero concatenando (sin establecer formato).


  • Explica como puede funcionar la siguiente instrucción:
byte num = 55;
String cad = "Juan tiene" + num;


  • Para convertir cadenas a números hacemos uso de los métodos parseXXXX de las clases envoltorio o bien llamando al método valueOf que devuelve una instancia de la clase envoltorio.
Pide gráficamente (JOptionPane.showInputDialog) que un usuario introduzca un número entero. Se debe informar al usuario (JOptionPane.showMessageDialog) si el número introducido no es correcto. En caso de que lo sea se mostrará el valor.
Deberá seguir solicitando introducir un número hasta que introduzca un número correcto entre 1 y 100.


  • Implementa un ejemplo de cada uno de los métodos utilizados habitualmente con la clase String.


  • Indica la salida de las siguientes órdenes:
1         String cad = "Casa".concat("Angel").replace("a", "o");
2         String cad = "Juan".length() + "Pedro".substring("ejemplo".indexOf("e"),2);
3         boolean salida = "Pase y diga una frase".replace("ase","to").endsWith("ta");
4         int comparar = "Amigo".compareToIgnoreCase("amiga");  (indicar si el número 'comparar' es positivo o negativo o cero.
5         int pos = "Abracadabra".replace("ra","le").lastIndexOf("bl");



Strings dinámicos

  • Haz uso de la clase StringBuilder para a partir de una cadena obtener otra utilizando los métodos disponibles para borrar, reemplazar, insertar y añadir (primero hazlo con varias órdenes y después con una sola. Debes de hacer uso de los tres métodos):
  • Tenemos: "La casa de la pradera" => "El coso mío de praderaaaa"



Expresiones regulares

  • Busca la expresión regular (y compruébala en este enlace) que cumpla lo siguiente:
  • Una entrada de 5 a 10 números entre 3 y 7 seguidos por la letra a o A.
  • Una entrada con vocales hasta un máximo de 10 seguido opcionalmente de un número.
  • Una entrada con el siguiente patrón: XX00000ZZ0 siendo XX letras entra la a y la z, ZZ vocales, 00000 números entre 0 y 5 y 0 números entre 0 y 9 y que pueden repetirse indefinidamente
  • Una entrada de 5 a 10 letras seguidos por la letra a o b de forma opcional (pueden aparecer o no)



Solución ejercicios cadena

  • Indica cuantas instancias de clase String se crean en cada una de las instrucciones:
  • String cad = "Hola" + "Mundo"; => 3.
  • String cad = new String("Hola Mundo"); => 2.
  • String cad = new String("Hola Mundo") + " Bienvenido" + new String(" a casa"); => 7.
Lo mismo pasaría si usamos el método concat:
  • String cad = "Hola".concat("Mundo"); => 3.
  • String cad = 10+5 + " no es igual a " + 12+3; => 5
Resultado: 15 no es igual a 123


  • Crea un objeto de cada una de las clases envoltorio de los tipos de datos numéricos primitivos (Integer, Float, Byte, Decimal) y imprímelos (sin necesidad de convertirlos) con el siguiente formato, haciendo uso del método printf:

Byte: ZZ SHORT: GG Integer: XX Long: DDDDD Float: YY.YY (dos dígitos para los decimales) Double: DD.DDD (tres dígitos para los decimales)

1         Byte b = 2;
2         Short s = 2131;
3         Integer i = 34;
4         Long l = 324324l;
5         Float f = 12.45f;
6         Double d = 44.24d;
7         
8         System.out.printf("\nByte:%d\nShort:%d\nInteger:%d\nLong:%d\nFloat:%.2f\nDouble:%.3f",b,s,i,l,f,d);
En este caso estamos haciendo uso de objetos de clases y cuando se imprimen se llama al método toString de la clase.
Haz lo mismo pero concatenando (sin establecer formato).
Al igual que en el caso anterior está llamando al método toString.


  • Explica como puede funcionar la siguiente instrucción:
byte num = 55;
String cad = "Juan tiene" + num;
En este caso, Java convierte el tipo de dato primitivo (byte) a la clase envoltorio Byte y después llama al método toString de la misma.


  • Indica la salida de las siguientes órdenes:
1         String cad = "Casa".concat("Angel").replace("a", "o");                                 => CosoAngel
2         String cad = "Juan".length() + "Pedro".substring("ejemplo".indexOf("e"),2);            => 4Pe
3         boolean salida = "Pase y diga una frase".replace("ase","to").endsWith("ta");           => false
4         int comparar = "Amigo".compareToIgnoreCase("amiga");                                   => Positivo 
5         int pos = "Abracadabra".replace("ra","le").lastIndexOf("bl");                          => 8


  • Haz uso de la clase StringBuilder para a partir de una cadena obtener otra utilizando los métodos disponibles para borrar, reemplazar, insertar y añadir (primero hazlo con varias órdenes y después con una sola. Debes de hacer uso de los tres métodos):
  • Tenemos: "La casa de la pradera" => "El coso mío de praderaaaa"
1         StringBuilder cadena = new StringBuilder("La casa de la pradera");
2         cadena.replace(cadena.indexOf("La"), 2, "El");
3         cadena.replace(cadena.indexOf("casa"), 7, "coso");
4         cadena.insert(8,"mío ");
5         cadena.delete(14, 17);
6         cadena.append("aaa");


Expresiones regulares

  • Busca la expresión regular (y compruébala en este enlace) que cumpla lo siguiente:
  • Una entrada de 5 a 10 números entre 3 y 7 seguidos por la letra a o A. => [3-7]{5,10}[aA]
  • Una entrada con vocales hasta un máximo de 10 seguido opcionalmente de un número. => [a-zA-Z]{1,10}[0-9]
  • Una entrada con el siguiente patrón: XX00000ZZ0 siendo XX letras entra la a y la z, ZZ vocales, 00000 números entre 0 y 5 y 0 números entre 0 y 9 y que pueden repetirse indefinidamente => [a-z]{2}[0-5]{5}[aeiou]{2}[0-9]+
  • Una entrada de 5 a 10 letras seguidos por la letra a o b de forma opcional (pueden aparecer o no) => [a-z]{5-10}[ab]?





-- Ángel D. Fernández González -- (2017).