Saltar al contenido

La API y las colecciones

Qué trae Java de fábrica y cómo está organizado: los paquetes de la API, el marco de colecciones con sus interfaces y sus clases, la construcción del proyecto con Maven y las herramientas y bibliotecas de terceros que acompañan a cualquier proyecto real.

La API de Java y sus paquetes

La API de Java es el conjunto de clases e interfaces que vienen con la plataforma, organizadas en paquetes. Saberse la API de memoria no tiene sentido; lo que se pregunta, y lo que de verdad hace falta para trabajar, es saber en qué paquete vive cada cosa, porque el nombre del paquete es el índice de la biblioteca.

PaqueteDe qué se ocupa
java.langEl núcleo del lenguaje. Está disponible siempre sin importar nada
java.netComunicaciones: sockets, direcciones y URL
java.sql y javax.sqlJDBC, el acceso a bases de datos relacionales a bajo nivel
java.textFormato y análisis de fechas, números y textos
java.utilEl cajón de utilidades: colecciones, fechas antiguas, aleatorios, lectura de entrada
java.util.logging, .jar, .zip, .regexRegistro de actividad, empaquetado, compresión y expresiones regulares
javax.xml.parsers, org.w3c.dom, org.xml.saxAnálisis de documentos XML
javax.jws y javax.xml.wsServicios web SOAP: anotaciones y publicación de puntos de acceso
java.io y java.nioFicheros y directorios. java.nio es la evolución posterior de java.io

Una advertencia de nomenclatura que se paga cara en el examen: el prefijo javax no significa «antiguo» ni «obsoleto». Los paquetes javax de la edición estándar, como javax.sql o javax.xml.parsers, siguen llamándose así. Lo que cambió de javax a jakarta fue únicamente la edición empresarial, y se explica más adelante.

java.lang es el único paquete que no hace falta importar: sus clases están disponibles siempre. Por eso se puede escribir String, Object o System sin declarar nada al principio del fichero.

Para el examen

  • java.lang: el único paquete que no hay que importar

  • java.util: colecciones y utilidades

  • java.io y java.nio: ficheros

  • java.net y java.sql: comunicaciones y acceso JDBC

  • Prefijo javax en Java SE: no es obsoleto

Las clases que más aparecen de cada paquete

  • java.lang: Object y Class, raíz e identidad de cualquier tipo; String, los envoltorios como Integer, Math, System para la salida por pantalla, Thread, y las interfaces Runnable e Iterable.
  • java.lang, cadenas modificables: StringBuffer y StringBuilder construyen texto por partes sin crear un objeto nuevo en cada paso. La diferencia es que StringBuffer es seguro entre hilos y StringBuilder no, y por eso StringBuilder es más rápido cuando no hay concurrencia.
  • java.net: Socket y ServerSocket para trabajar con TCP/IP a bajo nivel, URL y URLConnection para hablar HTTP, e InetAddress para resolver direcciones.
  • java.sql: Driver y DataSource como puntos de entrada, Connection para la conexión, Statement y PreparedStatement para las sentencias, y ResultSet junto a ResultSetMetaData para recorrer y describir el resultado.
  • java.text y java.util: DateFormat y SimpleDateFormat convierten entre texto y fecha en los dos sentidos; Calendar y Date son el modelo antiguo, superado primero por Joda-Time y después por java.time; Scanner lee de la entrada, StringTokenizer parte una cadena por un delimitador, Timer y TimerTask programan tareas y UUID genera identificadores únicos.
  • javax.xml.parsers: DocumentBuilder implementa el análisis DOM, que carga el documento entero en memoria y permite recorrerlo en cualquier orden; SAXParser implementa el análisis SAX, que va lanzando eventos según lee y ocupa mucha menos memoria.
  • java.io y java.nio: los flujos de bytes (InputStream y OutputStream) frente a los de caracteres (Reader y Writer); la interfaz Serializable, que marca una clase como convertible a una secuencia de bytes; y de java.nio, FileChannel, la clase de utilidad Files con operaciones sobre Path, y el WatchService, que avisa de los cambios que ocurren en un directorio.

Para el examen

  • StringBuffer frente a StringBuilder: el primero es seguro entre hilos; el segundo, más rápido

  • DOM: carga el documento entero en memoria

  • SAX: lanza eventos según lee, con mucha menos memoria

El marco de colecciones

