Ud 03

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 116

3

ANÁLISIS Y PROGRAMACIÓN EN JAVA

Utilización de las
librerías básicas de Java
ÍNDICE
3 3.1 3.2 3.3 3.4

Principales Clases básicas para Manipulación y Gestión de


paquetes de gestión de cadenas formato de fechas. colecciones.
clases y funciones Operaciones de Trabajando con
numéricas entrada-salida streams Java.
Flujos y ficheros
3.1 Principales
paquetes de
clases
C O M E N Z A R
Principales paquetes de clases

¿Qué es
un paquete?
Un paquete es un conjunto de clases,
lógicamente relacionadas entre sí, agrupadas
bajo un nombre, incluso un paquete puede
contener otros paquetes.

Sirven para facilitar el acceso a las clases cuando las


necesitemos en un programa.
Principales paquetes de clases

La biblioteca de clases de Java


está organizada en paquetes dispuestos jerárquicamente:

J AVA

lang applet predeterminado

io net Otros paquetes

util awt
Principales paquetes de clases

Las librerías en Java


FACILITAN MUCHAS OPERACIONES.

Nos permiten reutilizar código, es decir que podemos


hacer uso de los métodos, clases y atributos que componen
la librería, creada por otro usuario, evitando así tener que
implementar nosotros mismos esas funcionalidades.

Para referirnos a una clase de un paquete utilizamos el nombre


completo, excepto cuando el paquete se ha importado.
EJEMPLO: java.lang.System
hace referencia a la clase System del paquete java.lang.
Principales paquetes de clases

Cómo crear
una librería en JAVA
Una clase de Java se puede almacenar en un archivo jar (Java Archive).
Las clases en un archivo jar se almacenan en un formato comprimido,
como un archivo zip. Un archivo jar es un contenedor portátil de clases.

Cómo crear un archivo jar en Java


TIEMPO ESTIMADO DE LECTURA
10 min

https://drive.google.com/file/d/1BscK5WTMvRTq-G4i_c7WZaKMV9Zq5izu/preview
Principales paquetes de clases

Las clases internas


SON CLASES ANIDADAS DENTRO DE OTRAS CLASES O MÉTODOS. SON
RECURSOS ESENCIALES EN EL MANEJO DE INTERFACES GRÁFICAS EN JAVA.

Una clase interna tiene acceso a todas las variables y métodos de su clase
externa y puede referirse a ellos directamente de la misma manera que lo
hacen otros miembros no estáticos de la clase externa.

TIPOS:

CLASE INTERNA ANIDADA

MÉTODO CLASES INTERNAS LOCALES

CLASES ANIDADAS ESTÁTICAS

CLASES INTERNAS ANÓNIMAS


LECTURA

Tipos de clases internas


TIEMPO ESTIMADO
5 min
TIEMPO ESTIMADO DE LECTURA
10 min

https://drive.google.com/file/d/1_yt1fAcX2-QevqUzhpw7qF4wt8OarExz/view
Principales paquetes de clases

¿Cómo se crean
los objetos?
LAS CLASES SE UTILIZAN PARA CREAR OBJETOS.
HAY QUE UTILIZAR UN OPERADOR new.

EJEMPLO: CGrados grados = new CGrados ()


En el ejemplo podemos ver que para crear un objeto de la clase CGrados
debemos especificar a continuación del operador new el nombre de la
clase del objeto seguido de (). Utilizamos () porque CGrados es un
método, y como toda clase tiene al menos un método predeterminado
especial llamado igual que ella, por defecto sin parámetros, que se invoca
cada vez que se crea un objeto; ese método es el constructor de la clase.
Principales paquetes de clases

H E R R A M I E N TA

JAVADOC
PA R A D O C U M E N TA R D E M A N E R A R Á P I DA Y
SENCILLA LAS CLASES Y MÉTODOS

JAVADOC A
C O M E N TA R I O S F O R M ATO DISTINTOS
NIVELES
Principales paquetes de clases

JAVADOC
C O M E N TA R I O S

Su estructura se caracteriza por el asterisco adicional al


principio.

EJEMPLO:
// Este es un comentario de una sola línea
/*
* Este es un comentario normal de varias líneas
*/
/**
* Este es un Javadoc
*/

También pueden contener etiquetas HTML.


Principales paquetes de clases

JAVADOC
F O R M ATO

Los comentarios de Javadoc se pueden y se deben colocar sobre


cualquier clase, método o campo que queramos documentar.

La descripción de lo que estamos


1 comentando.
C O M P U E S TO S D E :
Las etiquetas de bloque
2 independientes (marcadas con "@")
que describen metadatos específicos.

Lista completa de etiquetas de bloque:


https://docs.oracle.com/en/java/javase/11/tools/javadoc.html
Principales paquetes de clases

JAVADOC
A DISTINTOS
NIVELES A nivel de clase El ejemplo muestra una breve descripción y dos
etiquetas de bloque diferentes:

Etiquetas independientes. Aparecen después


EJEMPLO: de la descripción con la etiqueta como la
/**
primera palabra de una línea, por ejemplo, la
etiqueta @author
* Héroe es la entidad principal que usaremos para . . .
Etiquetas en línea. Pueden aparecer en
*
cualquier lugar y están rodeadas de corchetes,
* Consulte la clase {@link com.baeldung.javadoc.Person} para por ejemplo, la etiqueta @link en la
conocer la verdadera identidad descripción.
* @author Spiderman
* También podemos ver que se utilizan dos tipos
*/ de etiquetas de bloque:
public class Superhéroe de clase pública extends Persona { {@link} proporciona un enlace en línea a una
// campos y métodos parte referenciada de nuestro código fuente
} @autor el nombre del autor que agregó la
clase, el método o el campo que se comenta.
Principales paquetes de clases

JAVADOC
A DISTINTOS
NIVELES A nivel de campo

Podemos usar una descripción sin etiquetas de bloque como esta,


dentro de nuestra clase Superhéroe.

/**
* El nombre público de un héroe que es de conocimiento común
*/
private heroName;

Los campos privados no tendrán Javadoc generado para ellos a


menos que pasemos explícitamente la opción private al comando
Javadoc.
Principales paquetes de clases

JAVADOC
A DISTINTOS
NIVELES A nivel de método

Los métodos pueden contener una variedad de etiquetas de bloque Javadoc.


EJEMPLO:
/**
* Frase corta descriptiva
* Descripción del método.
* Mención al uso{@link es.loquesea.$app.util.Otra#unMetodo unMetodo}.
* @param param1 descripción del parámetro.
* @return qué devuelve el método.
* @exception tipo de excepción que lanza el método y en qué caso
* @see paquete.Clase#metodo Código al que se hace referencia
* @throws IllegalArgumentException el param1 no tiene el formato deseado
*/
Principales paquetes de clases

JAVADOC
A DISTINTOS
NIVELES A nivel variables

En este caso vamos a ver como especificar la descripción, su modificador


(private, public), si procede, y cuáles son los valores válidos o qué ocurre si su
valor es null.

EJEMPLO:
/**
* Frase corta descriptiva
* Descripción de la variable.
* Valores válidos (si aplica)
* Comportamiento en caso de que sea null (si aplica)
*/
3.2 Clases básicas
para gestión de
cadenas y
funciones
numéricas
C O M E N Z A R
Clases básicas para gestión de cadenas y funciones numéricas

Una cadena de caracteres en Java


ES UN OBJETO DE LA CLASE string

Para entenderlo podemos pensar en un objeto String como


en una cadena de caracteres almacenada en una matriz
unidimensional de elementos de tipo char, que como
recordaremos es un tipo de datos que representa a un
carácter Unicode sencillo de 16 bits.
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo
char [] cadena = nex char [40];

Este ejemplo define una matriz cadena de 40 caracteres,


cadena [0] a cadena [39], cada uno de ellos iniciado con
el valor ‘\0’.

Una cadena de caracteres es una matriz de enteros, porque


a cada carácter le corresponde un entero entre 0 y 65535
(código UNICODE).

Para leer cadenas de caracteres utilizamos el método read,


por lo que si queremos almacenar una cadena de
caracteres en una matriz debemos ejecutar varias veces el
método read y guardar cada carácter leído en el siguiente
elemento libre de esa matriz de caracteres.
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo
En el ejemplo observamos
char [] cadena = nex char [40]; cómo se define la variable
int i = 0, car; cadena como una matriz de
try caracteres de longitud 40, y a
{ continuación establece un bucle
System.out.print ("Introducir un texto: "); para leer los caracteres que
while ((car = System.in.read()) != ‘\r‘ && i < cadena.length) tecleamos hasta que se
{ completa la matriz.
cadena[i] = (char) car;
i++; Cada carácter leído se almacena
} en el siguiente elemento libre
System.out.println("Texto introducido: " + cadena);
de cadena.
System.out.println("Longitud del texto: " + i);
Por último, vemos el contenido
System.out.println("Dimensión de la matriz: " + cadena.length);
de cadena, el número de
}
caracteres almacenados y la
catch(IOException ignorada) {} dimensión de la matriz.
Clases básicas para gestión de cadenas y funciones numéricas

La clase String
P E R T E N E C E A L PAQ U E T E java.lang.

Un objeto String representa una cadena de caracteres que no se puede modificar, por lo tanto las
operaciones no modificarán el objeto original sino que devolverán uno nuevo.

String ofrece métodos para examinar caracteres individuales de una cadena de caracteres, comparar
y copiar cadenas, buscar y extraer subcadenas, convertir cadenas a minúsculas o mayúsculas.

Operador +

Se utiliza para concatenar objetos String y para convertir otros objetos a


objetos String.

EJEMPLO:

System.out.println("Dimensión de la matriz: " + cadena.length);


Clases básicas para gestión de cadenas y funciones numéricas

Métodos de la clase String


String String trim

int compare To boolean startsWith

int length() boolean endsWith

String toLowerCase() String substring

String toUpperCase() static String valueOf


Clases básicas para gestión de cadenas y funciones numéricas

String (String valor)

Ya sabemos que todas las clases tienen al menos un método predeterminado que se
llama igual que ella y que debemos invocar para crear un objeto, es lo que conocemos
con el constructor de la clase.

La clase String proporciona varias formas de su constructor String, una para crear un
objeto String a partir de un literal, otra para crearlo a partir de otro String, etc…

Ejemplo
String strl = "abc"; //crea un String "abc"
String str2 = new String("def"); //crea un String "def"
String str3 = new String(strl); //crea un nuevo String "abc"

char[] cadena = new char[40]; // matriz de 40 caracteres


// …
String str4 = new String(cadena);
Clases básicas para gestión de cadenas y funciones numéricas

int compare To (String otro String)

Este método nos permite saber si una cadena está en orden alfabético antes
que otra, comparando las cadenas carácter por carácter.

Compara lexicográficamente el String especificado con el objeto String


que recibe el mensaje compareTo. El resultado que devuelve es un entero:

• <0 si el String que recibe el mensaje es menor que el otro String.

• =0 si el String que recibe el mensaje es igual que el otro String.

• >0 si el String que recibe el mensaje es mayor que el otro String.

Ejemplo
String str1 = "abcde", str2 = "abcdefg";
if (str1.compareTo(str2) <0)
System.out.println(str1);
Clases básicas para gestión de cadenas y funciones numéricas

int length()
Devuelve el número de caracteres del objeto String
que recibe el mensaje de length.

Ejemplo
String str1 = "La provincia de Madrid es muy bonita";
System.out.println("Longitud: " + str1.length());

El resultado es: Longitud: 36


Clases básicas para gestión de cadenas y funciones numéricas

String toLowerCase()
Con este método se convierten las letras mayúsculas
del objeto String en minúsculas.

Ejemplo
String S1 = new String("MAYÚSCULA CONVERTIDA EN MINÚSCULA");
// Convertir a LowerCase
System.out.println(S1.toLowerCase());
Clases básicas para gestión de cadenas y funciones numéricas

String toUpperCase()
Al contrario que el anterior, este método convierte las
letras minúsculas en mayúsculas.

Ejemplo
String S1 = new String("minúsculas convertidas en mayúsculas");
// Convertir a UpperCase
System.out.println(S1.toUpperCase());
Clases básicas para gestión de cadenas y funciones numéricas

String trim
En este caso, este método devuelve un objeto String resultado
de eliminar los espacios en blanco que pueda haber al principio
y al final del objeto String que recibe el mensaje trim.

Ejemplo
String sCadena = " Esto Es Una Cadena" ;
System.out.println(sCadena.trim()); //Devuelve "Esto Es Una Cadena"
Clases básicas para gestión de cadenas y funciones numéricas

boolean startsWith (String prefijo)

Este método devuelve un valor true si el prefijo especificado coincide con


el prefijo del objeto String que recibe el mensaje startsWith..

Ejemplo
int contador = 0;
String sInicio = "ca";
String sTexto;
Scanner reader = new Scanner(System.in);
System.out.println("Escribe palabras que empiecen por '" + sInicio + "'");
sTexto = reader.next();

while(sTexto.startsWith("ca")) {
System.out.println("Correcto... " + sTexto);
contador++;
System.out.println("Dime otra palabra...");
sTexto = reader.next();
}
Clases básicas para gestión de cadenas y funciones numéricas

boolean endsWith (String sufijo)

En este caso, devuelve un valor true si el sufijo especificado coincide con el final del
objeto String que recibe el mensaje endsWith.

Ejemplo
public class EmailsAcabadosEnDotCom {
public static void main(String[] args) {

String emails[] =
{"[email protected]","[email protected]","[email protected]","[email protected]","[email protected]",

"[email protected]","[email protected]","[email protected]","[email protected]"};

for (String email: emails)


if (email.endsWith(".com")) System.out.println(email);
}
}
Clases básicas para gestión de cadenas y funciones numéricas

String substring
Este método devuelve un nuevo String que encapsula una
subcadena de la cadena almacenada por el objeto String.

La subcadena empieza en IndiceInicial y se extiende


hasta IndiceFinal -1, o hasta el final si IndiceFInal no
se especifica.

