Comience con el marco de colecciones de Java

JDK 1.2 introduce un nuevo marco para colecciones de objetos, llamado Java Collections Framework. "Oh, no", te quejas, "¡ni otra API, ni otro marco para aprender!" Pero espere, antes de que se aleje, escúcheme: el marco de Colecciones vale su esfuerzo y beneficiará su programación de muchas maneras. Inmediatamente me vienen a la mente tres grandes beneficios:

  • Aumenta drásticamente la legibilidad de sus colecciones al proporcionar un conjunto estándar de interfaces para ser utilizado por muchos programadores en muchas aplicaciones.
  • Hace que su código sea más flexible al permitirle pasar y devolver interfaces en lugar de clases concretas, generalizando su código en lugar de bloquearlo.
  • Ofrece muchas implementaciones específicas de las interfaces, lo que le permite elegir la colección que más se ajusta y ofrece el mayor rendimiento para sus necesidades.

Y eso es solo para empezar.

Nuestro recorrido por el marco comenzará con una descripción general de las ventajas que ofrece para almacenar conjuntos de objetos. Como pronto descubrirá, debido a que sus viejos amigos caballos de batalla Hashtabley Vectoradmiten la nueva API, sus programas serán uniformes y concisos, algo que sin duda alegrará a usted y a los desarrolladores que acceden a su código.

Después de nuestra discusión preliminar, profundizaremos en los detalles.

La ventaja de las colecciones de Java: una descripción general

Antes de que Colecciones hiciera su debut más bienvenido, los métodos estándar para agrupar objetos Java eran a través de la matriz, el Vectory el Hashtable. Las tres colecciones tienen diferentes métodos y sintaxis para acceder a los miembros: las matrices usan los símbolos de corchetes ([]), Vectorusan el elementAtmétodo y Hashtableusan gety putmétodos. Estas diferencias han llevado a los programadores por el camino de la inconsistencia en la implementación de sus propias colecciones: algunos emulan los Vectormétodos de acceso y otros emulan la Enumerationinterfaz.

Para complicar aún más las cosas, la mayoría de los Vectormétodos están marcados como definitivos; es decir, no puede extender la Vectorclase para implementar un tipo de colección similar. Podríamos crear una clase de colección que se pareciera a a Vectory actuara como a Vector, pero no se podría pasar a un método que toma a Vectorcomo parámetro.

Finalmente, ninguna de las colecciones (matriz Vectoro Hashtable) implementa una interfaz de acceso de miembros estándar. A medida que los programadores desarrollaban algoritmos (como géneros) para manipular colecciones, estalló un acalorado discurso sobre qué objeto pasar al algoritmo. ¿Deberías pasar una matriz o una Vector? ¿Debería implementar ambas interfaces? Hable de duplicación y confusión.

Afortunadamente, Java Collections Framework soluciona estos problemas y ofrece una serie de ventajas sobre el uso de ningún marco o el uso de Vectory Hashtable:

  • Un conjunto utilizable de interfaces de colección

    Mediante la implementación de una de las interfaces básicas - Collection, Set, List, o Map- a garantizar que su clase se ajusta a una API común y se hace más regular y de fácil comprensión. Entonces, ya sea que esté implementando una base de datos SQL, un comparador de muestras de color o una aplicación de chat remota, si implementa la Collectioninterfaz, sus usuarios conocen bien las operaciones en su colección de objetos. Las interfaces estándar también simplifican el paso y la devolución de colecciones hacia y desde métodos de clase y permiten que los métodos funcionen en una variedad más amplia de colecciones.

  • Un conjunto básico de implementaciones de colecciones

    Además de los confiables Hashtabley Vector, que se han actualizado para implementar las Collectioninterfaces, se han agregado nuevas implementaciones de colección, que incluyen HashSety TreeSet, ArrayListy LinkedList, y HashMapy Map. El uso de una implementación común existente hace que su código sea más corto y más rápido de descargar. Además, el uso del núcleo de código Core Java existente garantiza que cualquier mejora en el código base también mejorará el rendimiento de su código.

  • Otras mejoras útiles

    Cada colección ahora devuelve un Iteratortipo mejorado de Enumerationque permite operaciones de elementos como inserción y eliminación. El Iteratores "a prueba de rápido", que significa que tienes una excepción si la lista que estás iteración se cambia por otro usuario. Además, las colecciones basadas en listas, como Vectorreturn a, ListIteratorpermiten la iteración y actualización bidireccional.

    Varias colecciones ( TreeSety TreeMap) apoyan implícitamente los pedidos. Utilice estas clases para mantener una lista ordenada sin esfuerzo. Puede encontrar los elementos más pequeños y más grandes o realizar una búsqueda binaria para mejorar el rendimiento de listas grandes. Puede ordenar otras colecciones proporcionando un método de comparación de colecciones (un Comparatorobjeto) o un método de comparación de objetos (la Comparableinterfaz).

    Por último, una clase estática Collectionsproporciona versiones no modificables (solo lectura) y sincronizadas de colecciones existentes. Las clases no modificables son útiles para evitar cambios no deseados en una colección. La versión sincronizada de una colección es una necesidad para los programas multiproceso.

