Ud6 Prog
Ud6 Prog
DE ALMACENAMIENTO
2
RESUMEN INTRODUCTORIO
INTRODUCCIÓN
CASO INTRODUCTORIO
3
1. ARRAYS
El array es una de las estructuras de datos más ampliamente utilizada por
su flexibilidad para derivar en complejas estructuras de datos y su
simplicidad. Empezaremos con una definición: un array es una secuencia de
elementos, donde cada elemento (un grupo de bytes de memoria que
almacenan un único ítem de datos) se asocia con al menos un índice
(entero no negativo). Esta definición da lugar a cuatro puntos interesantes:
RECUERDA
ENLACE DE INTERÉS
• Los arrays
4
2. ARRAYS DE UNA DIMENSIÓN
El tipo de array más simple tiene una sola dimensión: cada elemento se
asocia con un único índice. El lenguaje Java proporciona varias técnicas
para crear un array de una dimensión:
RECUERDA
5
EJEMPLO PRÁCTICO
RECUERDA
EJEMPLO PRÁCTICO
7
Reloj [] c2 = new RelojAlarma [3]; se asemeja a la declaración anterior,
excepto en que se crea un array unidimensional RelojAlarma, y su referencia se
asigna a la variable Reloj[] de nombre c2. (Asume RelojAlarma como subclase
de Reloj).
VIDEO DE INTERÉS
8
RECUERDA
EJEMPLO PRÁCTICO
EJEMPLO PRÁCTICO
9
Reloj[] c1 = new Reloj[3]; declara una variable de array unidimensional c1 del
tipo Reloj[], asigna memoria para un array Reloj que consta de un solo
elemento, crea un objeto Reloj y asigna su referencia a este elemento, y asigna
la referencia del array Reloj a c1. El código Reloj[] c2 = new RelojAlarma[3]; se
parece a la declaración anterior, excepto en que crea un array unidimensional de
un sólo elemento RelojAlarma que inicializa un objeto del tipo RelojAlarma.
ENLACE DE INTERÉS
EJEMPLO PRÁCTICO
10
public static void main(String[] args) {
String [] meses = new String [] { "Ene", "Feb", "Mar", "Abr",
"May", "Jun","Jul", "Ago", "Sep", "Oct", "Nov", "Dic" };
System.out.println (meses [0]); // Salida: Ene
// La siguiente instrucción provoca una excepción del tipo
// ArrayIndexOutOfBoundsException porque el índice es mayor
// que la longitud del array menos uno
System.out.println (meses [meses.length]);
System.out.println (meses [meses.length - 1]); // Salida: Dic
// La siguiente instrucción provoca una excepción del tipo
// ArrayIndexOutOfBoundsException porque el índice es < que 0
System.out.println (meses [-1]);
}
EJEMPLO PRÁCTICO
El compilador no dará ningún error porque todas las líneas son legales. Sin
embargo, durante la ejecución, c[0] = new Reloj(); resulta que lanza una
excepción del tipo ArrayStoreException. Esta excepción ocurre porque se puede
intentar acceder a un miembro específico de RelojAlarma mediante una referencia
a un objeto Reloj.
11
Por ejemplo, supongamos que RelojAlarma contiene un método public void
suenaAlarma(), Reloj no lo tiene, y el fragmento de código anterior se ejecuta sin
lanzar una excepción del tipo ArrayStoreException. Un intento de ejecutar a
c[0].suenaAlarma(); bloquea la JVM Máquina Virtual Java porque estamos
intentando ejecutar este método en el contexto de un objeto Reloj (que no
incorpora un método suenaAlarma()).
RECUERDA
12
EJEMPLO PRÁCTICO
La salida será:
Encontrado: 72
ARTÍCULO DE INTERÉS
• Algoritmos de búsqueda
13
Si el dato es numéricamente menor que el dato del elemento central,
la búsqueda binaria calcula el índice central de la mitad inferior del
array, ignorando la sección superior y repite el proceso. La búsqueda
continúa hasta que se encuentre el dato o se exceda el límite de la
sección (lo que indica que el dato no existe en el array).
La única ventaja de la búsqueda binaria es que reduce el tiempo
empleado en examinar elementos. El número máximo de elementos a
examinar es log2n (donde n es la longitud del array unidimensional).
Por ejemplo, un array unidimensional con 1.048.576 elementos
requiere que la búsqueda binaria examine un máximo de 20
elementos. La búsqueda binaria tiene dos inconvenientes; el
incremento de complejidad y la necesidad de preordenar el
array.
EJEMPLO PRÁCTICO
14
• Ordenación de Burbuja: Cuando entra en juego la ordenación de
datos, la ordenación de burbuja es uno de los algoritmos más
simples. Este algoritmo hace varios pases sobre un array
unidimensional. Por cada pase, el algoritmo compara datos
adyacentes para determinar si numéricamente es mayor o menor. Si
el dato es mayor (para ordenaciones ascendentes) o menor (para
ordenaciones descendientes) los datos se intercambian y se baja de
nuevo por el array. En el último pase, el dato mayor (o menor) se ha
movido al final del array. Este efecto "burbuja" es el origen de su
nombre.
VIDEO DE INTERÉS
15
EJEMPLO PRÁCTICO
int[] x= {20,15,12,30,-5,72,456};
int i, j, aux;
for (i = 0; i < x.length-1; i++) {
for (j = 0; j < x.length - i - 1; j++) {
if (x[j + 1] < x[j]) {
aux = x[j + 1];
x[j + 1] = x[j];
x[j] = aux;
}
}
for (i=0;i<x.length;i++) {
System.out.println("Valor del array " +x[i]);
}
}
SABÍAS QUE...
16
Java proporciona tres técnicas para crear un array bidimensional:
17
EJEMPLO PRÁCTICO
18
• Utilizar sólo la palabra clave "new"
Esta técnica requiere cualquiera de estas sintaxis:
En ambas sintaxis:
- variable_name especifica el nombre de la variable del array
bidimensional.
- type especifica el tipo de cada elemento. Como es una variable
de array bidimensional contiene una referencia a un array
bidimensional, su tipo es type[ ][ ].
- La palabra clave new seguida por type y por una expresión
entera entre corchetes cuadrados, que identifica el número
de filas. La instrucción new asigna memoria para las filas del
array unidimensional de filas y pone a cero todos los bytes de
cada elemento, lo que significa que cada elemento contiene
una referencia nula.
19
Debe crear un array unidimensional de columnas separado y
asignarle su referencia cada elemento fila.
- = se utiliza para asignar la referencia del array bidimensional
a variable_name.
EJEMPLO PRÁCTICO
En ambas sintaxis:
- variable_name especifica el nombre de la variable del array
bidimensional.
- type especifica el tipo de cada elemento. Como es una variable
de array bidimensional contiene una referencia a un array
bidimensional, su tipo es type[ ][ ].
- La palabra clave new seguida por type y por dos parejas de
20
corchetes cuadrados vacíos, y cero o más inicializadores de
filas entre un par de corchetes cuadrados. Si no se especifica
ningún inicializador de fila, el array bidimensional está vacío.
Cada inicializador de fila especifica cero o más valores iniciales
para las columnas de esa fila.
- = se utiliza para asignar la referencia del array bidimensional
a variable_name.
EJEMPLO PRÁCTICO
VIDEO DE INTERÉS
21
EJEMPLO PRÁCTICO
22
RECUERDA
ENLACE DE INTERÉS
• Matemáticas/Matrices/Multiplicación
EJEMPLO PRÁCTICO
23
4. CLASE STRING: REPRESENTANDO UNA
CADENA
Una cadena de texto no deja de ser más que la sucesión de un conjunto de
caracteres alfanuméricos, signos de puntuación y espacios en blanco con
más o menos sentido.
Todas ellas serán representadas en java con la clase String. Para encontrar
la clase String dentro de las librerías de Java tendremos que ir a
java.lang.String.
ENLACE DE INTERÉS
• Clase String
En este caso, Java, creará un objeto String para tratar esta cadena.
ENLACE DE INTERÉS
• Gestión de cadenas
26
Cuando el método llega al carácter de índice 3 (4º carácter)
tiene que comparar entre la r minúscula y la n minúscula. Si
utiliza el código Unicode llegará a la siguiente conclusión.
r(114) > n(110)
Y devolverá la resta de sus valores. En este caso un 4.
Se debe tener cuidado, porque este método no tiene en cuenta
las mayúsculas y minúsculas. Y dichos caracteres, aun siendo
iguales, tienen diferentes códigos. En la siguiente comparación:
ENLACE DE INTERÉS
28
El método…
Devolverá “Cuervo”.
El método...
Los ficheros XML se usan básicamente para tratar datos, ya sea para
estructurarlos, para enviar y recibir datos o para utilizarlos como base de
datos. La principal idea de los ficheros XML es que son portables, e
independientes del lenguaje de programación que usemos para procesarlos,
además de ser simples de editar a mano y fáciles de comprender.
Existen dos formas de procesar los ficheros XML en Java, básicamente. Por
una parte, se tiene el modelo DOM (Document Object Model) y por otra
parte el modelo SAX (Simple API for XML).
29
ENLACE DE INTERÉS
5.1 Dom
A la hora de procesar un documento XML con DOM, la representación que
se tiene va a ser la de un árbol jerárquico en memoria. Esto implica varias
cosas que se detallan a continuación:
30
Se tendrá un Document en memoria que representa al árbol del que saldrá el
fichero XML. Sin embargo, este árbol no tiene ni siquiera un nodo raíz, así
que el siguiente paso es crearlo:
Existe una cosa más en los ficheros XML, y son los atributos. Un nodo
(una etiqueta), puede tener una serie de atributos a los cuales se les asigna
nombre y valor, o puede no tener ninguno. De esta forma se podría agregar
al nodo raíz el atributo autor con valor elAutor, de la siguiente forma:
31
Esto deja en la variable sw la representación XML de este documento, con
su sangrado correspondiente y listo para ser tratado. Ahora se podría
escribir por pantalla, por fichero, mandarlo por un Socket… en este caso se
agrega un poco de código para escribirlo en un fichero:
32
Por otra parte, si se quiere leer un fichero XML y procesarlo de alguna
manera, primero se necesita crear un Document en memoria a partir de un
fichero XML bien formado:
33
Además, si se miran esos nodos de tipo #text se verá que no son nada. De
modo que para evitarlos se pueden filtrar así:
Se supone que se quiere sacar el valor por alguna razón. El código sería el
siguiente:
EJEMPLO PRÁCTICO
Se ve un ejemplo completo.
Archivo XML:
34
<Pedidos>
<Pedido numeroPedido="1">
<Cliente>
<Nombre>Thomas</Nombre>
<Apellido>Anderson</Apellido>
<User>Neo</User>
</Cliente>
<Productos>
<Producto>
<Nombre>Matrix 7.0</Nombre>
<FechaAlta>1307542390468</FechaAlta>
</Producto>
<Producto>
<Nombre>Gravedad 2.0</Nombre>
<FechaAlta>1307542390468</FechaAlta>
</Producto>
</Productos>
</Pedido>
<Pedido numeroPedido="2">
<Cliente>
<Nombre>Mr.</Nombre>
<Apellido>Regan</Apellido>
<User>Cifra</User>
</Cliente>
<FechaAlta>1307542390468</FechaAlta>
</Producto>
</Productos>
</Pedido>
<Pedido numeroPedido="2">
<Cliente>
<Nombre>Mr.</Nombre>
<Apellido>Regan</Apellido>
<User>Cifra</User>
</Cliente>
<Productos>
<Producto>
<Nombre>Reinsercion 1.0</Nombre>
<FechaAlta>1307542390468</FechaAlta>
</Producto>
</Productos>
</Pedido>
</Pedidos>
35
EJEMPLO PRÁCTICO
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
public PedidosXML_DOM() {
dom = null;
}
private void addCliente(Usuario cliente, Element nodoCliente) {
Element nombre = dom.createElement("Nombre");
Text textoNombre =
dom.createTextNode(cliente.getNombre());
nombre.appendChild(textoNombre);
36
Element apellido = dom.createElement("Apellido");
Text textoApellido =
dom.createTextNode(cliente.getApellido());
apellido.appendChild(textoApellido);
nodoCliente.appendChild(nombre);
nodoCliente.appendChild(apellido);
nodoCliente.appendChild(user);
}
private void addProducto(Producto producto, Element nodoProducto) {
Element nombre = dom.createElement("Nombre");
Text textoNombre =
dom.createTextNode(producto.getNombre());
nombre.appendChild(textoNombre);
nodoProducto.appendChild(nombre);
nodoProducto.appendChild(fechaAlta);
}
37
// Se crea un nuevo elemento para el cliente
Element cliente = dom.createElement("Cliente");
addCliente(pedido.getCliente(), cliente);
/*
* Transforma el árbol, agregando la cabecera y añadiendo
sangrados
*/
private void toFile(String ruta) {
try {
// Se vuelca el XML al fichero
TransformerFactory transFact =
TransformerFactory.newInstance();
// Se añade el sangrado
transFact.setAttribute("indent-number",
new
Integer(3));
38
Transformer trans =
transFact.newTransformer();
// Se incluye la cabecera XML y el sangrado
trans.setOutputProperty(
OutputKeys.OMIT_XML_DECLARATION, "no");
trans.setOutputProperty(OutputKeys.INDENT,
"yes");
// Se hace la transformación
StringWriter sw = new StringWriter();
StreamResult sr = new StreamResult(sw);
DOMSource domSource = new DOMSource(dom);
trans.transform(domSource, sr);
// Se escribe en el fichero
write(sw, ruta);
} catch(Exception ex) {
ex.printStackTrace();
}
}
/*
* Se crea un fichero XML a partir de una lista de pedidos
*/
newDocumentBuilder().newDocument();
Element root = dom.createElement("Pedidos");
dom.appendChild(root);
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
39
Element elementoUsuario = (Element)nodoUsuario;
String nombre = elementoUsuario.
getElementsByTagName("Nombre").item(0).getTextContent();
String apellido = elementoUsuario.
getElementsByTagName("Apellido").item(0).getTextContent();
String user = elementoUsuario.
getElementsByTagName("User").item(0).getTextContent();
getElementsByTagName("Nombre").item(0).getTextContent();
long fechaAlta = Long.valueOf(elementoProducto.
getElementsByTagName("FechaAlta").item(0).getTextContent());
elementoPedido.getAttribute("numeroPedido"));
Usuario user = readUsuario(elementoPedido.
getElementsByTagName("Cliente").item(0));
Pedido pedido = new Pedido(numeroPedido, user);
getElementsByTagName("Productos");
for(int i = 0; i < productos.getLength(); i++) {
pedido.addProducto(readProducto
((Element)productos.item(0)));
}
return pedido;
}
40
/*
* Se crea una lista de pedidos procesando un fichero XML
*/
public ArrayList<Pedido> XMLtoPedidos(String ruta) {
ArrayList<Pedido> pedidos = new ArrayList<Pedido>();
try {
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db =
dbf.newDocumentBuilder();
dom = db.parse(new File(ruta));
dom.getDocumentElement().normalize();
getElementsByTagName("Pedido");
for(int i = 0; i <
listaPedidos.getLength(); i++) {
pedidos.add(readPedido(listaPedidos.item(i)));
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
return pedidos;
}
}
5.2 SAX
Al contrario que con DOM, al procesar en SAX no se va a tener la
representación completa del árbol en memoria, pues SAX funciona con
eventos. Esto implica:
41
- La modificación de un nodo es mucho más compleja (y la
inserción de nuevos nodos).
- Como no se tiene el árbol en memoria es mucho más memory
friendly, de modo que es la única opción viable para casos de
ficheros muy grandes, pero demasiado complejo para ficheros
pequeños.
- Al ser orientado a eventos, el procesado se vuelve bastante
complejo.
Para poder procesar un fichero XML con SAX la clase lectora va a necesitar
heredar de la clase DefaultHandler (se recuerda que, como buena práctica
de programación, los datos deben estar separados de la entrada/salida).
Además, se va a necesitar un objeto de la clase XMLReader, el cual va a usar
la propia clase como ContentHandler y ErrorHandler. El esqueleto de la
clase entonces sería algo así:
Se ha dicho que SAX funciona por eventos. Pero ¿qué eventos son esos?
43
A partir de esto se podría, en lugar de escribir por pantalla los valores,
procesarlos y crear atributos de objetos de clases que se hayan definido.
ARTÍCULO DE INTERÉS
EJEMPLO PRÁCTICO
Se ve un ejemplo completo.
Archivo XML:
44
<Pedidos>
<Pedido numeroPedido="1">
<Cliente>
<Nombre>Thomas</Nombre>
<Apellido>Anderson</Apellido>
<User>Neo</User>
</Cliente>
<Productos>
<Producto>
<Nombre>Matrix 7.0</Nombre>
<FechaAlta>1307542390468</FechaAlta>
</Producto>
<Producto>
<Nombre>Gravedad 2.0</Nombre>
<FechaAlta>1307542390468</FechaAlta>
</Producto>
</Productos>
</Pedido>
<Pedido numeroPedido="2">
<Cliente>
<Nombre>Mr.</Nombre>
<Apellido>Regan</Apellido>
<User>Cifra</User>
</Cliente>
<Productos>
<Producto>
<Nombre>Reinsercion 1.0</Nombre>
<FechaAlta>1307542390468</FechaAlta>
</Producto>
</Productos>
</Pedido>
</Pedidos>
EJEMPLO PRÁCTICO
import java.io.IOException;
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
45
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public PedidosXML_SAX() {
try {
reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(this);
reader.setErrorHandler(this);
} catch (SAXException e) {
e.printStackTrace();
}
}
public ArrayList<Pedido> XMLtoPedidos(String ruta) {
ArrayList<Pedido> pedidos = new ArrayList<Pedido>();
try {
reader.parse(ruta);
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
return pedidos;
}
@Override
public void startElement(String uri, String localName, String name,
Attributes
atts) {
System.out.println("<" + localName + ">");
}
@Override
public void characters(char[] cadena, int inicio, int length) {
if(String.valueOf(cadena, inicio, length).trim().length() !=
0)
System.out.println(String.valueOf(cadena, inicio,
length));
}
@Override
public void endElement(String uri, String name, String qName) {
System.out.println("</" + name +">");
}
}
46
6. LISTAS
Una lista es una estructura de datos lineal que se puede representar
simbólicamente como un conjunto de nodos enlazados entre sí.
Las listas permiten modelar diversas entidades del mundo real como, por
ejemplo, los datos de los alumnos de un grupo académico, los datos del
personal de una empresa, los programas informáticos almacenados en un
disco magnético, etc.
ENLACE DE INTERÉS
47
o Listas densas. Cuando la estructura que contiene la lista es la
que determina la posición del siguiente elemento. La
localización de un elemento de la lista es la siguiente:
▪ Está en la posición 1 si no existe elemento anterior.
▪ Está en la posición N si la localización del elemento
anterior es la posición (N-1).
o Listas enlazadas: La localización de un elemento es:
▪ Estará en la dirección k, si es el primer elemento, siendo
k conocido.
▪ Si no es el primer elemento de la lista, estará en una
dirección, j, que está contenida en el elemento anterior.
• Por la información utilizada para acceder a sus elementos:
o Listas ordinales. La posición de los elementos en la
estructura la determina su orden de llegada.
o Listas calificadas. Se accede a un elemento por un valor que
coincide con el de un determinado campo, conocido como
clave. Este tipo de listas se pueden clasificar a su vez en
ordenadas o no ordenadas por el campo clave.
ENLACE DE INTERÉS
• Código de programación
48
Imagen: Implementación de una lista densa mediante una estructura estática
(matriz)
49
VIDEO DE INTERÉS
50
6.2 Tratamiento de listas en java
Para la utilización de listas es necesario definir la clase NodoLista utilizando
la siguiente sintaxis:
51
En el siguiente método estático (escribirLista), se recorre una lista
(nodoLista) mostrando en la pantalla el contenido de sus campos clave. Se
utiliza un método de llamada (escribirListaCompleta), que recibe como
argumento un objeto de la clase Lista (lista):
lista1: 10 13 21 FIN.
52
- En la tercera, nodoLista es el contenido del campo sig del nodo de
clave 21, es decir, null. Cuando se ejecuta esta tercera llamada se
cumple la condición de finalización y, en consecuencia, se inicia el
proceso de “vuelta”. Ahora nodoLista toma sucesivamente los
valores:
- Referencia al nodo de clave 21 (campo sig del nodo de clave 13).
- Referencia al nodo de clave 13 (campo sig del nodo de clave 10).
- Referencia al nodo de clave 10 (el primer elemento de la lista).
ENLACE DE INTERÉS
6.4.1 Pilas
Una pila es una agrupación de elementos de determinada naturaleza o tipo
(datos de personas, números, procesos informáticos, automóviles, etc.)
entre los que existe definida una relación de orden (estructura de datos).
53
En función del tiempo, algunos elementos de dicha naturaleza pueden llegar
a la pila o salir de ella (operaciones / acciones). En consecuencia, el
estado de la pila varía.
ENLACE DE INTERÉS
54
Y la interfaz utilizada sería la siguiente:
55
6.4.2 Colas
Una cola es una agrupación de elementos de determinada naturaleza o tipo
(datos de personas, números, procesos informáticos, automóviles, etc.)
entre los que existe definida una relación de orden. En función del tiempo,
pueden llegar a la cola o salir de ella algunos elementos de dicha naturaleza
(operaciones/acciones). En consecuencia, el estado de la cola varía.
ENLACE DE INTERÉS
57
Y la interfaz utilizada sería:
58
RESUMEN FINAL
59