Mostrando las entradas con la etiqueta Genéricos. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Genéricos. Mostrar todas las entradas

6 de octubre de 2017

Atrapando y manejando excepciones.

   Esta entrada se basa en la descripción del siguiente ejemplo:

      // Note: This class will not compile yet.
      import java.io.*;
      import java.util.List;
      import java.util.ArrayList;

      public class ListOfNumbers {
          private List<Integer> list;
          private static final int SIZE = 10;

          public ListOfNumbers ( ) {
              list = new ArrayList<Integer>(SIZE);
              for (int i = 0; i < SIZE; i++) {
                  
list.add(Integer.valueOf(i));
              }
          }

          public void writeList( ) {
// The FileWriter constructor throws IOException, which must be caught.
              PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));

              for (int i = 0; i < SIZE; i++) {
               // The get(int) method throws IndexOutOfBoundsException, which must be caught.
                  out.println("Value at: " + i + " = " + list.get(i));
              }
              out.close();
          }
      }


   El ejemplo ha sido tomado y adaptado para cumplir con las nuevas especificaciones del API de The Java Tutorials (Catching and Handling Exceptions). Puede descargar la versión ListOfNumbers1, misma que no compila debido a que no realiza el adecuado manejo de las excepciones que podrían generarse, y la versión corregida ListOfNumbers, la cual contiene ya los elementos necesarios para el adecuado manejo de dichas excepciones.

    Recomiendo al lector remitirse en este momento al Ejercicio 3 de la entrada de Ejercicios selectos para comparar este ejemplo con una versión alternativa que compacta las cláusulas catch en una sola.


5 de junio de 2017

Pilas (implementación).

   La representación de una pila, como una secuencia de nodos, se muestra en la siguiente figura. Los detalles de su implementación se desarrollarán a continuación.

Abstracción de una pila como una secuencia de nodos.

 Pila primitiva.

   Esta sección describe la implementación de una pila primitiva. Se ha denominado de esta forma debido a que implementa una estructura de datos que almacena un tipo de dato primitivo: int.

   La definición de la clase fundamental para la implementación de la estructura de datos se muestra en el Ejemplo NodoPrimitivo. Los detalles de este tipo de implementación de clases autorreferidas se han discutido con anterioridad en la entrada Abstracción de estructuras de datos y no se repetirán aquí, por lo que se sugiere al lector que la revise nuevamente y se tome el tiempo necesario para comparar el Ejemplo NodoPrimitivo con el Ejemplo Nodo antes de continuar.

   La implementación de la estructura de datos pila se muestra en el Ejemplo PilaPrimitiva, y su explicación se centrará únicamente en los métodos push, pop, estaVacia e imprime.

   El método estaVacia (líneas 37-39) realiza una verificación bastante simple: si el tope de la pila es igual a null, regresa verdadero (está vacía), si no, regresa falso (existe al menos un elemento).

   El método push por su parte (líneas 18-23), recibe como argumento el elemento a insertar en la pila (elemento), y se apoya del método estaVacia y de los constructores para realizar la inserción:

  • Si la pila está vacía (línea 19), se crea un nuevo nodo con el elemento correspondiente (línea 20) para el atributo dato, y null en su atributo siguiente.
  • Si la pila no está vacía (línea 21), se crea un nuevo nodo con el elemento correspondiente para el atributo dato y con el tope actual en su atributo siguiente (línea 22). Así mismo, note que el tope es actualizado para hacer referencia al nodo recién creado.
   Ahora bien, observe que el método pop (líneas 26-34) posee una característica particular: el método lanza (throws) una excepción ExcepcionEDVacia (línea 26) lo cual quiere decir que, en determinadas condiciones, el método puede lanzar una excepción; para el caso del método pop, la condición consiste en intentar eliminar un elemento de la pila cuando ésta está vacía.

   La excepción ExcepcionEDVacia definida en el Ejemplo ExcepcionEDVacia es en realidad bastante simple, ya que delega toda la responsabilidad a RuntimeException que es la clase de la que deriva, y lo único que hace es establecer un identificador para la excepción a través de sus constructores, los cuales en realidad utilizan el constructor de la super clase (clase padre) a través de la cláusula super. Es importante que el lector recuerde esta excepción, ya que será la excepción que utilizarán todas las estructuras de datos que se implementan en el blog.

   Ahora bien, cuando el programador se enfrenta a la necesidad de lanzar una excepción cabe la pregunta ¿y de qué tipo? Se puede utilizar una excepción escrita por alguien más o se puede hacer una propia. Se debería hacer clases de excepción propias cuando se responda de manera afirmativa a alguna de las siguientes preguntas, de otra forma, debería usarla una excepción escrita por alguien más (vea Creating Exception Classes):
  • ¿Necesita un tipo de excepción que no está representada en el API de Java?
  • ¿Sus usuarios se verán beneficiados si pueden diferenciar sus excepciones de aquellas lanzadas por clases escritas por alguien más?
  • ¿Su código lanza más de una excepción relacionada?
  • Si utiliza una excepción escrita por alguien más, ¿sus usuarios tendrán acceso a esas excepciones?
  • ¿Su paquete de clases debería ser independiente y auto contenido?
   Continuando con el Ejemplo PilaPrimitiva, el método pop verifica (línea 27) si la pila está vacía, si lo está, crea y lanza la excepción correspondiente (línea 28); en caso contrario, recupera el dato almacenado (línea 30), y desecha el nodo correspondiente al hacer que el tope haga ahora referencia al elemento siguiente del tope actual (línea 31), para finalmente regresar el dato recuperado (línea 33). En Java no hay una eliminación o liberación explícita de memoria, dicha labor es delegada al recolector de basura el cual se encarga, grosso modo, de identificar aquellos objetos que no estén siendo referidos para entonces liberar la memoria que utilizan.

   Por último, en el método imprime (líneas 42-57), si la estructura de datos está vacía (línea 43), se reporta (línea 44); en caso contrario, se realiza un recorrido por todos los nodos de la estructura para imprimir su contenido (líneas 47-54).

   La clase de prueba para la pila primitiva del Ejemplo PilaPrimitiva, se presenta en el Ejemplo PruebaPila. Observe cómo en la línea 6 se crea la pila y se utiliza un constructor sin argumentos.

   Las líneas 9-12 realizan la inserción en la pila de los números del cero al nueve; por cada inserción se imprime todo el contenido de la pila, como se muestra en la siguiente figura:

