Listado completo de tutoriales
73 - Colecciones: LinkedList |
La clase LinkedList implementa la lógica para trabajar con listas genéricas, es decir podemos insertar y extraer elementos de cualquier parte de la lista.
Confeccionaremos un programa para llamar los principales métodos de esta clase.
import java.util.LinkedList; public class PruebaLinkedList { public static void imprimir(LinkedList<String> lista) { for (String elemento : lista) System.out.print(elemento + "-"); System.out.println(); } public static void main(String[] args) { LinkedList<String> lista1 = new LinkedList<String>(); lista1.add("juan"); lista1.add("Luis"); lista1.add("Carlos"); imprimir(lista1); lista1.add(1, "ana"); imprimir(lista1); lista1.remove(0); imprimir(lista1); lista1.remove("Carlos"); imprimir(lista1); System.out.println("Cantidad de elementos en la lista:" + lista1.size()); if (lista1.contains("ana")) System.out.println("El nombre 'ana' si esta almacenado en la lista"); else System.out.println("El nombre 'ana' no esta almacenado en la lista"); System.out.println("El segundo elemento de la lista es:" + lista1.get(1)); lista1.clear(); if (lista1.isEmpty()) System.out.println("La lista se encuentra vacía"); } }
Para trabajar con listas genéricas debemos importar la clase LinkedList:
import java.util.LinkedList;
Creamos un objeto de la clase LinkedList:
LinkedList<String> lista1 = new LinkedList<String>();
La lista administra objetos de la clase String, luego mediante el método 'add' añadimos al final nodos:
lista1.add("juan"); lista1.add("Luis"); lista1.add("Carlos");
Llamamos al método estático 'imprimir' para mostrar todos los elementos de la lista:
imprimir(lista1);
El método estático recibe la lista y mediante un for recorre la colección mostrando sus elementos:
public static void imprimir(LinkedList<String> lista) { for (String elemento : lista) System.out.print(elemento + "-"); System.out.println(); }
El método 'add' de la clase LinkedList se encuentra sobrecargado, hay un segundo método 'add' con dos parámetros que recibe en el primer parámetro la posición donde se debe insertar el nodo y como segundo parámetro el dato a almacenar:
lista1.add(1, "ana");
Para eliminar un nodo de la lista debemos llamar al método 'remove' y pasar la posición del nodo a eliminar:
lista1.remove(0);
También podemos eliminar los nodos que coinciden con cierta información:
lista1.remove("Carlos");
La cantidad de nodos nos lo suministra el método 'size':
System.out.println("Cantidad de elementos en la lista:" + lista1.size());
Para conocer si la lista almacena cierto valor disponemos del método 'contains':
if (lista1.contains("ana")) System.out.println("El nombre 'ana' si esta almacenado en la lista"); else System.out.println("El nombre 'ana' no esta almacenado en la lista");
Para recuperar el dato de un nodo sin eliminarlo podemos hace uso del método 'get':
System.out.println("El segundo elemento de la lista es:" + lista1.get(1));
Eliminamos todos los nodos de la lista mediante el método 'clear':
lista1.clear();
Podemos consultar si la lista se encuentra vacía mediante el método 'isEmpty':
if (lista1.isEmpty()) System.out.println("La lista se encuentra vacía");
Más datos podemos conseguir visitando la documentación oficial de la clase LinkedList.
Confeccionar el juego de la serpiente (snake) utilizando un objeto de la clase LinkedList para representar cada trozo de la misma.
import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.LinkedList; import javax.swing.JFrame; public class Vibora extends JFrame implements Runnable, KeyListener { private LinkedList<Punto> lista = new LinkedList<Punto>(); private int columna, fila; // columna y fila donde se encuentra la cabeza de la vibora private int colfruta, filfruta; // columna y fila donde se encuentra la fruta private boolean activo = true; // disponemos en false cuando finaliza el juego private Direccion direccion = Direccion.DERECHA; private Thread hilo; // Hilo de nuestro programa private int crecimiento = 0; // indica la cantidad de cuadraditos que debe crecer la vibora private Image imagen; // Para evitar el parpadeo del repaint() private Graphics bufferGraphics;// Se dibuja en memoria para evitar parpadeo private enum Direccion { IZQUIERDA, DERECHA, SUBE, BAJA }; class Punto { int x, y; public Punto(int x, int y) { this.x = x; this.y = y; } } public Vibora() { // escuchamos los eventos de teclado para identificar cuando se presionan las // teclas de flechas this.addKeyListener(this); // la vibora comienza con cuatro cuadraditos lista.add(new Punto(4, 25)); lista.add(new Punto(3, 25)); lista.add(new Punto(2, 25)); lista.add(new Punto(1, 25)); // indicamos la ubicacion de la cabeza de la vibora columna = 4; fila = 25; // generamos la coordenada de la fruta colfruta = (int) (Math.random() * 50); filfruta = (int) (Math.random() * 50); // creamos el hilo y lo arrancamos (con esto se ejecuta el metodo run() hilo = new Thread(this); hilo.start(); } @Override public void run() { while (activo) { try { // dormimos el hilo durante una décima de segundo para que no se mueva tan // rapidamente la vibora Thread.sleep(100); // segun el valor de la variable direccion generamos la nueva posicion de la // cabeza de la vibora switch (direccion) { case DERECHA: columna++; break; case IZQUIERDA: columna--; break; case SUBE: fila--; break; case BAJA: fila++; break; } repaint(); sePisa(); // insertamos la coordenada de la cabeza de la vibora en la lista lista.addFirst(new Punto(columna, fila)); if (this.verificarComeFruta() == false && this.crecimiento == 0) { // si no estamos en la coordenada de la fruta y no debe crecer la vibora // borramos el ultimo nodo de la lista // esto hace que la lista siga teniendo la misma cantidad de nodos // ls.borrarUltimo(); lista.remove(lista.size() - 1); } else { // Si creciento es mayor a cero es que debemos hacer crecer la vibora if (this.crecimiento > 0) this.crecimiento--; } verificarFin(); } catch (InterruptedException e) { e.printStackTrace(); } } } // controlamos si la cabeza de la vibora se encuentra dentro de su cuerpo private void sePisa() { for (Punto p : lista) { if (p.x == columna && p.y == fila) { activo = false; setTitle("Perdiste"); } } } // controlamos si estamos fuera de la region del tablero private void verificarFin() { if (columna < 0 || columna >= 50 || fila < 0 || fila >= 50) { activo = false; setTitle("Perdiste"); } } private boolean verificarComeFruta() { if (columna == colfruta && fila == filfruta) { colfruta = (int) (Math.random() * 50); filfruta = (int) (Math.random() * 50); this.crecimiento = 10; return true; } else return false; } public void paint(Graphics g) { super.paint(g); if (!lista.isEmpty()) { if (imagen == null) { imagen = createImage(this.getSize().width, this.getSize().height); bufferGraphics = imagen.getGraphics(); } // borramos la imagen de memoria bufferGraphics.clearRect(0, 0, getSize().width, getSize().width); // dibujar recuadro bufferGraphics.setColor(Color.red); bufferGraphics.drawRect(20, 50, 500, 500); // dibujar vibora for (Punto punto : lista) { bufferGraphics.fillRect(punto.x * 10 + 20, 50 + punto.y * 10, 8, 8); } // dibujar fruta bufferGraphics.setColor(Color.blue); bufferGraphics.fillRect(colfruta * 10 + 20, filfruta * 10 + 50, 8, 8); g.drawImage(imagen, 0, 0, this); } } public void keyPressed(KeyEvent arg0) { if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) { direccion = Direccion.DERECHA; } if (arg0.getKeyCode() == KeyEvent.VK_LEFT) { direccion = Direccion.IZQUIERDA; } if (arg0.getKeyCode() == KeyEvent.VK_UP) { direccion = Direccion.SUBE; } if (arg0.getKeyCode() == KeyEvent.VK_DOWN) { direccion = Direccion.BAJA; } } public void keyReleased(KeyEvent arg0) { } public void keyTyped(KeyEvent arg0) { } public static void main(String[] args) { Vibora f = new Vibora(); f.setSize(600, 600); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
Cuando lo ejecutemos tendremos un resultado similar a esto: