Clase Vector

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 15

CLASE VECTOR

Vamos a continuar el estudio de la interface List del api de Java, pero esta vez nos centraremos en la implementación de
esta interface a través de la clase Vector. También veremos las características más importantes de esta nueva
implementación y haremos un ejemplo a modo de ejercicio. 

VECTOR

La clase Vector, al igual que ArrayList o LinkedList, también implementa a List, pero de un modo especial. Este modo
especial es sincronizado, lo que permite que se pueda usar en entornos concurrentes (es decir, en varios procesos que
se ejecutan al mismo tiempo y hacen uso posiblemente de los mismos recursos). Esta además es la principal
característica que la diferencia de otras clases estudiadas anteriormente como ArrayList.

Se recomienda que si no es necesario se use ArrayList en vez de Vector. Por tanto, solo utilizaremos la clase Vector si
tenemos previstas circunstancias especiales como procesos concurrentes.

Vamos a ver las principales características de esta clase, que además es muy parecida a ArrayList.

Un objeto de tipo Vector contiene elementos que pueden ser accedidos por un índice y puede aumentar o disminuir su
tamaño dinámicamente en tiempo de ejecución. 

EJEMPLO USO CLASE VECTOR

Vamos a realizar un ejemplo de uso sobre la clase Vector, donde añadiremos elementos, eliminaremos elementos y
consultaremos la capacidad del vector. Para ello también usaremos la clase Persona que hemos venido utilizando en
ocasiones anteriores durante el curso:

/* Ejemplo Interface List, clase Vector aprenderaprogramar.com */

public class Persona{

    private int idPersona;     private String nombre;     private int altura;

    public Persona(int idPersona, String nombre, int altura) {

        this.idPersona = idPersona;         this.nombre = nombre;         this.altura = altura;}

    @Override

    public String toString() {

        return "Persona-> ID: "+idPersona+" Nombre: "+nombre+" Altura: "+altura+"\n";

    }

Vamos a escribir ahora el siguiente código con el que vamos a trabajar:


/* Ejemplo Interface List, clase Vector aprenderaprogramar.com */

import java.util.Vector;

public class Programa {

    public static void main(String arg[]) {

            Vector<Persona> v = new Vector<Persona>();

            System.out.println("La capacidad inicial del vector es: "+v.capacity());

            int i = 0;

            while (i<15) {

                v.add(new Persona(i,"Persona"+i,i));

                i++;           }

            System.out.println("La capacidad actual del vector es: "+v.capacity());

            v.trimToSize();

            System.out.println("La capacidad actual del vector es: "+v.capacity());

            v.ensureCapacity(50);

            System.out.println("La capacidad actual del vector es: "+v.capacity());

      } 

Como podemos observar en el código, hemos creado una variable v de la clase Vector<Persona> sobre la que
consultamos sus capacidades en distintos momentos (antes de insertar elementos en el vector, y tras realizar
inserciones o cambios). Hemos utilizado algunos métodos que comentaremos ahora. 

La salida que obtendremos por consola será similar a esta:

Como hemos visto la capacidad inicial cuando creamos un nuevo vector es 10 (capacidad que asigna Java por defecto si
no se especifica otra), y el incremento definido en caso de ampliación del vector es 0. El incremento en caso de
ampliación establece cómo se aumentará el tamaño del vector en caso de que su capacidad vaya a ser excedida al
incrementarse el número de elementos en él y podemos establecerlo en 10, 20, 50, etc. elementos (los que nosotros
queramos). Tanto la capacidad inicial como el incremento definido pueden establecerse usando constructores
especiales que incluyen estos parámetros. En caso de no usar estos constructores, Java utiliza valores por defecto. El
valor por defecto 0 para el incremento significa que si se necesita ampliar la capacidad lo que se hace por defecto es
duplicar la capacidad del vector.

En nuestro ejemplo el vector se crea con capacidad inicial por defecto 10. Después añadimos 15 elementos dentro del
bucle while. Una vez se completa la capacidad inicial, para añadir el elemento 11 el vector necesita ampliar su capacidad
y como el incremento de capacidad está fijado por defecto como 0, entonces se duplica su capacidad a 20.

Posteriormente hacemos uso del método de la clase trimToSize(); este método lo que hace es ajustar la capacidad del
vector al tamaño real que tiene en ese momento. Por tanto su capacidad nuevamente se ve alterada hasta el valor 15.

Finalmente utilizamos el método ensureCapacity(50); este método permite ampliar la capacidad hasta un valor
determinado para asegurarnos de que el vector tendrá capacidad suficiente y hacer reserva de memoria hasta un
número dado de elementos, en nuestro ejemplo 50 elementos.

Recordar que si quisiéramos una determinada capacidad inicial y un determinado incremento por defecto nos bastaría
con crear el vector pasando los parámetros de forma adecuada en el constructor. Puedes consultar los constructores
disponibles en la documentación de la clase.

CLASE STACK

A continuación vamos a explicar la clase Stack de Java, que implementa la interface List. Stack se traduce por “pila” y
para recordar su significado podemos pensar en una pila de libros. También veremos las características más importantes
de esta nueva implementación y haremos un ejemplo a modo de ejercicio.

STACK

La clase Stack es una clase de las llamadas de tipo LIFO (Last In - First Out, o último en entrar - primero en salir). Esta
clase hereda de la clase que ya hemos estudiado anteriormente en el curso Vector y con 5 operaciones permite tratar un
vector a modo de pila o stack.

Las operaciones básicas son push (que introduce un elemento en la pila), pop (que saca un elemento de la


pila), peek (consulta el primer elemento de la cima de la pila), empty (que comprueba si la pila está vacía) y search (que
busca un determinado elemento dentro de la pila y devuelve su posición dentro de ella).

Esta clase es muy sencilla y al crear un objeto de tipo Stack con el constructor básico evidentemente no contendrá
ningún elemento.

Un conjunto mucho más completo y consistente para operaciones de stack LIFO es proporcionado en la interface Deque
y sus implementaciones, pero nosotros de momento vamos a limitarnos al estudio de la clase Stack.

EJEMPLO USO CLASE STACK

Realizaremos un ejemplo a modo de uso de pila. Uno de los casos más usados en informática de una pila es el de querer
verificar si una determinada sentencia o instrucción está equilibrada en cuanto a número de paréntesis, corchetes o
llaves de apertura y cierre. Cuando se escribe código de programación si no existe equilibrio entre signos de apertura
(por ejemplo un paréntesis de apertura) y cierre (por ejemplo un paréntesis de cierre) ni siquiera debería procesarse la
sentencia ya que no estaría formalmente bien construida. De esto se encargan los analizadores léxicos de los
compiladores.

Así que vamos a utilizar esta vez tan solo una clase Programa con el método main, donde vamos a ir analizando una
sentencia para verificar si es equilibrada o no en símbolos de paréntesis, recorriendo todos sus caracteres desde el inicio
hasta el final.

Iremos construyendo nuestra pila apilando un símbolo (cada vez que detectemos un símbolo de apertura o desapilando
de ella cuando detectemos un símbolo de cierre. Tendremos que ir analizando todos los caracteres de una expresión y
actuar cuando detectemos un paréntesis, operando en función de si el paréntesis leído es de abrir (“(”) o cerrar (“)”). El
equilibrio en la escritura vendrá determinado al terminar el análisis en función de si la pila está vacía (hay equilibrio) o
contiene algún elemento (no hay equilibrio).

Ejemplo: analizamos la expresión “Hay varios países (México, España) que comparten el mismo idioma (español o
castellano).”

El resultado al finalizar el análisis de la sentencia sería que la pila está vacía, y esto querrá decir que nuestra sentencia es
equilibrada en paréntesis y por tanto el resultado es correcto.

Si analizáramos la expresión “Hay varios países (México, España) que comparten el mismo idioma (español o castellano.”

El resultado al finalizar el análisis será que la pila contiene un paréntesis, lo que quiere decir que la expresión no es
equilibrada y no tiene el mismo número de paréntesis abiertos que cerrados.

Tendremos que tener en cuenta casos especiales como una expresión cuyo primer elemento sea un paréntesis de cierre.
Por ejemplo: “Hay varios países )México, España(“ la consideraríamos una expresión incorrecta ya que si la pila está
vacía el primer elemento siempre tendrá que ser un paréntesis de apertura y no uno de cierre. Tendremos en cuenta
por tanto que además de equilibrio exista corrección en la forma de construcción (que no puedan existir cierres de
paréntesis que no se hayan abierto).

Vamos a escribir ahora el siguiente código con el que vamos a trabajar:

/* Ejemplo Interface List, clase Stack aprenderaprogramar.com */

import java.util.Stack;

public class Programa {

    public static void main(String arg[]) {

            String cadenano = "(Cadena no equilibrada en paréntesis(()()()))))";

            String cadenasi = "(Cadena equilibrada en parentesis())";

            System.out.println("Verificación equilibrado en paréntesis para cadenano:");

            System.out.println(verificaParentesis(cadenano));

            System.out.println("Verificación equilibrado en paréntesis para cadenasi:");

            System.out.println(verificaParentesis(cadenasi));

    }

 
    public static boolean verificaParentesis(String cadena)  {

        Stack<String> pila = new Stack<String>();       int i = 0;

            while (i<cadena.length()) {  // Recorremos la expresión carácter a carácter

                if(cadena.charAt(i)=='(') {pila.push("(");} // Si el paréntesis es de apertura apilamos siempre               

                else if  (cadena.charAt(i)==')') {  // Si el paréntesis es de cierre actuamos según el caso

                            if (!pila.empty()){ pila.pop(); } // Si la pila no está vacía desapilamos

                            else { pila.push(")"); break; } // La pila no puede empezar con un cierre, apilamos y salimos

                }

                i++;

            }

            if(pila.empty()){ return true; } else { return false; }

    }

En este ejemplo hemos creado la función verificaParentesis que nos devuelve un boolean indicando si dada una cadena,
esta está equilibrada y correcta en paréntesis. Para ello se hace uso internamente en este método de una pila o stack.
Así el programa principal main tan solo llama a esta función con una cadena de ejemplo (cadenano o cadenasi) para
verificar su equilibrado y corrección en paréntesis. 

La salida que obtendremos por consola será similar a esta:

CONCLUSIONES

Hemos visto un claro ejemplo del uso de la clase Stack que aunque muy sencilla, es muy útil ya que su implementación
es muy fácil de aprender con tan solo los 5 métodos comentados anteriormente (push, pop, peek, empty, search).
El concepto básico de una cola es uno que normalmente las personas encuentran facil de entender, ya que nos
encontramos con el a diario. Cuando necesitamos ir a un banco (bueno, excepto si eres lo suficientemente rico para
evitar hacer fila) necesitamos hacer una cola para poder ser atendidos. La persona que esta en frente de la cola sera la
primera en ser atendida en el momento que una de las cajas este abierta. Cuando una nueva persona entra al banco,
esta tiene que ir al final de la cola y esperar su turno, esto significa que una cola funciona bajo un sistema "primero que
llega, primero que sale" o por sus siglas en ingles FIFO (first in first out).

Existe mas de una manera para implementar una cola, la manera mas común es utilizando Listas Enlazadas, las mismas
que se utilizaran para implementar algunos de los ejemplos.

import java.util.LinkedList;

import java.util.Queue;

/**

* @author Silviu Stroe (latzro.com)

*/

public class Main {

public void queueExample() {

Queue queue = new LinkedList();

queue.add("item1");

queue.add("item2");

queue.offer("Item3");

queue.offer("Item4");

System.out.println("remove: " + queue.remove());

System.out.println("element: " + queue.element());

System.out.println("poll: " + queue.poll());

System.out.println("peek: " + queue.peek());

}
/**

* @param args the command line arguments

*/

public static void main(String[] args) {

new Main().queueExample();

La diferencia entre una lista y una cola es que en una lista es posible escoger un item y una posición especifica dentro de
la lista con la que trabajar. Mientras tanto, con una cola solo es posible tener acceso al "primero en la fila" (aunque esto
no debe ser confundido con con clases como "LinkedList", las cuales implementan tanto listas como colas en su interfaz).

En este ejemplo se utiliza la clase LinkedList que implementa una interfaz simple de cola, se añaden items a la cola
utilizando los métodos ADD() y OFFER(). La diferencia que existe entre ellos es que el método ADD() terminará botando
una excepción si es que existe un problema al añadir un item en la cola, mientras que el método OFFER() solo retornará
falso en caso de que exista el mismo problema. Cual de estos métodos usar depende de que sistema se desea
implementar.

El ejemplo también muestra como eliminar items de la cola utilizando los métodos REMOVE() y POLL(). Como los
métodos previamente mencionados para poder añadir items a la cola, uno de ellos retornará una excepción si algo sale
mal (en este caso, que no exista ningún item en la cola que se pueda eliminar), mientras que el otro solo retorna falso.

Exactamente el mismo proceso se aplica para los dos métodos que son utilizados para obtener el primer item que está
en la cola. A continuación se explica a mas detalle el código:

import java.util.LinkedList;

import java.util.Queue;

public class Main {

/**

* Metodo de ejemplo para una cola

*/

public void queueExample() {

Queue queue = new LinkedList();


//Usando el metodo ADD para anadir.

//Si algo sale mal se botara existira una excepcion.

queue.add("item1");

queue.add("item2");

//Usando el metodo OFFER para anadir.

//Si algo sale mal se retornara un nulo.

queue.offer("Item3");

queue.offer("Item4");

//Eliminar el primer elemento de la cola.

//Si la cola esta vacia una excepcion java.util.NoSuchElementException sera botada.

System.out.println("remove: " + queue.remove());

//Observar que elemento esta en el primer puesto de la fila sin eliminarlo.

//Si la cola esta vacia una excepcion java.util.NoSuchElementException sera botada.

System.out.println("element: " + queue.element());

//Eliminar el primer elemento de la cola.

//Si la cola esta vacia, solo se retorna un falso.

System.out.println("poll: " + queue.poll());

//Observar que elemento esta en el primer puesto de la fila sin eliminarlo.

//Si la cola esta vacia, solo se retorna un nulo.

System.out.println("peek: " + queue.peek());

public static void main(String[] args) {

new Main().queueExample();

}
A continuación se muestra el resultado que se obtiene después de compilar el código:

remove: item1

element: item2

poll: item2

peek: Item3

Queue

• Paquete:

java.util
• Declaración de clase:

public interface Queue<E> extends Collection<E>, Iterable<E>


• Interfaz Queue ordenada cosas por el orden en que van a ser procesados. Por defecto ordena como FIFO pero puede
ordenar de otras formas.

• Queue generalmento NO PERMITE NULOS pero alguna de sus implementaciones como LinkedList si que los permiten.

• Algunos métodos de Queue:

boolean add(E e)

// Añade si hay capacidad en el Queue.

// Si ha podido añadir devuelve true y

// si no devuelve una excepción

//RuntimeException.IllegalStateException.

E element()

// Recupera sin borrar la cabeza del Queue.

boolean offer(E e)

// Inserta el elemento especificado en el Queue

// si hay tamaño suficiente. Devuelve un booleano.

// como add

E peek()
// Recupera sin borrar la cabeza del Queue o

// devuelve null si el Queue está vacío.

E poll()

// Recupera y elimina la cabeza del Queue o

// devuelve null si el Queue está vacío.

E remove()

// Recupera y elimina la cabeza del Queue.


PriorityQueue

• Paquete:

java.util
• Declaración de clase:

public class PriorityQueue<E> extends AbstractQueue<E>

          implements Serializable
• Algún constructor de Queue:

PriorityQueue()

// Crea un PriorityQueue con una capacidad inicial de 11

//posiciones y ordena los elementos de forma natural.

PriorityQueue(int initialCapacity, Comparator<? super E> comparator)

// Crea un PriorityQueue con la capacidad inicial que le indiquemos

// y ordena de acuerdo al Comparator que le pasemos.  


• Ordena de forma natural (ascendente) o según un Comparator y ese orden representa su prioridad.

• Permite duplicados.

q.add(“A”);

q.add(“A”); // 2 elementos

• No permite nulos. Da error en tiempo de ejecución.

q.add(null); // error en ejecución

• PriorityQueue permite trabajar con primitivos y con Referencias.

• PriorityQueue permite trabajar con Comparator.

• Si utilizamos Comparator con primitivos internamente hara un AutoBoxing para poder usar el Comparator.
• Algunos métodos de PriorityQueue:

boolean remove(Object)

// Elimina un elemento de la PriorityQueue.

   pq.remove("A");

boolean add(e) y offer(e)

// Añaden un elemento.

   pq.add("A");

   pq.offer("A"); // dos A

E peek()

// Devuelve 1 elemento en función del orden y no elimina.

   String primero = pq.peek();

   //tememos los mismos elementos

E poll()

// Devuelve 1 elemento en función del orden y lo elimina.

   String primero = pq.poll();

   //hemos eliminado el 1º elemento

Iterator<E> iterator()

// NO ORDENADOS.

   java.util.Iterator i = pq.iterator();

Object[] toArray()

// Devuelve un Array con los elementos de PriorityQueue.

   String[] nums = pq.toArray();


• Ejemplo de uso de PriorityQueue

// NO OLVIDAR IMPORTAR UTIL!!

import java.util.*; 

public class C1{


public static void main(String[] args){

PriorityQueue<Integer> pq = new PriorityQueue<Integer>();

// Ordena de forma natural

Integer[] nums = {4,3,1,2};

//OFFER(E) añadir

for(Integer i:nums)pq.offer(i);

//SIZE()

System.out.println("size: " + pq.size());

// 4

//ITERATOR(), no orden.

Iterator it = pq.iterator();

while(it.hasNext())System.out.print(it.next() + " ");

// 1 2 3 4 

//ADD

pq.add(new Integer(1)); // permite duplicados

try{

pq.offer(null);

// Error ejecución, no permite nulos.

}catch(java.lang.NullPointerException e){

//RuntimeException.NullPointerException

System.out.println("\n Error, PriorityQueue no "+

" permite nulos!");


}

//ADD(E)

System.out.println("\n Añade 5 -> add(5) : " +

pq.add(new Integer(5)));

// true

//ELEMENT()

System.out.println("Devuelve el 1º elemento sin "+

" borrar -> element(): " + pq.element());

// 1

//PEEK()

System.out.println("Devuelve el 1º sin " +

" borrarlo -> peek(): " + pq.peek());

// 1

//POLL()

System.out.println("Devuelve el 1º y lo " +

" elimina -> poll(): " + pq.poll());

// 1

//REMOVE()

System.out.println("Devuelve el 1º elemento " +

" y lo elimina -> remove: " + pq.remove());

// 1

//SIZE()

System.out.println("size: " + pq.size());

// 4
// CONSTRUCTOR CON COMPARATOR

PriorityQueue<Integer> pqc =

new PriorityQueue<Integer>(8, new PQsort());

Integer[] vals = {9,6,7,8};

for(Integer i:vals) pqc.offer(i);

//ITERATOR(), no orden

Iterator<Integer> itc = pqc.iterator();

while(itc.hasNext())System.out.print(itc.next() + " ");

// 9 8 7 6

class PQsort implements Comparator<Integer> { 

// Sobreescribir compare:

//     public int compare(Ref a, Ref b){}

// Sobrecargar compare:

//     public int compare(primitivo a, primitivo b){}

public int compare(Integer one, Integer two) {

// Invertir orden

return two - one; // UnBoxing

}
}

También podría gustarte