Ejemplo de inserción de elementos en la pila primitiva. Se muestra la salida del Ejemplo PruebaPila.

    Por otro lado, las líneas 15-24 realizan la eliminación de los elementos de la pila. Dicho fragmento de código intenta eliminar once elementos (líneas 17-18) de la pila (recuerde que sólo fueron insertados diez elementos, por lo que al intentar eliminar el décimo primero, se generará la excepción ExcepcionEDVacia), y dado que el método pop puede lanzar una excepción, el código involucrado en la eliminación debe estar dentro de una cláusula try-catch-finally, la cual permite atrapar (cachar) las excepciones que un método pudiera lanzar.

   Si se genera un excepción ExcepcionEDVacia, ésta es atrapada y el flujo de control se envía al ámbito de la cláusula catch en donde se realiza el correspondiente tratamiento de la excepción. Para el caso del Ejemplo PruebaPila el manejo de la excepción consiste únicamente en imprimir la secuencia de eventos (en forma de pila) que dieron lugar a la excepción; sin embargo, es importante aclarar que el manejo de una excepción puede ser tan elaborado como en un momento dado se requiera.

   La salida correspondiente a la eliminación de elementos de la pila primitiva, se muestra en la siguiente figura:

Ejemplo de eliminación de elementos en la pila primitiva. Se muestra la salida del Ejemplo PruebaPila.

Pila genérica.
   Esta sección generaliza la implementación de una pila de tal forma que la estructura de datos tenga la capacidad de almacenar objetos genéricos; es decir, objetos de cualquier clase.

   Como primer paso, es preciso que el lector se tome el tiempo que considere necesario para comparar el Ejemplo NodoPrimitivo discutido en la sección anterior, con el Ejemplo NodoG. Es importante resaltar que, aunque distintos, ambos ejemplos son esencialmente equivalentes.