Una colección es un objeto que agrupa otros objetos. Java las reúne en java.util con una jerarquía que conviene tener dibujada en la cabeza, porque casi todas las preguntas del apartado se resuelven sabiendo quién hereda de quién. En la cima está Iterable, la interfaz que permite recorrer algo elemento a elemento; de ella hereda Collection, y de Collection salen las tres familias.

InterfazQué garantizaClases habituales
ListOrden por posición y elementos repetidos permitidosArrayList, LinkedList, Vector
Set (y SortedSet)Sin repetidos. La variante ordenada mantiene además un criterio de ordenHashSet, LinkedHashSet, TreeSet
Queue (y Deque)Acceso por los extremos: cola, o cola por los dos ladosArrayDeque, LinkedList, PriorityQueue
MapPares clave y valor, con la clave sin repetirHashMap, LinkedHashMap, Hashtable, TreeMap

Un array y una lista no son lo mismo aunque se parezcan: el array tiene tamaño fijo desde que se crea, mientras que un ArrayList crece y mengua solo. Ese es el motivo por el que casi nunca se programa con arrays salvo en casos muy concretos.

Map guarda parejas y no elementos sueltos, así que queda fuera de la jerarquía: ni Iterable ni Collection están por encima de él. Es la excepción del árbol y la pregunta más repetida sobre colecciones, y por eso se recorre a través de sus vistas (keySet, values, entrySet) y no directamente.

Para el examen

  • Raíz: Iterable, y debajo Collection

  • List, Set y Queue: orden y repetidos, sin repetidos, y acceso por los extremos

  • Map: queda FUERA de Collection

  • Cómo se recorre un Map: por keySet, values o entrySet

Colecciones: implementaciones y métodos

La clase de utilidad Arrays acompaña al marco de colecciones sin formar parte de él: opera sobre arrays y ofrece asList para convertir un array o una lista de argumentos en una List, binarySearch para buscar en un array ordenado, fill para rellenarlo y sort para ordenarlo. El número variable de argumentos que admite asList es lo que en Java se escribe con tres puntos suspensivos en la declaración del parámetro.

ClaseQué la distingue
ArrayListLista sobre un array que crece solo. Rápida al acceder por posición
LinkedListLista doblemente enlazada. Sirve también como cola por los dos extremos
ArrayDequeCola de doble extremo sobre un array
Vector y StackAntecesores sincronizados. Stack añade el juego de la pila: push, pop, peek, empty y search
HashMapMapa de uso general. Admite claves y valores nulos y no está sincronizado
HashtableEquivalente antiguo y sincronizado, que no admite nulos
TreeMapMapa que mantiene sus claves ordenadas, porque implementa SortedMap
java
// un mapa de aciertos por subtema
Map<String, Integer> aciertos = new HashMap<>();
aciertos.put("jakarta-ee", 8);
aciertos.put("plataforma-net", 6);

Integer deJakarta = aciertos.get("jakarta-ee");   // 8
Set<String> subtemas = aciertos.keySet();         // las claves
Collection<Integer> notas = aciertos.values();    // los valores

// recorrer un mapa: por sus pares, no por el mapa
for (Map.Entry<String, Integer> par : aciertos.entrySet()) {
    System.out.println(par.getKey() + ": " + par.getValue());
}

Para el examen

  • ArrayList frente a LinkedList: acceso rápido por posición frente a servir además como cola doble

  • HashMap: admite nulos y no está sincronizado

  • Hashtable: sincronizado y no admite nulos

  • TreeMap: mantiene las claves ordenadas

Maven: construcción y dependencias

Maven es una herramienta escrita en Java que hace dos trabajos a la vez. El primero es automatizar la construcción: localizar el código fuente y los ficheros de configuración, compilarlos, pasar las pruebas y empaquetar el resultado. El segundo, y el que de verdad cambió la forma de trabajar, es gestionar las dependencias: declarar qué bibliotecas necesita el proyecto y dejar que la herramienta las descargue de un repositorio.

Todo se declara en un único fichero, el POM (Project Object Model), que es el pom.xml del proyecto. Las bibliotecas descargadas se guardan en un repositorio local en la máquina de quien desarrolla, y el repositorio público de referencia es el de la propia Apache. Existen además arquetipos, que son plantillas para crear un proyecto nuevo ya con su estructura.

