Logo DIE

Utilerías y Clases de Uso General

Unidad de Apoyo para el Aprendizaje

Iniciar

Introducción


Al trabajar en un problema de programación, normalmente se debe verificar si hay clases pre-construidas que satisfagan las necesidades del programa. Si existen esas clases, entonces hay que utilizarlas: “no tratar de reinventar la rueda”.

Hay dos ventajas principales de usar clases pre-construidas: se puede ahorrar tiempo ya que no es necesario escribir nuevas, y el uso de clases pre-construidas también puede mejorar la calidad de los programas, ya que han sido probadas completamente, depuradas y sometidas a un proceso de escrutinio para asegurar su eficiencia.

Nota: En esta UAPA se tomará como caso de estudio el lenguaje de programación Java, sin embargo, queda a criterio del profesor el uso de éste u otro lenguaje orientado a objetos.





Utilizar bibliotecas propias del lenguaje para realizar algunas tareas comunes y recurrentes.

Arreglos


Un arreglo es un objeto en el que se puede almacenar un conjunto de datos de un mismo tipo. Cada uno de los elementos del arreglo tiene asignado un índice numérico según su posición, del 0 el primer índice. Se declara de la siguiente manera:

tipoDeDato [ ] nombreVariable; o tipoDeDato nombreVariable[ ];

Como se puede apreciar, los corchetes pueden estar situados delante del nombre de la variable o detrás. Ejemplos:

int [ ] k; String [ ] p; char datos[ ];

Los arreglos pueden declararse en los mismos lugares que las variables estándar. Para asignar un tamaño al arreglo se utiliza la expresión:

variableArreglo = new tipoDeDato[tamaño];

También se puede asignar tamaño al arreglo en la misma línea de declaración de la variable.

int [ ] k = new int[5];

Cuando un arreglo se dimensiona, todos sus elementos son inicializados explícitamente al valor por defecto del tipo correspondiente.

Para declarar, dimensionar e inicializar un arreglo en una misma sentencia se indican los valores del arreglo entre llaves y separados por comas. Ejemplo:

int [ ] nums = {10, 20, 30, 40};

El acceso a los elementos de un arreglo se realiza utilizando la expresión:

variableArreglo[indice]

Donde índice representa la posición a la que se quiere tener acceso y cuyo valor debe estar entre 0 y tamaño – 1.

Todos los objetos arreglo exponen un atributo público llamado length que permite conocer el tamaño al que ha sido dimensionado un arreglo.

Ejemplo:

int [ ] nums = new int[10];
for(int i=0; i < nums.length; i++)
      nums[i] = i * 2;

Los arreglos, al igual que las variables, se pueden usar como argumentos y pueden ser devueltos por un método o función.

En Java se puede utilizar una variante del for llamado for-each, para facilitar el recorrido de arreglos y colecciones recuperando su contenido y eliminando la necesidad de usar una variable de control que sirva de índice. Su sintaxis es la siguiente:

for(tipoDato variable : variableArreglo){
       //instrucciones
}

Ejemplo:

int [ ] nums = { 4, 6 ,30, 15 };
for(int n : nums){
           System.out.println(n);
}

En este caso, sin acceder de forma explícita a las posiciones del arreglo, cada una de éstas es copiada automáticamente a la variable auxiliar n al principio de cada iteración.

Los arreglos en Java también pueden tener más de una dimensión, al igual que en C/C++ para declarar un arreglo bidimensional ser tendrían que usar dos pares de corchetes y en general para cada dimensión se empleará un nuevo par de corchetes.

Ejemplo:

int [ ] [ ] matriz;



Argumentos por línea de comandos

Es posible suministrar parámetros al método main a través de la línea de comandos. Para ello, los valores deberán especificarse a continuación del nombre de la clase separados por un espacio:

>> java NombreClase arg1 arg2 arg3

Los datos llegarán al método main en forma de un arreglo de cadenas de caracteres.

Ejemplo:

Diagrama de bloques



Se ejecuta utilizando la siguiente expresión en la línea de comandos:

Diagrama de bloques




API de JAVA


Diagrama de bloques



Como el lenguaje Java es un lenguaje orientado a objetos, la API de Java provee de un conjunto de clases utilitarias para efectuar toda clase de tareas necesarias dentro de un programa. La API Java está organizada en paquetes lógicos, donde cada uno contiene un conjunto de clases relacionadas semánticamente.

La información completa del API de Java se denomina especificación y sirve para conocer cualquier aspecto sobre las clases que contiene la API. Esta especificación es de crucial importancia para los programadores, debido a que en ella se pueden consultar los detalles de alguna clase que se quiera utilizar y ya no sería necesario memorizar toda la información relacionada.

La especificación del API de Java se encuentra en el sitio de Oracle.

En este sitio se puede consultar la especificación de las últimas versiones (ya que en cada versión se agregan o modifican algunas clases).

Una vez seleccionada la versión, se puede consultar el detalle de todas las clases que integran el API.

Manejo de cadenas


En Java las cadenas de caracteres no son un tipo de datos primitivo, sino que son objetos pertenecientes a la clase String.

String

String s = new String(“Texto de prueba”);

Sin embargo, debido al amplio uso de estos objetos en un programa, Java permite crear y asignar un objeto String a una variable de la misma forma que se hace con los tipos de datos primitivos. Entonces el ejemplo anterior es equivalente a:

String s = “Texto de prueba”;



Una vez creado el objeto y asignada la referencia de éste a una variable, puede utilizarse para acceder a los métodos definidos en la clase String (para profundizar más en este tema, se pueden revisar en la documentación del API com java.lang.String). Los más usados son: length, equals, charAt, substring, indexOf, replace, toUpperCase, toLowerCase, Split, entre otros.


Ejemplo:

s.length();       //Devuelve el tamaño de la cadena


s.toUpperCase();       //Devuelve la cadena en mayúsculas

Las variables de tipo String se pueden usar en una expresión que use el operador ‘+’ para concatenar cadenas.

Ejemplo:

String s = “Hola”;

String t = s + “ que tal”;

En Java las cadenas de caracteres son objetos inmutables, esto significa que una vez que el objeto se ha creado, no puede ser modificado.

Cuando escribimos una instrucción como la del ejemplo anterior, es fácil intuir que la variable s pasa a señalar al objeto de texto “Hola que tal”. Aunque a raíz de la operación de concatenación pueda parecer que el objeto “Hola” apuntado por la variable s ha sido modificado, en realidad no sucede esto; sino que al concatenarse “Hola” con “que tal” se está creando un nuevo objeto de texto “Hola que tal” que pasa a ser referenciado por la variable s. El objeto “Hola” deja de ser referenciado por dicha variable.



Java provee soporte especial para la concatenación de cadenas con las clases StringBuilder y StringBuffer.

StringBuilder

Es una secuencia de caracteres mutable, su contenido y capacidad puede cambiar en cualquier momento.

A diferencia de los Strings, los builders cuentan con una capacidad (capacity) y la cantidad de espacios de caracteres asignados

Esta siempre es mayor o igual que la longitud (length) y se expande automáticamente para acomodarse a más caracteres.



Un objeto StringBuilder es una secuencia de caracteres mutable, es decir, su contenido y capacidad puede cambiar en cualquier momento. Además, a diferencia de la clase String, la clase StringBuilder cuenta con una capacidad (capacity) preestablecida con cierta cantidad de espacios para caracteres, la cual siempre es mayor o a lo mucho igual que la longitud (length) de la cadena. Además, esta capacidad se puede expandir automáticamente para acomodar más caracteres.

Los métodos principales de la clase StringBuilder son append e insert. Cada uno convierte un dato en String y concatena o inserta los caracteres de dicho String al StringBuilder. El método append agrega los caracteres al final mientras que insert los agrega en un punto específico.

Para hacer la misma concatenación que el ejemplo con String, quedaría:

StringBuilder sb = new StringBuilder(“Hola”);


sb.append(" que tal");

Wrappers


Los wrappers o clases envoltorio están diseñadas para ser un complemento de los tipos primitivos. En efecto, los tipos primitivos son los únicos elementos de Java que no son objetos. Esto tiene algunas ventajas desde el punto de vista de la eficiencia, pero algunos inconvenientes desde el punto de vista de la funcionalidad.

Por ejemplo:

Los tipos primitivos siempre se pasan como argumento a los métodos por valor; mientras que los objetos se pasan por referencia. No hay forma de modificar en un método un argumento de tipo primitivo y que esa modificación se trasmita al entorno que hizo la llamada.



Una forma de conseguir esto es utilizar un wrapper.

Diagrama de bloques

Existe una clase Wrapper para cada uno de los tipos primitivos:

Diagrama de bloques

• Byte

• Long

• Short

• Float

• Character

• Double

• Integer

• Boolean

Todas estas clases se encuentran en java.lang.



Todas las clases Wrapper permiten crear un objeto de la clase a partir de tipo básico.

int k =23;
Integer num = new Integer(k);

A excepción de Character, las clases Wrapper también permiten crear objetos partiendo de la representación como cadena del dato.

String s = “4.65”;
Float ft = new Float(s)

Para recuperar el valor a partir del objeto, las ocho clases Wrapper proporcionan un método con el formato xxxValue( ) que devuelve el dato encapsulado en el objeto donde xxx representa el nombre del tipo en el que se quiere obtener el dato.

float dato = ft.floatValue( );
int n=num.intValue( );


Las clases numéricas proporcionan un método estático parseXxx(String) que permite convertir la representación en forma de cadena de un número en el tipo numérico correspondiente, donde Xxx es el nombre del tipo al que se va a convertir la cadena de caracteres.

String s1 = “25”, s2=”89.2”;
int n = Integer.parseInt(s1);
double d = Double.parseDouble(s2);





Autoboxing


Diagrama de bloques

Por ejemplo

int p = 5;
Integer n = new Integer(p);

Equivale a

int p = 5;
Integer n = p;



Es decir, la creación del objeto Wrapper se produce implícitamente al asignar el dato a la variable objeto. De la misma forma, para obtener el dato básico a partir del objeto Wrapper no será necesario recurrir al método xxxValue( ); esto se realizará implícitamente al utilizar la variable objeto en una expresión.

A esto se le conoce como autounboxing. Para el ejemplo anterior:

int a = n;

Colecciones


Diagrama de bloques



Java incluye un amplio conjunto de clases para la creación y tratamiento de colecciones. Todas ellas proporcionan una serie de métodos para realizar las operaciones básicas sobre una colección, como son:

Diagrama de bloques



Los principales tipos de colecciones que se encuentran por defecto en el API Java son:

Un conjunto (Set) es una colección desordenada, es decir, no mantiene un orden de inserción, y no permite elementos duplicados.

Clases de este tipo: HashSet, TreeSet, LinkedHashSet.


Una lista (List) es una colección ordenada, ya que mantiene un orden de inserción y permite elementos duplicados.

Clases de este tipo: ArrayList y LinkedList


Un mapa (Map) o arreglo asociativo, es un conjunto de elementos con una llave y un valor:

      <llave, valor>

Donde las llaves no pueden ser repetidas y a cada valor le corresponde una llave. La columna de valores sí puede repetir elementos.

Clases de este tipo: HashMap, Hashtable, TreeMap o LinkedHashMap.



Algunas de las clases más usadas para manejo de colecciones son las siguientes (todas ellas se encuentran en java.util):



Diagrama de bloques


Para crear un objeto ArrayList se utiliza la siguiente sintaxis:

ArrayList<TipoDato> nombreVariable = new ArrayList<TipoDato>( );

Ejemplo:

ArrayList<Integer> arreglo = new ArrayList<Integer>( );

En este caso se creó un ArrayList llamado arreglo, el cual podrá contener elementos enteros (Integer).

Una vez creado, se pueden usar los métodos de la clase ArrayList para realizar las operaciones habituales con una colección, las más usuales son:



Ejemplo:

Diagrama de bloques


Diagrama de bloques


La utilización de colecciones basadas en claves resulta útil en aquellas aplicaciones en las que se requiera realizar búsquedas de objetos a partir de un dato que lo identifica. La creación de un objeto Hashtable se realiza de la siguiente manera:

Hashtable<TipoDatoClave, TipoDatoElemento> nombreVariable = new
Hashtable<TipoDatoClave, TipoDatoElemento>( );

Ejemplo:

Hashtable<String, Integer> miHashtable = new Hashtable<String, Integer>( );



Los principales métodos de la clase Hashtable para manipular la colección son los siguientes:

put(clave, valor)

Añade a la colección el elemento valor, asignándole la clave especificada. En caso de que exista esa clave en la colección el elemento se sustituye por el nuevo valor.

containKey(clave)

Indica si la clave especificada existe o no en la colección. Devuelve un boolean.

get(clave)

Devuelve el valor que tiene asociado la clave que se indica. En caso de que no exista ningún elemento con esa clave asociada devuelve null.

remove(clave)

Elimina de la colección el valor cuya clave se especifica. En caso de que no exista ningún elemento con esa clave no hará nada y devolverá null, si existe eliminará el elemento y devolverá una referencia al mismo.

size()

Devuelve el número de elementos almacenados en el Hashtable.



Ejemplo:

Diagrama de bloques



Al no estar basado en índices, un Hashtable no se puede recorrer totalmente usando el for con una sola variable. Esto no significa que no se pueda iterar sobre un Hashtable, se puede hacer a través de una enumeración.

Los métodos proporcionados por la enumeración (enumeration) permiten recorrer una colección de objetos asociada y acceder a cada uno de sus elementos.

Así, para recorrer completamente el Hashtable, se obtienen sus claves usando el método keys( ) y para cada una de las claves se obtiene su valor asociado usando get(clave).

Ejemplo:

Diagrama de bloques

Clases de utilerías


En Java existen algunas clases que sirven para apoyar el desarrollo de aplicaciones, dichas clases tienen funcionalidades generales como cálculos matemáticos, fechas, etcétera. Algunas de las clases más útiles se presentan a continuación:

Esta clase proporciona métodos para la realización de las operaciones matemáticas más habituales. Para utilizar sus métodos simplemente se coloca el nombre de la clase Math seguida del operador punto y el nombre del método a utilizar

Ejemplo:

Math.pow(5, 2);       //Eleva 5 a la potencia 2
Math.sqrt(25);       //Obtiene la raíz cuadrada de 25

En java.util se encuentran dos clases para el tratamiento básico de fechas: Date y Calendar.

Un objeto Date representa una fecha y hora concretas con precisión de un milisegundo. Esta clase permite manipular una fecha y obtener información de ésta de una manera sencilla; sin embargo, a partir de la versión 1.1 se incorporó una nueva clase llamada Calendar que amplía las posibilidades a la hora de trabajar con fechas.

Para crear un objeto de la clase Date con la fecha y hora actual se utiliza:

Date fecha = new Date( );

Usando el método toString( ) se obtiene la representación en forma de cadena de la fecha:

System.out.println(fecha.toString());

Calendar es una clase que surgió para cubrir las carencias de la clase Date en el tratamiento de las fechas. Para crear un objeto de Calendar se usa la siguiente sintaxis:

Calendar calendario = Calendar.getInstance( );

Utilizando el método get( ) se puede recuperar cada uno de los campos que componen la fecha, para ello este método acepta un número entero indicando el campo que se quiere obtener. La propia clase Calendar define una serie de constantes con los valores que corresponden a cada uno de los campos que componen una fecha y hora, por ejemplo:

Diagrama de bloques



A partir de la introducción de la versión Java 8, el manejo de las fechas y el tiempo ha cambiado. Desde esta versión, se ha creado una nueva API para el manejo de fechas y tiempo en el paquete java.time, que resuelve distintos problemas que se presentaban con el manejo de fechas y tiempo en versiones anteriores, por ejemplo:

Diagrama de bloques
ícono

Actividad. Números aleatorios

El API de Java provee clases prediseñadas que pueden ser de mucha utilidad cuando se va a implementar un programa. Asimismo, el lenguaje permite extender la funcionalidad de los tipos de datos primitivos utilizando clases especiales (Wrappers). El lenguaje también permite agrupar información de un mismo tipo en estructuras que pueden ser arreglos o colecciones, siendo estas últimas un tipo de estructura más compleja con funcionalidades que permiten resolver problemas de manera óptima.

ícono

Autoevaluación. Tipos de dato ‘referencia’ en Java

Una variable en java consta de dos elementos:

Referencia = valor


La referencia se guarda en el stack de la memoria, mientras que el valor s epuede guardar tanto en él (si es un valor primitivo) como en el heap (si es un objeto o un arreglo) El contenido de un arreglo, las cadenas y los objetos se guardan en el heap, mientras que las referencias y los valores primitivos se guardan en el stack.


Fuentes de información

Dean, J. y Dean, R. (2009). Introducción a la programación con Java. México: McGraw-Hill.

Martín, A. (2008). Programador Certificado Java 2 (2.a ed.). México: Alfaomega Grupo Editor.

Sierra, K. y Bates, B. (2008). SCJP Sun Certified Programmer for Java 6, Study Guide. Estados Unidos de América: McGraw-Hill.


Cómo citar


Solano, J. A. (2019). Utilerías y clases de uso general. Unidades de Apoyo para el Aprendizaje. CUAED/Facultad de Ingeniería-UNAM. Consultado el (fecha) de (vínculo)