Ejemplo
String str1 = " abcdefgh ", str2 = "";
str1 = str1.trim();
if (str1.endsWith("gh"))
str2 = str1.substring(0, str1.length() - "gh".length());
Clases básicas para gestión de cadenas y funciones numéricas

static String valueOf


Este método devuelve un nuevo String creado a partir del
dato pasado como argumento, que puede ser de tipo
boolean, char, char [], int, long, float, double
y Object.

Ejemplo
double pi = Math.PI;
String str1 = String.valueOf(pi);
Clases básicas para gestión de cadenas y funciones numéricas

Un objeto Stringbuffer
E S U N O B J E TO M O D I F I C A B L E E N C O N T E N I D O Y E N TA M A Ñ O

Métodos más interesantes:

StringBuffer

StringBuffer insert

StringBuffer delete

StringBuffer replace
Clases básicas para gestión de cadenas y funciones numéricas

StringBuffer([arg])
Este método permite crear un objeto de la clase
Stringbuffer. Existen 3 formas de invocarlo:

StringBuffer str1 = new StringBuffer();


StringBuffer str2 = new StringBuffer(80);
StringBuffer str3 = new StringBuffer("abcde");

System.out.println(strb1 + " " + strb1.length()+ " " +


strb1.capacity());
System.out.println(strb2 + " " + strb1.length()+ " " +
strb2.capacity());
System.out.println(strb3 + " " + strb3.length()+ " " +
strb3.capacity());

Los resultados serían estos:


0 16 0 80 abcde 5 21
Clases básicas para gestión de cadenas y funciones numéricas

StringBuffer([arg])
Según lo que muestran estos ejemplos, entendemos que:

Si Stringbuffer se invoca sin argumentos construye un


objeto vacío con una capacidad inicial para 16 caracteres.

Cuando invoca con un argumento entero construye un


objeto vacío con la capacidad especificada.

Cuando se invoca con un String como argumento


construye un objeto con la secuencia de caracteres que
proporciona el argumento y una capacidad igual al numero
de caracteres almacenados más 16.
Clases básicas para gestión de cadenas y funciones numéricas

StringBuffer insert (int índice, tipo x)

Con este método se puede insertar la cadena de caracteres que resulta de


convertir el argumento x en un objeto String, en el objeto StringBuffer
que recibe el mensaje insert.

Los caracteres se añaden a partir de la posición especificada por el


argumento índice. El tipo del argumento puede ser boolean, char, char
[], int, long, float, double, String y Object.

La longitud del objeto StringBuffer se incrementa en la longitud


correspondiente al String insertado.
Clases básicas para gestión de cadenas y funciones numéricas

StringBuffer insert (int índice, tipo x)

Ejemplo
StringBuffer strb = new StringBuffer("Mes de del año ");
strb.insert("Mes de ".length(), "Mayo "); // "Mes de ".length ()=7
strb.append(2022);

Según el ejemplo vemos como se crea un objeto StringBuffer con la cadena


“Mes de del año”, para después insertar la cadena “Mayo” a partir de la posición
7 y al final añade la cadena representativa del entero 2022.

El resultado es “Mes de Mayo del año 2022”


Clases básicas para gestión de cadenas y funciones numéricas

StringBuffer delete (int p1, int p2)

Utilizamos este método para eliminar los caracteres que hay entre las
posiciones p1 y p2 del objeto StringBuffer que recibe el mensaje delete.

P2 debe ser mayor que p1. Si p1 es igual a p2 no se realizará ningún


cambio y si es mayor Java lanzará una excepción.

Ejemplo
StringBuffer strb = new StringBuffer("Mes de del año ");
strb.insert(7, "Mayo ");
strb.append(2022);
strb.delete(7, 13);
strb.insert(7, "Junio ");

Vemos cómo se elimina la subcadena “Mayo” del objeto strb y se añade en su misma
posición la cadena “Junio”.

El resultado será “Mes de Junio de 2022”.


Clases básicas para gestión de cadenas y funciones numéricas

StringBuffer replace (int p1, int p2, String str)

Utilizamos este método para eliminar los caracteres que hay entre
las posiciones p1 y p2 del objeto StringBuffer que recibe el
mensaje replace, por los caracteres especificados por str.

Longitud y capacidad del objeto que resulta se ajustan


automáticamente al valor requerido.

P2 debe ser mayor que p1. Si p1 es igual que p2 la operación se


convierte en una inserción y si es mayor Java lanza una excepción.

Ejemplo
StringBuffer strb = new StringBuffer("Mes de del año ");
strb.insert(7, "Mayo ");
strb.append(2022);
strb.replace(7, 12, "Junio ");
System.out.println(strb);

El resultado será: Mes de Junio del año 2022


Clases básicas para gestión de cadenas y funciones numéricas

La clase StringTokenizer
Pe r m i t e r e a l i z a r a n á l i s i s l ex i c o g r á f i c o s s o b r e c a d e n a s
de caractereres, devolviendo subcadenas de la misma,
(tokens) divididas mediante varios delimitadores, los
c ua l e s s e pue d e n pe r s ona l iz a r, o c a mb ia r s e g ún s e v a n
obteniendo tokens de la cadena.
Clases básicas para gestión de cadenas y funciones numéricas

CLASE StringTokenizer

Constructores
StringTokenizer (String cadena);: devuelve un StringTokenizer que
divide la cadena con los delimitadores por defecto: espacio, tabulador, nueva
línea, retorno de carro y avance de página.

StringTokenizer (String cadena, String delimitadores);:


devuelve un StringTokenizer que divide la cadena de entrada siempre que se
encuentre cualquiera de los caracteres presentes en el String delimitadores.
Los delimitadores no se devuelven como tokens.

StringTokenizer (String cadena, String delimitadores,


boolean returnDelims);: Igual que el anterior pero además, ofrece la
posibilidad de indicarle que devuelva los delimitadores como tokens.
Clases básicas para gestión de cadenas y funciones numéricas

Acciones
PA R A A N A L I Z A R U N string:

1 2 3

PREGUNTAR PEDIR CONOCER


si hay más tokens el siguiente token cuántos tokens quedan
(hasMo-reTokens();) (String nextToken();) por obtener int
countTokens();.

Ejemplo
// Crea un tokenizer que separa por comas una frase
StringTokenizer tokenizer = new StringTokenizer("Prueba a leer cadenas, " +
"siempre que estén separadas por comas, sin devolver los delimitadores"
,",");
while(tokenizer.hasMoreTokens()){ Según el ejemplo se imprimirá
System.out.println(tokenizer.nextToken()); por pantalla una sentencia,
} separándola por las comas.
Clases básicas para gestión de cadenas y funciones numéricas

Operaciones más habituales


SOBRE CADENAS DE CARACTERES

Ejemplo 1

Recupera la letra U del String “Hola mUndo”,


imprimiendo el índice en el que se encuentra
dentro de la cadena.

String str = "Hola mUndo!";


int index = -1;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'U') {
index = i;
break;
}
}
System.out.println("El caracter: " + str.charAt(index) + ", está en la posición: " + index);
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo 2

Encuentra la última aparición de la cadena “Hola” dentro de: "Hola mundo ,Hola amigo".

String strOrig = "Hola mundo ,Hola amigo";


int lastIndex = strOrig.lastIndexOf("Hola");
if (lastIndex == -1) {
System.out.println("No se ha encontrado Hola");
} else {
System.out.println("La última aparición de Hola empieza en la posición: " +
lastIndex);
}
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo 3

Corrige la frase eliminando la letra que sobra: "Esto ess Java!".

String myStr = "Esto ess Java!";

int indexToDelete = myStr.lastIndexOf("s");

System.out.println(myStr.substring(0, indexToDelete) + myStr.substring(indexToDelete + 1));


Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo 4
Da la vuelta a la cadena: "abcdef"

String string = "abcdef";


String reverse = new StringBuffer(string).reverse().toString();
System.out.println("Antes de darle la vuelta: " + string);
System.out.println("Después de darle la vuelta: " + reverse);

Ejemplo 5
Da la vuelta a la cadena: "Curso de Java!",
pero sin utilizar StringBuffer.

String input = "Curso de Java!";


char[] try1 = input.toCharArray();

for (int i = try1.length-1;i >= 0; i--)


System.out.print(try1[i]);
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo 6

Separa los meses de la cadena: "enero-febrero-


marzo", e imprímelos por separado en consola.

String str2 = "enero-febrero-marzo";


String[] temp;
String delimeter = "-";
temp = str2.split(delimeter);

for (int i = 0; i < temp.length; i++) {


System.out.println(temp[i]);
}

// Otra forma de imprimirlos:

for (String s : temp) {


System.out.println(s);
}
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo 7
Forma la frase: "Hola querido alumno de Java", a partir de las cadenas: "Hola", "querido",
"alumno" y "de Java", por dos métodos diferentes.

String cadena1 = "Hola";


String cadena2 = "querido";
String cadena3 = "alumno";
String cadena4 = "de Java";

System.out.println(cadena1 + " " + cadena2 + " " + cadena3 + " " + cadena4);

StringBuffer result = new StringBuffer();

result.append(cadena1);
result.append(" ");
result.append(cadena2);
result.append(" ");
result.append(cadena3);
result.append(" ");
result.append(cadena4);

System.out.println(result);
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo 8
Forma la frase: "Hola mundo", a partir de las cadenas: "Hola" y
"mundo", por un método diferente a los dos del ejercicio anterior.

String s = "Hola";
s = s.concat(" ");
s = s.concat("mundo");
System.out.print(s);

Ejemplo 9
Pon en mayúsculas la frase: "esta frase va en mayúsculas".

String str = "esta frase va en mayúsculas";


String strUpper = str.toUpperCase();
System.out.println("Frase original: " + str);
System.out.println("Frase en mayúsculas: " + strUpper);
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo 10
Observa las siguientes transformaciones de cadenas:

String name = "Hola mundo";


String s1 = String.format("Frase: %s", name);
String s2 = String.format("valor: %f",32.33434);
String s3 = String.format("valor: %32.12f",32.33434);
System.out.print(s1);
System.out.print("\n");
System.out.print(s2);
System.out.print("\n");
System.out.print(s3);
System.out.print("\n");

Se obtienen las siguientes salidas:

Frase: Hola mundo


valor: 32,334340
valor: 32,334340000000
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo 11
Imprime el código Unicode del carácter 5 en la frase: "Bienvenido al curso de Java ".

String test_string = "Bienvenido al curso de Java";


System.out.println("El texto de prueba es: " + test_string);

System.out.println("El código Unicode en la posición 5 es: " +


test_string.codePointBefore(5));

System.out.println("v".codePointBefore(1));

System.out.println(test_string.charAt(4));

// Obsérvese que el método codePointBefore va desde 1 hasta length del String


Clases básicas para gestión de cadenas y funciones numéricas

Funciones numéricas
Las funciones numéricas en Java se refieren a un
conjunto de métodos y clases que se utilizan para
realizar operaciones aritméticas como la adición, la
multiplicación, la división y el cálculo del resto.
Estas funciones se proporcionan en la clase Math.
La clase Math contiene métodos para ejecutar
operaciones numéricas elementales tales como raíz
cuadrada, exponencial, logaritmo, y funciones
trigonométricas.
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo

double raíz_cuadrada , n = 345.0;

raíz_cuadrada = Math.sqrt(n);

System.out.println("La raíz cuadrada de " + n +


" es " + raíz_cuadrada);
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo Math.abs()

int num = -10;

int absVal = Math.abs(num);

// absVal es igual a 10

Esta función devuelve el valor


absoluto de un número entero o de
un número de punto flotante.
Clases básicas para gestión de cadenas y funciones numéricas

Ejemplo Math.pow()

int base = 2;

int exponente = 3;

double resultado = Math.pow

Esta función devuelve el resultado


de una base elevada a un
exponente.
Clases básicas para gestión de cadenas y funciones numéricas

En el siguiente enlace podemos ver todos


los métodos de la clase Math de Java.

¡Vamos a verlo!
3.3 Manipulación y
formato de
fechas.
Operaciones de
entrada-salida
C O M E N Z A R
Manipulación y formato de fechas. Operaciones de entrada -salida

Existen múltiples opciones para manejar fechas en Java:

Java Calendar
Ejemplo:
La clase Java Calendar se utiliza para SimpleDateFormat sdf = new SimpleDateFormat("dd/M/yyyy");
representar y manipular fechas y horas. Esta String date = sdf.format(new Date());
clase proporciona métodos para convertir System.out.println(date); //27/01/2023
entre diferentes representaciones de fechas,
y para realizar operaciones aritméticas
sobre ellas. Uno de los usos más comunes Salida:
es calcular la fecha de hoy o la fecha de 27/01/2023
mañana a partir de la fecha actual.
Manipulación y formato de fechas. Operaciones de entrada -salida

Ejemplo:
LocalDate date = LocalDate.now();
Java Time System.out.println(date);

Incluye muchas clases, pero las básicas son:


Instant: Se usa para almacenar un punto Salida:
determinado en el tiempo (con fecha y hora) Es El código anterior tendrá la siguiente salida (entendiendo que se escribió el 27-
muy útil si queremos manejar momentos en el 01-2023):
tiempo de manera neutra e intercambiarlo entre
2023-01-27
aplicaciones y sistemas.
LocalDate: Almacena una fecha sin hora.
Podemos utilizarla si queremos almacenar un LocalDate date2 = LocalDate.of(2023, 01, 27);
cumpleaños.
LocalDate date3 = LocalDate.parse("2023-01-27");

Salida:
Las dos expresiones crearán objetos de tipo LocalDate con la fecha 27-01-2023.
Manipulación y formato de fechas. Operaciones de entrada -salida

LocalTime:
Almacena una hora sin fecha. Es interesante si queremos almacenar por
ejemplo una hora de apertura o cierre.

Java Time Ejemplo:


LocalTime time = LocalTime.now();
Incluye muchas clases, pero las básicas son:
LocalTime time2 = LocalTime.parse("11:00:59.759");
Instant: Se usa para almacenar un punto
determinado en el tiempo (con fecha y hora) Es LocalTime time3 = LocalTime.of(11, 00, 59);
muy útil si queremos manejar momentos en el System.out.println(time);
tiempo de manera neutra e intercambiarlo entre
System.out.println(time2);
aplicaciones y sistemas.
System.out.println(time3);
LocalDate: Almacena una fecha sin hora.
Podemos utilizarla si queremos almacenar un
cumpleaños.
Salida:
11:02:06.198
11:00:59.759
11:00:59
Manipulación y formato de fechas. Operaciones de entrada -salida

LocalDateTime:
Almacena una fecha y una hora.
Ejemplo:
LocalDateTime dateTime = LocalDateTime.now();

Java Time LocalDateTime dateTime1=LocalDateTime.of(2018, 10, 10, 11, 25);


LocalDateTime dateTime2=LocalDateTime.parse("2018-10-10T11:25");
Incluye muchas clases, pero las básicas son:
Instant: Se usa para almacenar un punto
determinado en el tiempo (con fecha y hora) Es System.out.println(dateTime);
muy útil si queremos manejar momentos en el System.out.println(dateTime1);
tiempo de manera neutra e intercambiarlo entre
aplicaciones y sistemas. System.out.println(dateTime2);

LocalDate: Almacena una fecha sin hora.


Podemos utilizarla si queremos almacenar un Salida:
cumpleaños.
2018-10-30T11:46:58.274
2018-10-10T11:25
2018-10-10T11:25

ZonedDateTime: Almacena una fecha y hora con una zona horaria.


Duration and Period. Más allá de fechas y horas, la API también permite el
almacenamiento de periodos y duraciones de tiempo.
Manipulación y formato de fechas. Operaciones de entrada -salida

Joda-time
Es una biblioteca gratuita y Open Source.
Es fácil de usar y fácil de extender ya que
admite múltiples sistemas de calendario
a través de un sistema conectable basado
en la clase Chronology.
La biblioteca está diseñada para
proporcionar toda la funcionalidad
necesaria para los cálculos de fecha y
hora.
Dispone de cálculos de zona horaria actualizados y de un conjunto
completo de pruebas para desarrolladores que garantiza la calidad de
la biblioteca.
Hay una Guía completa de usuario que proporciona respuesta a las
cuestiones más planteadas por los desarrolladores.
3.4 Gestión de
colecciones.
Trabajando con
streams Java.
Flujos y ficheros
C O M E N Z A R
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Una colección
ES UN OBJETO QUE REPRESENTA UN GRUPO DE OBJETOS

A veces necesitamos implementar una funcionalidad


determinada que opere sobre cualquier tipo de
datos para que cualquier clase pueda beneficiarse de
esa funcionalidad.

Un ejemplo de esa funcionalidad genérica son las


clases de colecciones.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

E N J AVA C O N TA M O S C O N

El mecanismo de los genéricos


PARA INDEPENDIZAR LA IMPLEMENTACIÓN DE UNA CLASE DE
LOS TIPOS DE DATOS QUE UTILIZA.

De este modo se puede particularizar el uso de una clase


genérica indicando en cada caso la clase con la que
queremos trabajar, y así se eliminan errores en tiempo de
ejecución y se trasladan a la fase de compilación, donde el
compilador puede realizar comprobaciones acerca de los
tipos de datos utilizados.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Definición de clases genéricas


DEFINIR UNA CLASE COMO GENÉRICA:

Debemos introducir una variable de tipo en la declaración.

Esta variable va a ser la que se utilice durante la implementación


de la propia clase para referirse al tipo de datos que se contendrá.

Sintaxis
[modif_clase] class NombreClase <IdentTipo> {
// Implementación de la clase
}
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Ejemplo para la clase Paquete que contiene dos instancias de una clase concreta habría
que declararla de la siguiente manera:
Ejemplo
public class Paquete <T> {
T primero;
T segundo;
public Paquete(T primero, T segundo){
this.primero = primero;
this.segundo = segundo;
}
public T getPrimero(){
El identificador T que hemos
return this.primero; utilizado en el ejemplo para
} referirnos a la variable de tipo
en la declaración, es el
public T getSegundo(){ parámetro de tipo formal.
return this.segundo; Puede ser cualquier
} identificador siempre que siga
las reglas de nombrado de Java.
}
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

IDENTIFICADORES DE UNA

Única letra mayúscula


DE ESTE MODO ES MÁS FÁCIL DISTINGUIR LOS PARÁMETROS
DE TIPO FORMAL DE LAS CLASES E INTERFACES.

LETRAS PARA IDENTIFICAR ELEMENTOS CONCRETOS:

E Se utiliza para elementos de las colecciones.

K Se utiliza para las claves como las de las tablas hash.

N Para los números.

T Para los tipos.

V Para los valores.

S/U Se utilizan cuando se usa más de un tipo.


G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Cuando se declara la clase


U T I L I Z A M O S E L PA R Á M E T R O D E T I P O F O R M A L PA R A I D E N T I F I CA R
E L T I P O D E LO S O B J E TO S M A N E J A D O S , TA N TO PA R A A R G U M E N TO S
Y T I P O S D E S A L I DA , C O M O E N VA R I A B L E S Y AT R I B U TO S D E L A C L A S E .

También en las interfaces se puede aplicar la declaración de genéricos.

Si se declara una interfaz de forma genérica, las clases que implementen


la interfaz tendrán que declararse igualmente de forma genérica.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

InterfazGenerica
Ejemplo
public interface InterfazGenerica <T> {
// contenido de la interfaz
}

ClaseGenerica
Ejemplo
public class ClaseGenerica <T> implements InterfazGenerica <T> {
// contenido de la clase
}
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

El uso de genéricos Por ejemplo, vamos a declarar una clase nueva PaqueteDual
que contenga dos objetos de dos clases distintas:
N O E STÁ L I M I TA D O A U N T I P O
POR CLASE.
Ejemplo
Podemos declarar dos variables de tipo, public class PaqueteDual <T,U> {
o mas, en la declaración de la misma, T primero;
utilizando diferentes identificadores. U segundo;

public PaqueteDual(T primero, U segundo){


this.primero = primero;
this.segundo = segundo;
}

public T getPrimero(){
return this.primero;
}

public U getSegundo(){
return this.segundo;
}}
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Uso de clases genéricas


PARA USARLAS:

Debemos hacer una invocación genérica de tipo, donde


se reemplace el parámetro de tipo formal de la clase con
un valor concreto que será el nombre de una clase.

Para hacer esto se declara un objeto de la clase genérica en


la que se añade el nombre de la clase en la que queremos
particularizar el genérico, entre los caracteres < y >.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Paquete<String> paqueteDeCadenas;

Ejemplo La declaración del objeto paqueteDeCadenas de tipo Paquete<String>


implica que dicho objeto sólo podrá contener objetos de tipo String,
pero no limita que se puedan crear paquetes de cualquier otra clase,
parametrizando la clase genérica sobre diferentes tipos de datos.

Cuando se declara un objeto de una clase genérica, ésta pasa a ser


un tipo parametrizado.

En nuestro ejemplo, Paquete<String> es una nueva clase. Para instanciar esta


clase utilizamos la palabra reservada new, de igual forma que para instanciar
cualquier otro objeto, pero indicando el parámetro de tipo en el constructor:

paqueteDeCadenas = new Paquete<String>(”primer String”,”segundo


String”);
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Una vez inicializado el objeto


SE PUEDE INVOCAR A SUS MÉTODOS SIN TENER QUE INDICAR EL
PARÁMETRO DE TIPO FORMAL NI REALIZAR NINGÚN CASTING.

Según nuestro ejemplo, la invocación del método


paqueteDeCadenas.getPrimero() devuelve un objeto
de tipo String.

El tipo parametrizado se puede utilizar como parámetro


de tipo formal en otra clase, de este modo podremos
declarar objetos de tipo Paquete<Paquete<Integer>>,
que serían paquetes que contendrían instancias del tipo
Paquete<Integer>.

La relación de herencia entre dos clases no se traslada


a los genéricos particularizados en dichas clases.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Métodos y constructores genéricos


LA DECLARACIÓN DE ELEMENTOS GENÉRICOS NO SE LIMITA A LAS CLASES,
TAMBIÉN SE PUEDEN DEFINIR TANTO MÉTODOS COMO CONSTRUCTORES.

DEFINICIÓN MÉTODO GENÉRICO:

Se establece un parámetro de tipo formal en la declaración del


método, encerrado entre < >, situado entre los modificadores
y el tipo de retorno del método.

Ejemplo
[modif_método] <IdentTipo> tipoRetorno nombreMétodo (args) {
// implementación
}
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las colecciones
UNO DE LOS USOS MÁS COMUNES DE LOS GENÉRICOS

DEFINICIÓN
Las colecciones son un conjunto de clases que aportan
! funcionalidad específica a la hora de almacenar múltiples
instancias de cualquier otra clase, ofreciendo diferentes
estructuras de datos de tamaño dinámico como arrays,
pilas, colas, tablas hash, etc.

La descripción completa de estas clases podemos


encontrarla en la API de Java, nosotros aquí vamos
a ver algunos de los elementos más relevantes que
forman la implementación de colecciones de Java.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

LAS COLECCIONES SE ORGANIZAN

En torno a diferentes jerarquías


QUE PARTEN DE DIFERENTES INTERFACES QUE DEFINEN EL CONJUNTO
DE MÉTODOS QUE TIENE CADA FAMILIA DE COLECCIONES.

Interfaz Collection<E>. Define una funcionalidad Si las clases que utilizamos implementan esta interfaz,
genérica para cualquier colección como el método para se pueden recorrer de una manera estándar,
añadir nuevos elementos, add(E e). independientemente del tipo de clase que sean.

El método contains(Object o);. Permite comprobar


si un objeto se encuentra en la colección.

El método size();. Devuelve el número de elementos


contenidos.

El método iterator();. Devuelve un iterador para


recorrer la colección.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Otras interfaces
EXTIENDEN A ÉSTA:

Set<E> Representa el concepto matemático de conjunto. Veremos


esta interfaz con detalle más adelante.

List<E> Representa listas de tamaño variable de elementos donde


se puede controlar la posición de los mismos. También la
veremos en detalle más adelante.

Queue<E> Representa una colección indicada especialmente para


almacenar elementos antes de ser procesados.

Map<K,V> No forman parte de la jerarquía de Collection, aunque se


utilizan para contener múltiples elementos. Los mapas se
utilizan para asociar a los valores claves que no pueden
estar repetidas dentro del mapa, aunque sí los objetos a
los que representan. La veremos en detalle más adelante.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

La interfaz Iterable<E>
SE UTILIZA ÚNICAMENTE PARA DEFINIR CONJUNTOS DE VALORES
QUE PUEDAN SER RECORRIDOS.

Para que La interfaz Collection<E> extienda Iterable<E>, define el


método iterator(), y esto devuelve un objeto que implementa la interfaz
Iterator<E>, que permite recorrer de forma secuencial todos los objetos
presentes en la colección.

Métodos que contienen Iterator<E>:

b o o l e a n h a s N e x t ( ) ; permite averiguar si un iterador tiene


1 más elementos que ofrecer.

E n e x t ( ) ; devuelve el elemento en la posición actual de la


2 colección y avanza una posición.

3 v o i d r e m o v e ( ) ; elimina de la colección el último elemento


obtenido por medio de una llamada a next();.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Ejemplo public <E> void recorrer(Collection<E> coleccion){


Iterator<E> iterador = coleccion.iterator();
E elemento;
while(iterador.hasNext()){
elemento = iterador.next();
System.out.println(elemento);
}
}

En este método se utilizan los recursos de la interfaz Iterable y


permite recorrer cualquier colección.
El método recorrer se define como genérico para establecer un
control sobre los elementos que se extraen de la interfaz.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Podemos implementar un método similar que utilice la colección como un raw type, empleando instancias
de Object en lugar de instancias de la clase concreta que contiene la colección:

public void recorrerObjetos(Collection coleccion){


Iterator iterador = coleccion.iterator();
Object elemento;
while(iterador.hasNext()){
elemento = iterador.next();
System.out.println(elemento);
}
}

A partir de Java 1.8, se implementan streams y expresiones labmda para


recorrer colecciones según el paradigma de programación funcional con
una sintaxis más reducida y simplificada, pero esta cuestión escapa del
alcance de este curso básico.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las colecciones List


MANTIENEN LOS ELEMENTOS EN ORDEN Y UTILIZAN ESE ORDEN
PARA ACCEDER, AÑADIR, OBTENER O ELIMINAR ELEMENTOS.

Las listas implementan la interfaz List<E>, y las más relevantes son:

ArrayList<E>. Son arrays de tamaño variable que permiten


todo tipo de elementos. Permiten un acceso a los elementos y
1 la obtención del iterador bastante rápidos. La capacidad de
cada instancia es el tamaño del array interno que se utiliza
para almacenar los elementos.

LinkedList<E>. Es una lista compuesta de elementos


doblemente enlazados, en los que cada nodo conoce cuál es
2
su anterior y posterior. Podemos utilizar LinkedList<E> para
eliminar o insertar elementos al principio y al final de la lista.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

ArrayList<E> ArrayList<String> palabras = new ArrayList<String>();

Ejemplo palabras.add("supercalifragilisticuespialidoso");
// Añadir más elementos
while (palabras.remove("carro")){
// Borrar todas las ocurrencias de cierta palabra
// No hacen falta más acciones
}
String[] arrayPalabras = new String[1];
arrayPalabras = palabras.toArray(arrayPalabras);
// El array se usa si caben los elementos
// Si no se devuelve uno nuevo

En el ejemplo vemos como se utiliza un ArrayList en la que se introducen


cadenas, y se eliminan después todas las cadenas que contienen la palabra
“carro” para devolver un array de String con las palabras restantes.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

public Integer[] insertarAlternativo(int[] entrada){


LinkedList<Integer> salida = new LinkedList<Integer>();
LinkedList<E> Integer[] resSalida = new Integer[1];
Ejemplo int anterior = 0;
for (int i=0; i<entrada.length; i++){
if (anterior <= entrada[i]){
salida.addFirst(new Integer(entrada[i]));
}
else{
salida.addLast(new Integer(entrada[i]));
}
}
resSalida = salida.toArray(resSalida);
return resSalida;
}