Cada biblioteca se identifica con tres coordenadas, y esa terna es lo que se pregunta: groupId (quién la publica), artifactId (qué biblioteca es) y version (cuál de sus versiones). El fabricante es dueño de su groupId y de sus artifactId, así que dos bibliotecas distintas nunca chocan.

xml
<!-- una dependencia del proyecto, en pom.xml -->
<dependency>
  <groupId>com.llegandoalcorte</groupId>
  <artifactId>motor-de-repasos</artifactId>
  <version>2.4.0</version>
</dependency>

groupId, artifactId y version. Con esas tres coordenadas se localiza cualquier artefacto en cualquier repositorio, y por eso una dependencia declarada así se resuelve igual en el portátil de quien programa que en el servidor de integración.

Para el examen

  • Qué hace: automatiza la construcción y gestiona dependencias

  • Dónde se declaran: en el pom.xml

  • Las tres coordenadas: groupId, artifactId y version

La estructura del proyecto y las fases de construcción

Maven impone una disposición de carpetas fija, y esa imposición es deliberada: como todos los proyectos se organizan igual, la herramienta no necesita que se le explique dónde está cada cosa y quien llega nuevo a un proyecto sabe orientarse sin preguntar. El código fuente de la aplicación vive bajo src/main/java, y el resultado de la construcción se deja en target.

La construcción está organizada en fases encadenadas, de modo que pedir una fase ejecuta también todas las anteriores. Por eso una sola orden de empaquetado compila, pasa las pruebas y genera el .jar o el .war, sin necesidad de ir paso a paso.

bash
# se lanza desde el directorio donde está el pom.xml
mvn package

# la disposición fija de carpetas
#   pom.xml
#   src/main/java        código de la aplicación
#   src/main/resources   configuración y recursos
#   src/test/java        pruebas
#   target/              lo construido

Un detalle que se pregunta a menudo: cada dependencia se declara con una versión concreta, no con «la última». Es lo que hace que una construcción de hoy y otra de dentro de dos años den el mismo resultado. Y una comparación clásica: Maven y Ant son las dos de Apache, pero Ant se limita a automatizar tareas y no gestiona dependencias, que es justo lo que Maven añadió.

Para el examen

  • Estructura fija: src/main/java, src/main/resources, src/test/java y target

  • Las fases: se encadenan: empaquetar compila y prueba antes

  • Ant: automatiza tareas, pero no gestiona dependencias

Herramientas y bibliotecas del ecosistema

Alrededor de la plataforma hay un ecosistema que en la práctica forma parte del trabajo diario. Conviene tenerlo ordenado por función, que es como se pregunta: dado un nombre, para qué sirve.

FunciónNombres que hay que reconocer
Entorno de desarrolloEclipse, IntelliJ IDEA, NetBeans
Construcción y automatizaciónAnt, Maven, Gradle, Ivy, y Jenkins para la integración continua
Distribuciones del JDKOpenJDK y sus recompilaciones, como Amazon Corretto o la de IBM
Migraciones de base de datosLiquibase y Flyway
Generación de PDFiText y PDFBox
CriptografíaBouncy Castle
Registro de actividadLog4j, Logback y la fachada SLF4J
XML y transformacionesXerces, Xalan, Woodstox y Apache FOP
PruebasJUnit y Mockito para las unitarias, JMeter para las de carga
Utilidades generalesApache Commons y Guava
Cliente HTTPApache HttpComponents. Desde Java 11 la propia plataforma trae uno en java.net.http
JSONGson y Jackson
Documentos y contenidosApache POI para ficheros de ofimática y Apache Tika para detectar y extraer contenido de multitud de formatos
Procesos de datosPentaho Kettle, para extraer, transformar y cargar
Menos código repetitivoProject Lombok, que genera con anotaciones los accesores, constructores, equals, hashCode y toString
Marco de trabajo webSpring, probablemente el más utilizado del mundo Java

Ninguno de estos nombres forma parte de la plataforma: son piezas de terceros que se incorporan como dependencias del proyecto. Esa es justamente la razón de existir de un gestor como Maven, y por eso los dos puntos se estudian juntos.

Para el examen

  • JUnit y Mockito: pruebas

  • JMeter y Jenkins: carga e integración continua

  • Gson y Jackson: JSON

  • POI y Tika: ofimática y detección de formatos

  • Lombok y Spring: anotaciones y el marco web más usado