Java Collections Framework es parte de Core Java y está incluido en el java.util.collectionspaquete de JDK 1.2. El marco también está disponible como paquete para JDK 1.1 (ver Recursos).

Nota: Se nombra la versión de colecciones JDK 1.1 com.sun.java.util.collections. Tenga en cuenta que el código desarrollado con la versión 1.1 debe actualizarse y recompilarse para la versión 1.2, y los objetos serializados en 1.1 no se pueden deserializar en 1.2.

Veamos ahora más de cerca estas ventajas ejercitando el marco de colecciones de Java con algún código propio.

Una buena API

La primera ventaja de Java Collections Framework es una API regular y consistente. La API está codificada en un conjunto básico de interfaces, Collection, Set, List, o Map. La Collectioninterfaz contiene operaciones básicas de recopilación, como agregar, eliminar y probar la pertenencia (contención). Cualquier implementación de una colección, ya sea una proporcionada por Java Collections Framework o una de sus propias creaciones, admitirá una de estas interfaces. Debido a que el marco de Colecciones es regular y consistente, aprenderá una gran parte de los marcos simplemente aprendiendo estas interfaces.

Ambos Sete Listimplementar la Collectioninterfaz. La Setinterfaz es idéntica a la Collectioninterfaz excepto por un método adicional toArray, que convierte Seta en una Objectmatriz. La Listinterfaz también implementa la Collectioninterfaz, pero proporciona muchos accesos que usan un índice entero en la lista. Por ejemplo, get, remove, y settodos tomar un número entero que afecta al elemento de indexado de la lista. La Mapinterfaz no se deriva de la colección, pero proporciona una interfaz similar a los métodos de java.util.Hashtable. Las claves se utilizan para poner y obtener valores. Cada una de estas interfaces se describe en los siguientes ejemplos de código.

El siguiente segmento de código demuestra cómo realizar muchas Collectionoperaciones en HashSetuna colección básica que implementa la Setinterfaz. A HashSetes simplemente un conjunto que no permite elementos duplicados y no ordena ni coloca sus elementos. El código muestra cómo crear una colección básica y agregar, eliminar y probar elementos. Como Vectorahora admite la Collectioninterfaz, también puede ejecutar este código en un vector, que puede probar cambiando la HashSetdeclaración y el constructor a Vector.