En el ejemplo vemos como, usando los métodos addFirst(<E> e); y


addLast(<E> e); (aportados por LinkedList), a partir de un array de enteros,
se van extrayendo y colocando al principio o final de la lista según de si el
número recibido es mayor o menor que el anterior.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

La interfaz Set<E>
S E U T I L I Z A PA R A R E P R E S E N TA R CO N J U N TO S .

Los conjuntos son colecciones representadas por la


interfaz Set<E> en los que no existen elementos repetidos.

También son colecciones especialmente adecuadas para


comprobar la presencia de elementos puesto que su
implementación del método contains(Object item); es
muy eficiente debido a que no se tienen que recorrer todos
los elementos contenidos como en otras colecciones.

CLASES QUE HashSet<E>


LA IMPLEMENTAN:
TreeSet<E>
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

LO S M A PA S S O N CO N J U N TO S D E
OBJETOS, LLAMADOS VALORES,
QUE TIENEN ASOCIADOS UNA
CLAVE QUE LOS IDENTIFICA.

Se representan por la interfaz Map<K,V>.


G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Hashtable<K,V>
E S L A I M P L E M E N TAC I Ó N D E U N A TA B L A hash.

Estas tablas son contenedores asociativos (tipo Diccionario) que


permiten un almacenamiento y posterior recuperación eficientes de
elementos (valores) a partir de otros objetos, llamados claves.

Esta tabla hash realiza el acceso a los elementos por medio de su clave.

Esta clase implementa una tabla hash de tipo abierto, en la que si los
hash de varias claves colisionan, sus correspondientes valores se
alojan bajo el mismo punto de entrada.

El factor de carga se controla ampliando su capacidad según se añaden


más elementos, y reduciendo así las colisiones.

Esta clase no permite que las claves o los valores sean nulos, y está
sincronizada para permitir un acceso concurrente a sus métodos.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Ejemplo de uso de una tabla hash para almacenar valores textuales


mediante claves también textuales.

Ejemplo
Hashtable<String,String> tabla = new Hashtable<String,String>();
tabla.put("nombre", "Francisco Sánchez");
tabla.put("dirección", "C/ La Fresa S/N");
tabla.put("telefono", "91555443322");
tabla.put("email", "[email protected]");
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

TA B L A h a s h

Para extraer toda la información


SE UTILIZAN LAS MISMAS CLAVES QUE SE HAN
U T I L I Z A D O PA R A I N T R O D U C I R E S A I N F O R M AC I Ó N :

System.out.println("Nombre: " + tabla.get("nombre"));


System.out.println("Dirección de correo electrónico: "+
tabla.get("email"));
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

TreeMap<K,V>
E S U N M A PA Q U E A L M AC E N A L A S C L AV E S O R D E N A DA S
S I G U I E N D O S U O R D E N N AT U R A L , AT E N D I E N D O A L A
I M P L E M E N TAC I Ó N D E L M É TO D O c o m p a r e T o ( ) ; .

Esta clase implementa también la interfaz


NavigableMap, por lo que los elementos que
contienen se pueden recorrer en función de la relación
de orden en tres de sus claves, tal y como describen
los métodos de dicha interfaz.

Esta clase garantiza complejidad logarítmica en las


operaciones de inserción (put), acceso (get),
eliminación (remove) y comprobación de existencia
de elementos (containsKey) por la relación de orden
que hay entre las claves.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Ejemplo
public static void main(String[] args) {
TreeMap <String,Integer> mapaNumeros = new
TreeMap<String,Integer>();
mapaNumeros.put("uno", 1);
mapaNumeros.put("dos", 2);
...
mapaNumeros.put("diez", 10);
for (String s: mapaNumeros.descendingKeySet()){
System.out.print(mapaNumeros.get(s));
}
System.out.print("\n------------\n");
for (String s: mapaNumeros.headMap("ocho", false).keySet()){
System.out.print(mapaNumeros.get(s));
}
}
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

En el ejemplo vemos como se crea un TreeMap cuyas claves son


Strings y que contiene valores de tipo Integer.

Después se introducen los enteros de 1 a 10, utilizando como


clave el nombre del número.

Como es un mapa ordenado, se ordenan los elementos según su


clave, que al ser un String, se ordenan en orden lexicográfico.

La llamada al método descendingKeySet() devuelve un conjunto


con sus claves ordenadas de forma inversa, y la llamada a
headMap() devuelve todas las claves inferiores a la clave que se le
proporciona ("ocho") sin incluirla y en orden lexicográfico.

La salida sería:
13768921045
------------
541029
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

SE REPRESENTAN CON
Map<K,V>
Recorrer mapas
No heredan de Colletion ni de Iterable
pero aun así se pueden recorrer.

Esta interfaz define el método


keySet(); que permite obtener un
conjunto (Set<K>) que contiene todas
las claves del mapa. Todos los valores
que contiene en mapa se pueden
obtener a través de ese conjunto.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

El siguiente método
P E R M I T E R E CO R R E R TO DA S L A S C L AV E S D E U N M A PA Y S U S VA LO R E S A S O C I A D O S :

public <K,V> void recorrer(Map<K,V> mapa){


Iterator<K> iterador = mapa.keySet().iterator();// Iterador del conjunto
V elemento; // de claves
K clave;
while(iterador.hasNext()){
clave = iterador.next(); // Por cada clave se obtiene el mapa
elemento = mapa.get(clave); // su correspondiente valor
System.out.println(elemento);
}
}
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

API de transmisión
Una de las principales características
nuevas de Java 8 es la introducción de
la funcionalidad de transmisión,
java.util.stream, que contiene clases
para procesar secuencias de
elementos.
La clase de API central es Stream<T>.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

¿Cómo se puede crear un Stream utilizando las fuentes de datos existentes?

Creación de stream. Se pueden crear los flujos a partir de


diferentes fuentes de elementos, colección o matriz con la
ayuda de los métodos stream() y of():

String[] arr = new String[]{"a", "b", "c"};


Stream<String> stream = Arrays.stream(arr);
stream = Stream.of("a", "b", "c");

Agregamos un método predeterminado stream() a


la interfaz Collection, lo que permite crear un
Stream<T> usando cualquier colección como
fuente de elementos, así a partir de cualquier tipo
de colección se puede obtener un Stream:
Stream<String> stream = list.stream();
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Subprocesamiento múltiple con flujos.

Stream API también permite simplificar los subprocesos


múltiples al proporcionar el método parallelStream() que
ejecuta operaciones sobre los elementos de la transmisión en
modo paralelo, esto es, en hilos de ejecución separados.

El siguiente código permite ejecutar el método


doWork() en paralelo para cada elemento de la
secuencia:
list.parallelStream().forEach(element ->
doWork(element));
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Operaciones de streams
Hay muchas operaciones útiles que se pueden realizar en un stream. Se dividen en:

Operaciones intermedias (retornar Stream<T>).