La primera diferencia que salta a la vista, además del nombre de la clase, es la notación <T>. Dicha notación se utiliza en Java para especificar que la clase gestiona objetos genéricos, es decir, que el tipo o la clase de los objetos que almacena no está especificada en la definición de la misma, sino que se especifica en el momento de la instanciación del objeto (observe la línea 6 del Ejemplo PruebaPilaGenerica).

   La línea 7 del Ejemplo NodoG define que la clase del atributo dato es T, es decir, un genérico, y por lo tanto el atributo siguiente es una referencia a un objeto que almacena objetos genéricos.

   Observe cómo ahora los constructores y los métodos de tipo set reciben como argumentos objetos genéricos T (líneas 10, 14 y 19), y referencias a objetos que a su vez almacenan objetos genéricos (líneas 14 y 27); mientras que los métodos de tipo get regresan genéricos (línea 23), o referencias a objetos que almacenan objetos genéricos (línea 31).

   Ahora bien, las consideraciones hechas para el Ejemplo NodoG respecto a los genéricos, son las mismas que debe tomar en cuenta para el Ejemplo Pila, por lo que una vez más se pide encarecidamente al lector que compare este último con el Ejemplo PilaPrimitiva discutido en la sección anterior tomando en consideración lo explicado hasta este momento para los genéricos.

   Observe que en ninguna parte del Ejemplo Pila se hace explícita una clase específica para el genérico T, por lo que también aquí se hace una gestión de genéricos en directa relación con los genéricos utilizados en el Ejemplo NodoG.

   En resumen, la clase NodoG del Ejemplo NodoG define nodos que almacenan objetos genéricos (nodos genéricos), los cuales son utilizados de manera conveniente por la clase Pila del Ejemplo Pila para conformar una estructura de datos dinámica que almacena objetos o nodos genéricos en forma de pila.

   El Ejemplo PruebaPilaGenerica muestra la clase de prueba para la pila genérica del Ejemplo Pila. La línea más importante del Ejemplo PruebaPilaGenerica es la línea 6, ya que es en ella en donde finalmente se define la clase de objetos que contendrá (almacenará) la pila: Integer.

   Consulte la sección Genéricos de la entrada Ejemplos selectos de transición para ampliar un poco más la información y los detalles acerca de los genéricos en Java. En el Ejemplo PilaC se muestra la implementación alternativa de una pila utilizando un ArrayList del API de Java; mientras que en el EjemploPruebaPilaC se presenta su correspondiente clase de prueba. Adicionalmente, se proporcionan al lector dos ejemplos adicionales que utilizan colecciones (estructuras de datos) del API: Stack y ArrayDeque (Deque); tómese el tiempo de estudiarlos y revisar la información correspondiente en el API.

   Finalmente, asegúrese de comprobar que la salida del Ejemplo PruebaPilaGenerica corresponde, en esencia, con la salida del Ejemplo PruebaPila para la inserción de datos (push), y que lo correspondiente ocurre también para la eliminación de elementos (pop).

6 de abril de 2017

Consideraciones adicionales (pilas).

   La pila es una estructura de datos sumamente importante y ampliamente utilizada en distintas áreas no sólo de la computación. Su definición y funcionalidad es clara y simple, por lo que no es casual que haya sido la primera estructura de datos estudiada y presentada en el blog.

   Por otro lado, los conceptos expuestos en el blog respecto a los genéricos en Java y C++ resultarán fundamentales para los siguientes temas, ya que todas las estructuras de datos siguientes se basan en ellos, por lo que se invita nuevamente al lector a realizar un repaso de los conceptos relacionados con los genéricos así como a tener presente la importancia de los mismos a lo largo de las estructuras de datos subsecuentes.

   Adicionalmente, una vez que se han presentado los conceptos de pila (definición y operaciones) y una propuesta de implementación, resulta fundamental el conocer el esquema de relación que existe entre las clases más importantes involucradas en la implementación de la pila genérica estudiada. Los siguientes diagramas de clases UML presentan dicha relación respecto a las dos implementaciones realizadas:

Diagrama de clases UML para la pila genérica (Java).
 
    Insto amablemente al lector a que se tome el tiempo que considere necesario para comparar el diagrama de clases de la figura anterior con las clases en Java que implementan la pila genérica (Ejemplo Pila), el nodo genérico (Ejemplo NodoG), y la excepción de estructura de datos vacía (Ejemplo ExcepcionEDVacia).
 
Diagrama de clases UML para la pila genérica (C++).
 
    De manera similar a lo dicho en el párrafo anterior para el Ejemplo pila_genérica de C++.

   Los detalles de UML quedan fuera de los alcances del blog; sin embargo, los diagramas de clases UML de las figuras anteriores muestran una relación de composición entre la clase Pila y la clase NodoG (Nodo) de cero a muchos (0 .. *), lo cual quiere decir que una pila puede tener ninguno, uno, o muchos nodos. Por otro lado, también se muestra la relación de asociación uno a uno existente entre la clase Pila y la clases de excepción correspondientes a cada diagrama (observe también que los diagramas de clases muestran así mismo la relación de herencia que existe para las excepciones).

   Asegúrese de comprender el diagrama UML que sea de su interés respecto al lenguaje que esté utilizando así como su relación con los ejemplos citados, ya que en las entradas siguientes se utilizarán este tipo de diagramas de clases UML en complemento con la definición del ADT, para definir la implementación de la estructura de datos correspondiente.