importar java.util.collections. *; public class CollectionTest {// Estática public static void main (String [] args) {System.out.println ("Collection Test"); // Crea una colección HashSet collection = new HashSet (); // Añadiendo String dog1 = "Max", dog2 = "Bailey", dog3 = "Harriet"; colección.add (perro1); collection.add (perro2); colección.add (perro3); // Dimensionamiento System.out.println ("Colección creada" + ", size =" + collection.size () + ", isEmpty =" + collection.isEmpty ()); // Containment System.out.println ("La colección contiene" + dog3 + ":" + colección.contains (dog3)); // Iteración. El iterador admite hasNext, luego, elimina System.out.println ("Iteración de la colección (sin clasificar):"); Iterador iterador = colección.iterador (); while (iterador.hasNext ()) System.out.println ("" + iterator.next ()); // Eliminando collection.remove (dog1); colección.clear (); }}

Construyamos ahora sobre nuestro conocimiento básico de colecciones y veamos otras interfaces e implementaciones en Java Collections Framework.

Buenas implementaciones concretas

Hemos ejercido la Collectioninterfaz en una colección concreta, el HashSet. Veamos ahora el conjunto completo de implementaciones de colecciones concretas proporcionadas en el marco de colecciones de Java. (Consulte la sección Recursos para obtener un enlace al esquema anotado de Sun del marco de las colecciones de Java).

Implementaciones
Tabla de picadillo Matriz de tamaño variable Árbol equilibrado (ordenado) Lista enlazada Legado
Interfaces Conjunto HashSet * TreeSet * *
Lista * Lista de arreglo * Lista enlazada Vector
Mapa HashMap * TreeMap * Tabla de picadillo

Implementations marked with an asterix (*) make no sense or provide no compelling reason to implement. For instance, providing a List interface to a Hash Table makes no sense because there is no notion of order in a Hash Table. Similarly, there is no Map interface for a Linked List because a list has no notion of table lookup.

Let's now exercise the List interface by operating on concrete implementations that implement the List interface, the ArrayList, and the LinkedList. The code below is similar to the previous example, but it performs many List operations.

import java.util.collections.*; public class ListTest { // Statics public static void main( String [] args ) { System.out.println( "List Test" ); // Create a collection ArrayList list = new ArrayList(); // Adding String [] toys = { "Shoe", "Ball", "Frisbee" }; list.addAll( Arrays.toList( toys ) ); // Sizing System.out.println( "List created" + ", size=" + list.size() + ", isEmpty=" + list.isEmpty() ); // Iteration using indexes. System.out.println( "List iteration (unsorted):" ); for ( int i = 0; i < list.size(); i++ ) System.out.println( " " + list.get( i ) ); // Reverse Iteration using ListIterator System.out.println( "List iteration (reverse):" ); ListIterator iterator = list.listIterator( list.size() ); while ( iterator.hasPrevious() ) System.out.println( " " + iterator.previous() ); // Removing list.remove( 0 ); list.clear(); } } 

As with the first example, it's simple to swap out one implementation for another. You can use a LinkedList instead of an ArrayList simply by changing the line with the ArrayList constructor. Similarly, you can use a Vector, which now supports the List interface.

When deciding between these two implementations, you should consider whether the list is volatile (grows and shrinks often) and whether access is random or ordered. My own tests have shown that the ArrayList generally outperforms the LinkedList and the new Vector.

Notice how we add elements to the list: we use the addAll method and the static method Arrays.toList. This static method is one of the most useful utility methods in the Collections framework because it allows any array to be viewed as a List. Now an array may be used anywhere a Collection is needed.

Notice that I iterate through the list via an indexed accessor, get, and the ListIterator class. In addition to reverse iteration, the ListIterator class allows you to add, remove, and set any element in the list at the point addressed by the ListIterator. This approach is quite useful for filtering or updating a list on an element-by-element basis.

La última interfaz básica en Java Collections Framework es Map. Esta interfaz se implementa con dos nuevas implementaciones concretas, el TreeMapy el HashMap. El TreeMapes una aplicación árbol equilibrado que ordena los elementos de la llave.

Ilustremos el uso de la Mapinterfaz con un ejemplo simple que muestra cómo agregar, consultar y borrar una colección. Este ejemplo, que usa la HashMapclase, no es muy diferente de cómo usamos el Hashtableantes del debut del marco de Colecciones. Ahora, con la actualización de Hashtablepara admitir la Mapinterfaz, puede cambiar la línea que crea HashMapuna instancia de y reemplazarla con una instancia de Hashtable.