Operaciones terminales (retornar un resultado de tipo definido).

long count = list.stream().distinct().count();

En este ejemplo vemos como el método distinct(). representa


una operación intermedia, que crea una nueva secuencia de
elementos únicos de la secuencia anterior. Y el método count() es
una operación de terminal, que devuelve el tamaño del flujo.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las operaciones de streams

Iteración

H a z c l i c
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las operaciones de streams

Iteración
Stream API permite sustituir los bucles for, for-each y while. Permite
concentrarse en la lógica de operación, pero no en la iteración sobre la
Filtración secuencia de elementos. Por ejemplo:
for (String string : list) {
H a z c l i c
if (string.contains("a")) {
return true;
}
}
Con Java 8 este código se podría escribire solo con una línea de código:
boolean isExist = list.stream().anyMatch(element -
>element.contains("a"));
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las operaciones de streams


El método filter() nos permite seleccionar o discriminar un flujo de elementos
Iteración que satisfacen un predicado. Por ejemplo:
ArrayList<String> list = new ArrayList<>();
Filtración list.add("One");
list.add("OneAndOnly");
Cartografía. list.add("Derek");
Mapping
list.add("Change");
H a z c l i c
list.add("factory");
list.add("justBefore");
El siguiente código crea un Stream<String> de List<String>,
list.add("Italy"); encuentra todos los elementos de este flujo que contienen el
carácter "d" y crea un nuevo flujo que contiene solo los
list.add("Italy");
elementos filtrados:
list.add("Thursday");
list.add(""); Stream<String> stream =

list.add(""); list.stream().filter(element ->


element.contains("d"));
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las operaciones de streams


Para convertir elementos de un Stream aplicándoles una función especial y recopilar estos nuevos
Iteración elementos en un Stream, podemos usar el método map():
List<String> uris = new ArrayList<>();
Filtración uris.add("C:\\My.txt");
Stream<Path> stream = uris.stream().map(uri -> Paths.get(uri));
Cartografía. En este ejemplo vemos cómo se convierte Stream<String> en Stream<Path> al aplicar una
Mapping expresión lambda específica a cada elemento de la secuencia (Stream) inicial.
Si tenemos un Stream en el que cada elemento contiene su propia secuencia de elementos y
Pareo. Matching queremos crear un Stream de estos elementos internos, tenemos que usar el método flatMap():
List<Detail> details = new ArrayList<>();
H a z c l i c
details.add(new Detail()); En este ejemplo, tenemos una lista
de elementos de tipo Detail. La
Stream<String> stream =
clase Detail contiene un campo
details.stream().flatMap(detail ->
PARTS, que es List<String>. Con el
detail.getParts().stream());
método flatMap(), cada elemento
del campo PARTS se extraerá y
agregará a la nueva secuencia
resultante..
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las operaciones de streams

Iteración
Stream API ofrece un conjunto de instrumentos para validar
elementos de un stream de acuerdo con algún predicado. Para
Filtración
hacer esto, se puede usar uno de los siguientes métodos:
anyMatch(), allMatch(), noneMatch(). Esas operaciones
Cartografía. devuelven un valor booleano:
Mapping
boolean isValid = list.stream().anyMatch(element ->
Pareo. Matching element.contains("h")); // true
boolean isValidOne = list.stream().allMatch(element ->
element.contains("h")); // false
boolean isValidTwo = list.stream().noneMatch(element ->
element.contains("h")); // false
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las operaciones de streams

Iteración Para streams vacíos, el método allMatch() con cualquier predicado


dado devolverá verdadero:
Stream.empty().allMatch(Objects::nonNull); // true
Filtración

Cartografía. El código anterior supone algo así como una apuesta segura, ya
Mapping que no podemos encontrar ningún elemento que no satisfaga el
predicado.
Pareo. Matching De igual manera, el método anyMatch() siempre devuelve falso
para secuencias vacías:
Reducción Stream.empty().anyMatch(Objects::nonNull); // false

H a z c l i c
De nuevo es algo lógico, ya que no podemos encontrar un
elemento que satisfaga esta condición.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las operaciones de streams


Stream API permite reducir una secuencia de elementos a
Iteración algún valor de acuerdo con una función específica con la ayuda
del método reduce() del tipo Stream. Este método toma dos
Filtración parámetros:
• valor de inicio
Cartografía. • una función de acumulador.
Mapping
Imagina que tienes un List<Integer> y quieres tener una suma
Pareo. Matching de todos estos elementos y algún Integer inicial (en este
ejemplo 23). Puedes ejecutar el siguiente código y el resultado
será 26 (23 + 1 + 1 + 1).
Reducción
List<Integer> integers = Arrays.asList(1, 1, 1);
Coleccionismo Integer reduced = integers.stream().reduce(23,
(a, b) -> a + b);
H a z c l i c
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

Las operaciones de streams

Iteración
La reducción también puede proporcionarse mediante
el método collect() de tipo Stream. Esta operación es
Filtración muy útil si queremos convertir un flujo en una colección
o un mapa y representar un flujo en forma de una sola
Cartografía. cadena. Hay una clase de utilidad Collectors que
Mapping
proporciona una solución para casi todas las
operaciones de recolección típicas. Para algunas tareas
Pareo. Matching
no triviales, se puede crear un recopilador
personalizado.
Reducción

List<String> resultList = list.stream().map(element ->


Coleccionismo element.toUpperCase()).collect(Collectors.toList());
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

S t re a m d e
S t re a m va c í o colección S t re a m d e A r ray

+ + +
Haz clic
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

S t re a m va c í o

En el caso de la creación de una secuencia vacía debemos usar el método empty():


Stream<String> streamEmpty = Stream.empty();

A menudo usamos el método empty() en la creación para evitar devolver un valor


nulo para flujos sin ningún elemento:

public Stream<String> streamOf(List<String> list)


{
return list == null || list.isEmpty() ?
Stream.empty() : list.stream(); }

En el ejemplo anterior si la lista es nula o está vacía, se devuelve un Stream vacío,


en caso contrario se devuelve el stream de la lista original.
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

S t re a m d e
S t re a m va c í o colección S t re a m d e A r ray

+ + +
Haz clic
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

S t re a m d e
colección

También, como hemos visto anteriormente, podemos crear un


flujo de cualquier tipo de Colección (Colección, Lista, Conjunto):

Collection<String> collection =
Arrays.asList("a", "b", "c"); Stream<String>
streamOfCollection = collection.stream();
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

S t re a m d e
S t re a m va c í o colección S t re a m d e A r ray

+ + +
Haz clic
G e s t i ó n d e c o l e c c i o n e s . Tra b a j a n d o c o n s t re a m s J ava . F l u j o s y f i c h e ro s

S t re a m d e
A r ray

Una matriz o Array también puede ser la fuente de un stream:

Stream<String> streamOfArray = Stream.of("a", "b", "c");

Podemos crear también un stream a partir de una matriz existente o de


parte de una matriz:

String[] arr = new String[]{"a", "b", "c"};


Stream<String> streamOfArrayFull = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3);
hemos
terminado
¡EXCELENTE TRABAJO!

También podría gustarte