13 de febrero de 2017

Ejemplos selectos de transición.

   Es imposible presentar, ya no digamos una entrada, sino en un blog completo un conjunto de ejemplos representativos para cualquier lenguaje de programación; sin embargo, en esta entrada se han seleccionado algunos ejemplos que pudieran ser de utilidad para la familiarización del lector con el lenguaje de programación Java, así como para comprender los ejemplos desarrollados en el blog.

Lectura de datos desde la terminal.
   Una de las tareas más comunes para cualquier programa es la lectura de datos desde la entrada estándar (teclado). Para los programas del blog que utilizan entrada de datos, se sugiere el enfoque que se presenta en el Ejemplo Lectura, el cual no hace uso de una interfaz gráfica de usuario (GUI) para centrar la atención en los aspectos relevantes (como la lectura de datos en este caso), y también para mantener más cortos los programas.

   El Ejemplo Lectura muestra en la línea 4 la importación de la clase Scanner del paquete java.util, el cual es un paquete con diversas utilerías; se recomienda en este momento echar un vistazo en el API de Java para tener una mejor idea de las clases que contiene el paquete java.util.

   Las instancias de la clase Scanner (como entrada) proporcionan diferentes servicios, entre ellos el método nextInt, el cual se encarga de obtener el siguiente número entero de la entrada estándar (líneas 17 y 19).

   Observe que el objeto entrada ha sido creado (línea 10) utilizando el objeto in de la clase System que, por decirlo de una manera simple, es la parte complementaria de System.out. Éste es el mecanismo usual para la entrada de datos. También note que han sido declarados tres objetos pertenecientes a la clase Integer (líneas 12-14).

   Java también maneja lo que se conoce como tipos de datos primitivos al estilo del lenguaje C; la clase Integer es en realidad una envoltura (wrapper) para el tipo de dato int. Una posible salida para el Ejemplo Lectura se muestra en la siguiente figura:

Una posible salida para el Ejemplo Lectura.

Estructuras de control.
   Java incorpora las estructuras de control tradicionales del enfoque estructurado, las cuales se asumen conocidas por el lector. Esta sección presenta un resumen necesariamente incompleto de las estructuras de control de selección y de repetición, con la única intención de tenerlas como una referencia inmediata.

   Estructuras de selección.
   El Ejemplo If muestra el uso de la estructuras de selección if y los operadores relacionales (líneas 20-31), así como el uso de la estructura de selección if-else (líneas 33-38).

   Los lectores familiarizados con el lenguaje de programación C notarán que tanto las estructuras de selección como los operadores relacionales son idénticos en Java, pero a diferencia de C, sí existe el tipo booleano, por lo que en Java es válido decir que una expresión se evalúa como verdadera o falsa según sea el caso.

   Note que las líneas 34 y 36 han hecho uso de una expresión de concatenación de cadenas de la forma:

objeto + cadena + objeto

lo cual es bastante común en Java. Dicha expresión lo que hace es precisamente concatenar las cadenas por medio del operador +. Note que aunque los objetos, como en el caso del ejemplo, no son cadenas, Java incorpora en la mayoría de sus clases el método toString, el cual se encarga de regresar una representación de cadena del objeto correspondiente.

   De hecho se recomienda que, en la medida de lo posible, las clases definidas por el usuario definan el método toString con la intención de mantener una compatibilidad con este tipo de situaciones como la que se acaba de describir. Tome en cuenta que aunque el método toString es heredado de la clase Object (la clase base en Java), es recomendable definir un comportamiento particular para una clase específica. Note también que no existe un llamado explícito del método sino un llamado implícito, mismo que se realiza a través del operador de concatenación de cadenas +.

   Una posible salida para el Ejemplo If se muestra en la siguiente figura:

Una posible salida para el Ejemplo If.

   Por otro lado, la siguiente tabla muestra la lista de operadores relacionales utilizados en Java:

Operador     Descripción
  ==            Igual que
    !=             Distinto de
                  <              Menor estricto que
                  >              Mayor estricto que
                <=             Menor o igual que
                >=             Mayor o igual que


   Estructuras de repetición.
   Las estructuras de repetición while, do-while y for se muestran respectivamente en los Ejemplos While, DoWhile y For.

   Los Ejemplos While, DoWhile y For se explican por sí mismos. Note que en los tres ejemplos se ha utilizado el tipo de dato primitivo int para la variable de control contador. La salida de los tres ejemplos es la misma, y se muestra en la siguiente figura:

Salida de los Ejemplos While, DoWhile y For.

Arreglos.
   El Ejemplo Arreglo muestra la creación, recorrido e impresión de un arreglo de enteros primitivos (int).

   La línea 7 define al objeto arreglo como un arreglo de enteros. Observe que el objeto es creado (new), con un tamaño específico (diez).

   Adicionalmente se definen también un par de variables:
  1. Un valor inicial: valor (línea 8).
  2. Un incremento: incremento (línea 9)
   Los arreglos en Java al ser creados y definidos como objetos, tienen definido el atributo público length, mismo que almacena la longitud del arreglo. Dicha propiedad es la que se utiliza como expresión condicional en los ciclos for de las líneas 12 y 17 respectivamente.

   El primer ciclo recorre el arreglo para inicializar y asignar los valores al arreglo en función de valor, incremento y la variable de control i.

   Por otro lado, el segundo ciclo realiza un recorrido tradicional para la impresión del arreglo en la salida estándar. La salida del Ejemplo Arreglo se muestra en la siguiente figura:

Salida del Ejemplo Arreglo.

Argumentos en la línea de comandos.
   El Ejemplo MainArgs muestra la forma de procesar los argumentos en la invocación de un programa, lo cual resultará útil y necesario en diversas ocasiones, como es el caso de algunos de los ejercicios planteados en el blog.

   El objeto args es un arreglo de cadenas (línea 6), por lo que en la línea 7 se verifica si se han proporcionado o no argumentos en la línea de comandos; en caso de que no, se reporta en la línea 8:

Salida del Ejemplo MainArgs sin argumentos.
 
    Si se proporcionaron argumentos, entonces se procesa la lista de argumentos con un ciclo (línea 10) y se imprime en la salida estándar dicha lista de argumentos, mismos que están almacenados en el arreglo de cadenas args:

Una posible salida del Ejemplo MainArgs con argumentos.

Excepciones.
   Las excepciones permiten una abstracción sobre el mecanismo de manejo de errores ligeros o condiciones que un programa pudiera estar interesado en atrapar y procesar.

   La idea subyacente en las excepciones es separar el manejo de este tipo de condiciones o errores de la lógica de funcionamiento inherente al programa.

   Una excepción es una situación anormal en la lógica de ejecución esperada por un programa, como el intentar clonar un objeto que no tiene implementado el mecanismo de clonación por ejemplo, manejar un formato de datos inadecuado para algún especificador, intentar realizar una operación de E/S en un canal cerrado, intentar acceder a elementos de una estructura de datos que no contiene elementos, entre muchísimas otras más.

   En la práctica, es posible definir en Java clases que gestionen excepciones o errores de una aplicación en particular. De hecho, una de las intenciones de las excepciones es la de, ante una problemática determinada, tratar de solucionarla en la medida de lo posible para continuar con el programa o aplicación, y no la de terminar con la primera dificultad que se presente.

   Un manejo completo y robusto de excepciones es una labor que, si bien su dominio no requiere de años, tampoco es una tarea trivial y queda fuera de los alcances de esta sección. Para obtener un poco más de información, refiérase a las entradas correspondientes relacionadas con las excepciones, en el contenido temático.

   Para muchos de los ejemplos desarrollados en el blog se hará uso (directo o indirecto) de la excepción definida por la clase RuntimeException del API, la cual maneja el conjunto de excepciones generadas durante la ejecución.

   La clase Throwable es la clase base de todas las excepciones que pueden ser lanzadas en Java, por lo que la revisión y estudio de esta jerarquía de clases del API es un punto inicial fundamental tanto para la comprensión de las excepciones, como para su referencia permanente. La relación de la jerarquía de clases en la que se encuentra la clase Exception en el contexto de Java, se expresa en un diagrama de clases de UML (Unified Modeling Language) de la siguiente figura:

Relación UML de la jerarquía de clases Exception de Java.

   La clase Throwable tiene dos derivaciones:
  1. Error: condiciones excepcionales que son externas al programa o la aplicación; usualmente no es posible anticiparlas o recuperarse de ellas (mal funcionamiento del hardware o del sistema). Los programas sencillos normalmente no atrapan o lanzan este tipo de excepciones.
  2. Excepción: indican que ocurrió algún problema pero, al menos en principio, no un problema serio. La mayoría de los programas que escriba atraparán o lanzarán este tipo de excepciones en lugar de los de la clase Error.
   La clase RuntimeException es un tipo especial de excepción reservada para indicar el uso incorrecto de un API por ejemplo. En este sentido, el Ejemplo ExcepcionEDVacia muestra la definición de una excepción bastante sencilla pero útil; de hecho, la clase mostrada en dicho ejemplo es la que se utiliza para las estructuras de datos desarrolladas en el blog.

   Note que la excepción ExcepcionEDVacia es una subclase de la clase RuntimeException. La clase RuntimeException es la super clase de las excepciones que pueden ser lanzadas durante la ejecución de la máquina virtual de Java.

Genéricos.
   La definición de jdk 5.0 introdujo nuevas modificaciones y extensiones a Java; una de ellas fue el aspecto relacionado con los genéricos (generics).

   Los genéricos son en sí mismos todo un tema de estudio, pero dado que se utilizan en la mayoría de los ejemplos del blog respecto a la definición de las estructuras de datos, aquí se presenta una exagerada y necesariamente incompleta y breve introducción.

Los genéricos permiten una abstracción sobre los tipos de datos o los objetos que se procesan, y dentro de sus objetivos se encuentran el eliminar la ambigüedad latente que existía en la conversión forzada de tipos (cast) y lo molesto de su realización, ya que usualmente un programador sabe cual es el tipo de dato que está procesando cuando utiliza una colección de datos por ejemplo.

   El siguiente fragmento de código, se utilizaba antes de los genéricos:

      List lista = new LinkedList();
      lista.add("Genericos en Java");
      String cadena = (String) lista.get(0);


   Con los genéricos el programador pone una marca (clase o tipo de datos en particular) por decirlo de alguna manera, para restringir los datos a almacenar y recuperar:

      List<String> lista = new LinkedList<String>();
      lista.add("Genericos en Java");
      String cadena = lista.get(0);


  El cambio es aparentemente simple pero significativo ya que evita los errores intencionales o accidentales en tiempo de ejecución, además de que permite al compilador hacer una verificación sobre los tipos de datos que se gestionan. Note que en el segundo fragmento de código, el cast ha sido eliminado.

1 de febrero de 2017

Referencias sugeridas.

  1. Bracha, Gilad, "Generics", Oracle Corporation, The Java Tutorials, (último acceso febrero 2017).
  2. Budd, Timothy A., "An Introduction to Object-Oriented Programming", Addison Wesley.
  3. Byte Magazine, Smalltalk, Volume 06 Number 08, A McGraw Hill Publication.
  4. Deitel, H. M. y Deitel, P. J., "Cómo Programar en Java", Prentice Hall.
  5. Goldberg Adele and Robson David, "Smalltalk-80 The Language and its Implementation", Addison-Wesley Publishing Company.
  6. Gökel Canol, Computer Programming using GNU Smalltalk, GNU Free Documentation License 1.3.
  7. Kuhn, Thomas Samuel., "The Structure of Scientific Revolutions", University of Chicago Press.
  8. Langsam, Yedidyah, Augenstein, M. J. and Tenenbaum, A. M., "Estructuras de Datos con C y C++", Prentice Hall Hispanoamericana.
  9. Mark Allen Weiss, "Estructuras de Datos en Java", Addison Wesley.
  10. McConnell, Steve, "Code Complete", Microsoft Corporation.
  11. Oracle, The Java Tutorials, Java Documentation.
  12. Shalloway, Alan and Trott James R., "Design Patterns Explained A New Perspective on Object Oriented Design", Addison Wesley.
  13. Sierra, Kathy and Bates, Bert, "Sun Certified Programmer & Developer for Java 2", Mc Graw Hill/Osborne.
  14. Schildt, Herbert, "C++: The Complete Reference", Mc Graw Hill Osborne.
  15. Stroustrup, Bjarne, "El Lenguaje de Programación C++", Addison Wesley.
  16. Unified Modeling Language Web Site, (último acceso febrero 2017).
  17. Wirth, Niklaus, "Algoritmos y Estructuras de Datos", Prentice Hall.