0% encontró este documento útil (0 votos)
68 vistas31 páginas

Certificación Java SE 8 Programmer I

Este documento describe conceptos clave de Java como versiones, memoria del JVM, clases, POO y más. Cubre temas como pilares de POO, herencia, encapsulamiento, memoria del JVM como pila, marco, heap y metaspace.

Cargado por

Jesús
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
68 vistas31 páginas

Certificación Java SE 8 Programmer I

Este documento describe conceptos clave de Java como versiones, memoria del JVM, clases, POO y más. Cubre temas como pilares de POO, herencia, encapsulamiento, memoria del JVM como pila, marco, heap y metaspace.

Cargado por

Jesús
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Java SE 8 Programmer I - (1Z0-808)

Certificación oficial:
● Java SE 8 Programmer I (1Z0-808)

JAVA Multithreading, Parallel & Asynchronous


● JAVA Multithreading, PArallel & Asynchronous

Versiones de Java
Java SE (JSE) - Java Core Java EE (J2EE) - Java advanced

Java Standard Edition used to develop Java Enterprise Edition designed for enterprise and server applications.
desktop and web applications and Requires an application server to deploy and run.
basic web services. Doesn’t requiere
an application server to run. ● JPA - Java Persistence API
● WebApplications: API Java Servlets, JSP Java Server Pages, HTML, CSS.
● JDBC - Java Database Produces WAR file.
Connectivity ● EJB Enterprise JavaBeans. Produces JAR file.
● JavaFX, Swing, AWT (UI) ● EAR file: JAR + WAR.
● JMS - Java Message Service
● JNDI - Java Naming and Directory Interface
● JTA - Java Transaction API
● JAXP, JAX-WS, JAX-RPC - Java API for XML

JVM Stack/Heap/Metaspace memory areas


JVM Stack: Each thread has its own Frames Stack that holds a frame for each method executing on that thread. That Frames Stack
follows a LIFO (Last In, First Out) structure, so the currently executing method is at the top of the stack. A new frame is created and
added (pushed) to the top of stack for every method invocation. The frame is removed (popped) when the method returns normally or
if an uncaught exception is thrown.

JVM Frame: A new stack frame is created for every method invocation and destroyed when its execution completes. Each frame
contains a local variables array, a return value, operand stack and a Current Class Constant Pool reference. The stack is small and
managed automatically. The local variable array stores only primitive variables and references, while objects are stored on the heap.

JVM Heap: memory zone that stores dynamically created objects and arrays during runtime. It’s a larger memory region shared among
all threads. The Garbage collection (GC) frees unused memory in the heap. To support garbage collection the heap is divided into three
sections:

● Young Generation: Often split between Eden and Survivor. New objects and arrays are created into the young generation.
Minor garbage collection will operate in the young generation. Objects, that are still alive, will be moved from the eden space to
the survivor space.
● Old Generation (also called Tenured Generation). Major garbage collection, which typically causes the application threads to
pause, will move objects between generations. Objects, that are still alive, will be moved from the young generation to the old
(tenured) generation.
● Permanent Generation: is collected every time the old generation is collected. They are both collected when either becomes
full. From Java 8, replaced with Metaspace.

Metaspace: Starting from Java 8, Metaspace replaces the old PermGen (Permanent Generation). It holds class metadata (name, fields,
methods, constants, static methods). It dynamically re-sizes itself (up to the max limit of your machine memory) unlike the older
PermGen memory space which needed to be specified with a fixed size.

Java S8 Programmer I (1Z0 - 808) Página 1


Configuring memory parameters
-Xms: This option sets the initial heap memory size (-Xms512M) //512Mb
-Xmx: This option sets the maximum heap memory size (-Xmx2G) //2Gb
-Xss: This option sets the JVM stack size (-Xss256k)//256kb

Clases en Java
Clase JAVA: es una plantilla (template) que define la forma de un objeto, agrupa atributos y métodos.

A class is the blueprint from which individual objects are created, it


has attributes and methods.

Sus elementos son:


1. Modificador de acceso de la clase (public, default):
● public: accesible desde cualquier lugar. Solo UNA clase pública por cada archivo .java.
● default (no se escribe): es accesible por todas las clases dentro del mismo paquete.
● Tipos de clases:
○ final: La clase no puede tener subclases.
○ abstract: La clase puede contener métodos sin implementación. Es una superclase y no pueden crear
objetos de ella.
2. Atributos de la clase
● Modificadores de acceso (public, protected, default, private):
● public: accesible desde cualquier lugar.
● protected: accesible dentro de la clase, subclases y las clases dentro del mismo paquete. Se recomienda usarlo
solamente en la clase Padre que heredarán a las clases hijo.
● default (no se escribe): es accesible por todas las clases dentro del mismo paquete.
● private: accesible solo dentro de la clase.
● Tipos de atributos:
○ Modificador + static accesible sin necesidad de instanciar la clase.
○ Modificador + final: el atributo debe ser inicializado y no se puede modificar. Un objeto puede también
ser final, esto ocasiona que no se puede cambiar su referencia a memoria, solamente su contenido:
final Persona per = new Persona();
per.setNombre("Juan"); //válido
per = new Persona(); //inválido

○ Modificador + volatile: is primarily used to address visibility issues in a multithreaded environment,


ensuring that changes made to a variable by one thread are immediately visible to other threads.

3. Métodos de la clase (funciones)


● Los mismos modificadores que los atributos: (public, protected, default, private):
● Tipos de métodos:
○ Modificador + Static: Métodos estáticos, solo pueden invocar otros métodos y atributos estáticos. No
pueden utilizar la palabra this. Los métodos NO estáticos sí pueden invocar métodos y atributos estáticos.
Se puede importar un método estático por medio de import static
mx.com.nombreempresa.clase.metodo, y después se invoca el método tal cuál sin agregar ya prefijos.

Java S8 Programmer I (1Z0 - 808) Página 2


○ Modificador + final: evita que se modifique la definición de un método desde una subclase, es decir, no
puede sobreescribirse el método en una subclase.

Modificador Clase Package Subclase Otros paquetes

public ✔ ✔ ✔ ✔

protected ✔ ✔ ✔ ⏺
default ✔ ✔ ⏺ ⏺
private ✔ ⏺ ⏺ ⏺
A partir de Java 9 (pendiente por desarrollar el tema)
Accesibilidad por medio de módulos:
● Public para todos
● Public solo a módulos amigos
● Public solo dentro de un módulo
● Además de Protected, Package y Private
module hello.world { //nombre module java.base{
exports com.example.hello; //paquetes expuestos exports java.lang;
requires java.base; //dependencias con otros módulos ...
} }

POO Programación Orientada a Objetos


(Oriented-Object Programming) OOP

Es un paradigma de programación basado en clases (atributos y funciones) reutilizables y objetos. Permite que el código sea
reutilizable, organizado y fácil de mantener. Sus 4 pilares son: PAEI

Abstraction
Abstraction shows only useful data by providing only the most necessary details.
Es la exposición de los datos de un objeto proporcionando únicamente los detalles más necesarios y útiles de un objeto.
Supone una extensión a la encapsulación.

Encapsulation
Encapsulation is used to restrict direct access to attributes and methods of a
class by using access modifiers.
Consiste en ocultar atributos de un objeto de manera que solo se pueda cambiar mediante operaciones definidas en ese
objeto

Inheritance
Inheritance is a mechanism in which one object acquires all the properties and
behaviors of a parent object.
La herencia es un mecanismo que permite la definición de una Clase Hija como extensión de una Clase Padre mediante la
palabra extends con el fin de reutilizar código.
Java permite múltiples niveles de herencia pero no la herencia múltiple, es decir una clase sólo puede heredar directamente
de una clase ascendiente. Todo lo que es común a ambas clases está en la Clase Padre, mientras lo específico, queda restringido a
las Clases Hijas. Solo se heredan los métodos y atributos públicos, default y protected.

Hijo extends Padre → Empleado extends Persona

Los constructores no se heredan pero pueden ser accedidos por medio de la palabra super diferenciándolos por el número
de parámetros que se envíen.

Polimorfismo (Polymorphism)

Java S8 Programmer I (1Z0 - 808) Página 3


Polymorphism refers to the ability of a class to provide different implementations of
a method, depending on the type of object that is passed to the method.

El polimorfismo es una característica que permite que un mismo objeto tipo Padre pueda hacer referencia (instancias) tanto
de la Clase Padre como de las Clases Hijas, esto permite llamar a métodos con igual nombre, pero que pertenecen a clases distintas y
en tiempo de ejecución se decide qué método es el que se ejecuta (usando instanceof). Como se utiliza la herencia, los objetos
pueden sobreescribir (@Override) los métodos compartidos, con métodos secundarios específicos.

Padre padre = new Hija(); //Upcasting implicitly

Shapes myTriangle = new Triangle(); //Upcasting implicitly

Nota: Al sobreescribir los métodos en la Clase Hija, su identificador de acceso no puede ser más débil que el de la Clase Padre, es
decir, si en la Clase Padre tiene Protected, en la Clase Hija no puede asignarse un Private. Para determinar de qué tipo es, se utiliza la
palabra instanceof la cual nos devuelve un listado de la herencia completa de dicha clase, de lo más particular (Triangle) hasta lo
más genérico (Object)

Returns:

It's instance of Triangle


It's instance of Shapes
It's instance of Object

Para utilizar los métodos específicos (no los compartidos) de las clases hijas, es necesario hacer una conversión de tipos (casting) de
Clase Padre a Clase Hija, con la instrucción.


✓ ((Triangle) shape).methodOfTriangleClass(); //Downcasting explicitly
Triangle variable = new Shape(); //Downcasting implicitly, compile-time error

Conversión de tipos (casting)


● Downcasting: (specialization or narrowing) is typecasting from parent object to a child type or casting common type to
individual type. Downcasting cannot be implicit.

Java S8 Programmer I (1Z0 - 808) Página 4


❌ Child c = new Parent(); //Downcasting implicitly, compile-time error
✓ Child c = (Child)p; //Downcasting explicitly or...
✓ ((Child) parent).methodOfChildClass(); //Downcasting explicitly

● Upcasting: (Generalization or Widening) is typecasting from a child object to a parent object. Upcasting can be done
implicitly.

Parent p = new Child(); //Upcasting implicitly

Clase abstracta (public abstract class NombreClase)


● Es una superclase que permite unificar campos y métodos de las subclases, evitando la repetición de código y unificando
procesos. Se usan para heredar CARACTERÍSTICAS.
● Declara un conjunto de atributos, constructores y métodos.
● Puede contener métodos abstractos (sin cuerpo) y métodos concretos (con cuerpo).
● No se puede instanciar, solo heredar (extends).
● No soporta herencia múltiple.
● Las clases que los extienden deben definir sus métodos usando @Override
● A veces se define como abstracta solo para que no se pueda instanciar aunque no contenga métodos abstractos.

Interfaz JAVA (public interface NombreInterfaz)


● Variante de clase abstracta pero que no hereda de Object. Se usan para heredar COMPORTAMIENTOS.
● Contiene solamente constantes, métodos abstractos y a partir de Java 8 también métodos por defecto.
● Todos sus atributos son constantes: public static final por default (aunque no se especifique explícitamente).
● Todos sus métodos son public abstract automáticamente (aunque no se especifique explícitamente).
● Sus métodos por defecto son public default y sí llevan cuerpo.

Java S8 Programmer I (1Z0 - 808) Página 5


● No tiene constructores.
● No se puede instanciar, solo implementar (implements).
● Las clases que los implementen deben implementar todos sus métodos usando @Override, si no, dicha clase hija debe
marcarse como abstracta.
● Soporta implementación múltiple (separando las interfaces con comas).

Abstract Class Interface

1 public abstract class ClassName public interface Iname


2 Share CHARACTERISTICS Share BEHAVIORS
3 Cannot be instantiated Cannot be instantiated
4 Extends from Object Doesn't extends from Object
5 Can have Abstract & Concrete methods. All methods are abstract by nature (public abstract)
All attributes are public static final (by default)
6 Inherited with extends Implemented with implements
7 Single inheritance Multiple inheritance
8 Some methods could be Overriden All methods must be Overriden
9 It has constructors Does not have constructors

Java S8 Programmer I (1Z0 - 808) Página 6


Tipos en Java
Tipos primitivos Enteros
Upcasting Downcasting Wrapper
Tipo Tamaño Default Rango
(Widening - Implícito) (Narrowing - Explícito) Class
byte myByte = (byte)
byte 8 bits 0 -128 a 127 -
myShort;
Byte
short myShort = (short)
short myShort = myInt; Short
short 16 bits 0 -32,768 a 32,767 myByte; short myShort = (short)
myChar;

' \u0000' a ' char myChar =


(char)(myInt + '0'); Character
char 16 bits ' \u0000' \uFFFF' char myChar = (char)
0 a 65535 myShort;
int myInt = myShort;
int myInt Integer
=Character.getNumeri
int myInt = (int)
cValue(myChar);
int 31 31 myLong;
32 bits 0 -2 a 2 -1 (To convert char
int myInt = (int)
(default) '0'=48 to 0)
myDouble;
int myInt =
Integer.parseInt(myS
tring);
long myLong = (long)
long 64 bits 0L -263 a 263-1 long myLong = myInt;
myFloat;
Long

boolean 1 bit false true/false - - Boolean

Tipos primitivos Flotantes


Tipo Tam Defa Rango Upcasting Downcasting Wrapper
año ult (Widening implícito) (Narrowing - Explícito) Class

32 1.4E-45 a float myFloat = myLong; float myFloat =


float 0.0f float myFloat = myInt; (float) myDouble;
Float
bits 3.402823E38
4.9E-324 a double myDouble = myFloat;
double 64
0.0d 1.79769313486232 double myDouble = myInt; - Double
(default) bits double myDouble = myLong;
E308

Tipos referenciados (Object)


● Clases: Las clases son tipos de datos de referencia que pueden tener atributos y métodos. Puedes crear instancias de una
clase utilizando el operador new (BigDecimal, BigInteger)
○ BigDecimal se aconseja para trabajar con dinero en Java.
● Interfaces: Similar a las clases, pero pueden contener solo métodos abstractos y constantes.
● Arreglos: Colecciones de elementos del mismo tipo. Los elementos de un arreglo pueden ser primitivos o de referencia.
● Enum: Una enumeración es un tipo de datos especial que define un conjunto fijo de constantes.

Autoboxing y Unboxing
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object
wrapper classes. Unboxing is converting an object of a wrapper type (Integer) to its corresponding primitive (int) value.

Integer enteroClase = 10; //Autoboxing: primitive to Wrapper class


int enteroPrimitivo = enteroClase; //Unboxing: Wrapper class to primitive

Tipo Char
Se utiliza para almacenar caracteres individuales, está considerado también un tipo numérico, si bien su representación habitual es la
del carácter cuyo código almacena, utiliza 16 bits y se usa la codificación UTF-16 de Unicode.

//Los tres almacenan el caracter !


char letra = '!';
char letraDecimal = 33;
char letraUnicode = '\u0021';

Java S8 Programmer I (1Z0 - 808) Página 7


//Convierte el caracter ! en su respectivo decimal, que es 33
int letraenInt = '!';

Inferencia de tipos (local-variable type inference) Java10


La inferencia de tipos es un proceso por el cual el compilador determina el tipo de una variable local que ha sido declarada sin una
declaración explícita de su tipo. El tipo es inferido a partir del valor inicial provisto a la variable. En Java existe a partir de la versión 10
y solo para las variables locales, no para atributos de una clase, ni como argumentos de función.

var contador=10;

Reglas para variables


● Deben iniciar con cualquier letra (con o sin acento), guion bajo o signo de moneda.
● No pueden empezar con número o cualquier otro carácter.
● No pueden tener espacios.
● No pueden tener nombres de palabras reservadas.

Caracteres especiales o secuencias de escape


Código Significado
\n Nueva línea
\r Retorno de carro
\t Tabulación
\' Comilla simple
\" Comilla dobles
\\ Barra inversa \
\u Caracter UNICODE

Palabras reservadas (50)


boolean class transient case throw

byte abstract volatile default throws

char final native do goto

short static super while assert

int extends this for new

long implements import continue return

float interface package break void

double public if try instanceof

const protected else catch synchronized

enum private switch finally strictfp

Clase Scanner
Dentro del paquete java. util, Scanner es una clase que nos permite obtener la entrada de datos primitivos. Esto quiere decir que
podemos capturar datos del tipo int, double, string y etc.

Scanner consola = new Scanner(System.in);


var usuario = consola.nextLine(); //Una variable autodeterminada
String name = consola.nextLine(); //Una cadena
char gender = consola.next().charAt(0); // Un solo carácter
int age = consola.nextInt(); //int
long mobileNo = consola.nextLong(); //long
double average = consola.nextDouble(); //double

Java S8 Programmer I (1Z0 - 808) Página 8


//Read input from a URL and adds each line to a List
List<String> stringList = new ArrayList<>();

URL url = new URL("https://adventofcode.com/2023/day/1/input");


try (Scanner scanner = new Scanner(url.openStream())) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
stringList.add(line);
}
}

Operadores de aritméticos de Incremento


1) Pre-incremento: primero incrementa la variable y después se asigna.
int a = 3;
int c = ++a; //Primero se incrementa "a" y después se asigna su nuevo valor a "c"
//c = 4 y a = 4

2) Post-incremento: primero se asigna su valor y después se incrementa.


int a = 3;
c = a++; //Primero se utiliza el valor de "a" y después se incrementa
//c = 3 y a = 4

Operador Ternario
La variable resultado recibirá el valor1 en el caso de que la condición sea true o bien el valor2 en el caso de que la condición sea
false.

resultado = (condicion)?valor1:valor2;

Prioridad de operaciones

Java S8 Programmer I (1Z0 - 808) Página 9


String type
Java String Pool
Storage area in Java heap where string literals stores. Cada vez que necesitamos crear un nuevo String, Java revisa si ya existe en el
pool, en tal caso nos devuelve una referencia a ella. Cuando creamos dos cadenas con el mismo texto, el operador == nos devuelve
true siempre, ya que apuntan al mismo objeto del pool.

Solamente crea una nueva referencia en memoria cuando se solicita explícitamente usando la instrucción new String(" ")
Si se usa la instrucción new String(" ").intern(); entonces el String Pool actúa como lo hace normalmente y devuelve una
referencia si es que dicho texto ya existía.

Java StringBuilder and Java StringBuffer


A diferencia de String, StringBuilder sí es mutable. Stored in heap.16 characters by default.

StringBuilder → Faster and preferred in non-concurrent environments (Non-Thread safe)


StringBuffer→ Slower but preferred in concurrent environments (Thread safe)

//DECLARING
StringBuilder builder = new StringBuilder();
StringBuilder builderWithText = new StringBuilder("Hello"); // Initial content

StringBuffer buffer = new StringBuffer();


StringBuffer bufferWithText = new StringBuffer("Hello"); // Initial content

//Operations
builder.append("Hola"); // Agregar al final de la cadena
builder.insert(2, "123"); // Insertar en una posición específica

builder.setCharAt(1, 'X'); // Modificar un carácter en una posición específica


builder.replace(1, 3, "ABC"); // Reemplazar un rango de caracteres
builder.delete(1, 3); // Eliminar un rango de caracteres
builder.deleteCharAt(0); // Eliminar un carácter en una posición específica
builder.reverse(); // Invertir la cadena
builder.setLength(0); // vaciar el builder

int length = builder.length(); // Obtener la longitud de la cadena


String result = builder.toString(); // Convertir StringBuilder a String

Clase Object
Es una superclase implícita de todas las demás clases. Todas las demás clases son subclases de Object. Tiene ciertos métodos que
se recomienda implementarse en las clases hijas.
● Método toString()
Cuando definimos en una clase el método toString(), imprimimos ahí todo el contenido de los miembros para ese objeto, y se
puede invocar usando System.out.println(objetoClase.toString()); o simplemente System.out.println(objetoClase);
● Método hashCode()
Al implementarse, devuelve enteros distintos para objetos distintos por medio de un cálculo. Se recomienda implementar cuando se
vayan a usar Hashmap, HashSet, HashMap, Hashtable, etc. para facilitar la búsqueda. Devuelve enteros distintos para objetos
distintos.
● Método equals()
Compara el objeto dado con el objeto "this" (el objeto sobre el que se llama el método). Da una forma genérica de comparar objetos
para la igualdad. Se recomienda anular el método equals(Object obj) para obtener nuestra propia condición de igualdad en Objects.

NOTA: En general, es necesario anular el método hashCode() siempre que se anule este método, a fin de mantener el
contrato general para el método hashCode, que establece que los objetos iguales deben tener códigos hash iguales.

Argumentos de longitud variable


Un método que toma una cantidad variable de argumentos se denomina método varargs el cual se especifica por tres puntos (…) En
ese caso, el parámetro varParameters se convierte en un arreglo con todos los argumentos que se recibieron.
public static void vaTest(int ... varParameters){
//1 parámetro de longitud variable
int a = varParameters[0]; //Se trata como un arreglo
}

vaTest(1,2,3); //3 argumentos

Java S8 Programmer I (1Z0 - 808) Página 10


vaTest(10); //1 argumento
vaTest(); //sin argumentos

En caso de que la función lleve más de un parámetro, el de longitud variable debe ir al final del listado, si no, marca error.

public static void vaTest(String name, int ... varParameters){


//2 parámetros, uno de ellos de longitud variable
}

Regular Expressions
A regular expression is a sequence of characters that forms a search pattern. When you search for data in a text, you can use this
search pattern to describe what you are searching for and can be used to perform all types of text search and text replace operations.
We need to import the java.util.regex The package includes the following classes:
● Pattern Class - Defines a pattern (to be used in a search)
● Matcher Class - Used to search for the pattern
● PatternSyntaxException Class - Indicates syntax error in a regular expression pattern

Pattern pattern = Pattern.compile("Game (\\d+):", Pattern.CASE_INSENSITIVE); //WHAT to find


Matcher matcher = pattern.matcher("Game 324:"); //WHERE to find

if(matcher.find()){ //VALIDATE if expression is found in text (it returns the first coincidence)
matcher.group(1); //RETURNS the matching content of the first capturing group
}

while(matcher.find()){ //Use WHILE when multiple coincidences are expected e.g "Game 1: Game 2: Game 3:"
matcher.group(1); //RETURNS the matching content of the first capturing group
}

//With different capture groups to find


Pattern pattern = Pattern.compile("(\\d{3})-(\\d{2})-(\\d{4})"); //3 capture groups (text in parenthesis)
Matcher matcher = pattern.matcher("123-45-6789");
if(matcher.find()){
matcher.group(1); //RETURNS first text in parenthesis
matcher.group(2); //RETURNS second text in parenthesis
matcher.group(3); //RETURNS third text in parenthesis
}

NOTE: matcher.group(); //When there are not capture groups (expression between parenthesis)

Pattern namePattern = Pattern.compile("[A-Z][a-z]+\\s[A-Z][a-z]+"); //Format "Name name" with space between


Pattern phonePattern1 = Pattern.compile("\\(\\d{3}\\)\\s\\d{3}-\\d{4}"); //Format (555) 123-4567
[A-Z] //Matches any uppercase letter from A to Z.
[a-z] //Matches any lowercase letter from a to z.
[abc] //Find one character from the options between the brackets e.g.(apple → 'a', banana → 'b')
[^abc] //Find one character NOT from the options e.g.(apple → 'p','p','l','e', banana → 'n','n')
\\s //Matches a whitespace character.
\\( //Matches a ( character.
\\) //Matches a ) character.
\\d{3} //Matches exactly 3 digits (0-9).
(\\d+) //Matches one or more digits as a unit matcher.group(1); → '1234'
[0-9] //Matches one digit: while(...){ matcher.group();} → 1','2','3','4'
| //Find a match for any one of the patterns separated by | as in: (cat|dog|fish)
. //Represents any unique character, e.g "c.t" will match with "cat"
^ //Matches any line that starts with that word as in: ^Hello
$ //Matches any line that ends with that word World$
\w //Word character: Represents one letter, number or underscore.
\b //Word limiter: represents where a word starts or ends. e.g \bworld\b in "Hello world!" because there
are no word characters before or after "world", only a "!" which is not word character.
n+ //Matches any string that contains 1 or more occurrences of n (e.g. 'a+' → "a", "aa", "aaa", etc.)
n* //Matches any string that contains 0 or more occurrences of n (e.g. 'a*' → "", "a", "aa", etc.)
n? //Matches any string that contains 0 or 1 occurrences of n (e.g. 'a?' → "", "a")
n{x} //Matches any string that contains a sequence of X n's (e.g. 'a{3}' → "aaa")
n{x,y} //Matches any string that contains a sequence of X to Y n's (e.g. 'a{2,4}' → "aa", "aaa", "aaaa")
n{x,} //Matches any string that contains a sequence of at least X n's (e.g. 'a{2,}' → "aa", "aaa", "aaaa",
etc.)

Java S8 Programmer I (1Z0 - 808) Página 11


Enumeraciones
Una enumeración es una lista de constantes con nombre que definen un nuevo tipo de datos. Un objeto de un tipo de enumeración
sólo puede contener los valores definidos por la lista. La declaración de Enum puede hacerse fuera de una clase, o dentro de una clase
(class), pero NO dentro de un método. Tiene las propiedades de un atributo estático, público y final.

enum Color{
ROJO, VERDE, AZUL;
}

public class HolaMundo {


public static void main(String[] args) {
Color color = Color.ROJO;
System.out.println(color); //rojo

switch(color){
case ROJO: //rojo
case VERDE: // verde
case AZUL: // azul
}
}

En las sentencias case, los nombres de las constantes de enumeración se usan sin estar calificados por el nombre de tipo de
enumeración. Es decir, se utiliza color, no Color.color. Esto se debe a que el tipo de enumeración en la expresión de switch ya ha
especificado implícitamente el tipo de enumeración de las constantes de case.

Cada enum es implementado internamente mediante el uso de class.

//internamente enum Color se convierte en:


class Color
{
public static final Color ROJO = new Color();
public static final Color AZUL = new Color();
public static final Color VERDE = new Color();
}

Por lo tanto, una enumeración puede definir constructores, agregar métodos y tener variables de instancia.
enum Color
{
ROJO(750, 400),
VERDE(525, 526),
AZUL(470, 631);

//Parámetros de cada enum


private final int longitudOnda;
private final int frecuencia;

//Constructor con cada parámetro


Color(int longitudOnda, int frecuencia){
this.longitudOnda = longitudOnda;
this.frecuencia = frecuencia;
}

//Getters
public int getLongitudOnda() {
return this.longitudOnda;
}
public int getFrecuencia() {
return this.frecuencia;
}
}

public class HolaMundo {


public static void main(String[] args) {
Color color = Color.ROJO;
System.out.println("Color: " +color
+ ", Longitud de onda: " + color.getLongitudOnda()

Java S8 Programmer I (1Z0 - 808) Página 12


+ ", Frecuencia: " + color.getFrecuencia());
//Color: ROJO, Longitud de onda: 750, Frecuencia: 400
}
}

Bloques de inicialización
● Statick block: De contexto estático: son bloques de código que se ejecutan cuando una clase es cargada, no cuando es
instanciada. Se ejecuta una sola vez.
public class HolaMundo { Output:
public HolaMundo() { 1. Bloque de inicializacion estático
System.out.println("4. Constructor"); 2. Inicio
} 3. Bloque de inicializacion dinámico
4. Constructor
//Bloque de inicialización dinámico 5. Fin
{
System.out.println("3. Bloque de inicializacion dinámico");
}

//Bloque de inicialización estático


static{
System.out.println("1. Bloque de inicializacion estático");
}

public static void main(String[] args) {


System.out.println("2. Inicio");
new HolaMundo();
System.out.println("5. Fin");
}
}

● Dynamic block: De contexto Dinámico: son bloques de código que se ejecutan cuando una clase es instanciada, pero se
ejecutan justo antes que el constructor. Se ejecuta cada que se instancia la clase.

public class HolaMundo { Resultado:


public HolaMundo() { 1. Inicio
System.out.println("3. Constructor"); 2. Bloque de inicializacion dinámico
} //Primer instancia
3. Constructor
//Bloque de inicialización dinámico 2. Bloque de inicializacion dinámico
{ //Segunda instancia
System.out.println("2. Bloque de inicializacion dinámico"); 3. Constructor
} 4. Fin

public static void main(String[] args) {


System.out.println("1. Inicio");
new HolaMundo(); //Primer instancia
new HolaMundo(); //Segunda instancia
System.out.println("4. Fin");
}
}

Java S8 Programmer I (1Z0 - 808) Página 13


Java Beans
Son un modelo de componente reutilizable (una clase que sigue ciertas convenciones que hacen posible el acceder a sus propiedades
y manipularlas). Con esto Java EE, Hibernate o Spring pueden hacer uso de ellas.
● Tienen atributos privados que se acceden o modifican con get() y set().
● Tienen un constructor vacío (sin argumentos) y algunos otros definidos por el usuario.
● Implementa la interfaz Serializable (tiene persistencia) para enviar información entre diferentes equipos. Bytecode
streaming.
● Permite al IDE conocer sus propiedades y conductas siguiendo pautas de diseño, nombres de funciones y definiciones de las
clases (Introspección)

Memoria en Java
● Memoria Stack: es donde se almacenan las variables locales, se guarda la referencia del objeto.
p1 = 0x333
● Memoria Heap: es donde se almacenan los objetos a los que apuntan las variables locales.
0x333 = tipo Object

System.gc(); → Invoca al garbage collector

https://www.w3resource.com/java-exercises/array/index.php
https://www.youtube.com/watch?v=dGY1e_ebn4w

Java S8 Programmer I (1Z0 - 808) Página 14


Colecciones (Java Collection Framework)
A collection is an object that represents a group of objects. Collections refer to a framework that provides a set of interfaces and
classes for the manipulation and storage of groups of objects. It includes fundamental interfaces like List, Set, and Map, along with
their respective implementations such as ArrayList, HashSet, and HashMap. They offer a rich set of operations for organizing,
accessing, and manipulating data in a structured manner.
● Arrays data structure
✓ Static Data Structure that contains collections of homogeneus elements (same type), fixed size. Can hold both object and
primitive data type .
★ Single dimensional (1-D): linear array in which elements are stored in a continuous row.
//DECLARING
int[] numeros = new int[5]; //1º forma
int []numeros = new int[5]; //2º forma
int numeros[] = new int[5]; //3º forma
int numeros[] = {1,3,4,5}; //4º forma
int[] numeros = new int[]{1,3,4,5}; //5º forma
String[] names = {"a", "b", "c"}; //6º forma

//TRAVERSING, TRAVERSE (recorrer)


for(int num: arreglo){
System.out.println(num);
}

//SORTING an int[]
Arrays.sort(numeros);

//COPY an array
//with new length (filled with 0 or truncated to that size)
int[] numeros = Arrays.copyOf(numeros1,4);
//FROM this start TO this end
int[] numeros = Arrays.copyOfRange(numeros1,4,5);

//BASIC OPERATIONS
Arrays.toString(arr1); //Returns "[1,3,5,2]" instead of [I@29453f44
Arrays.equals(arr1,arr2); //Check if two int[] arrays are equals
Arrays.binarySearch(arr1,3);//Returns the position where the specified value is found
Arrays.stream(numeros).sum());//Return the sum of all elements in the array
Arrays.stream(numeros).max().orElse(0); //Returns max or 0 if array is empty
Arrays.stream(numeros).filter(e -> e != numRemoved).toArray() //Returns a new array without a num

//To Stream or Spliterator


Arrays.stream(arr1); //Returns an array as a Stream
Arrays.spliterator(arr1); //Returns an array as a Spliterator

//To [2,7,4] from String "274"


int[] numeros = "274".chars().map(Character::getNumericValue).toArray();
//To String "274" From [2,7,4]
String concatenatedString = String.join("", Arrays.stream(numeros)
.mapToObj(String::valueOf).toArray(String[]::new));

★ Two dimensional (2-D): array of array in which elements are stored in rows and columns. [How many 1-D
arrays][How many elements per array] ó [row][col]
int[][] twoDim1 = new int[4][5]; /
/Non-rectangular, five integers each row
String[][] letters = { {"a", "b", "c"}, //[0]
{"a", "b", "c"}, //[1]
{"a", "b", "c"} };//[2]

★ Multi dimensional: nested array.


int[][] twoDim2 = new int[2][ ];
//Non-rectangular, different rows size
twoDim2[0] = new int[5]; //[0]
twoDim2[1] = new int[3]; //[1]
int[][] twoDim = new int[ ][4]; //Illegal!

int[][][] threeDim = new int[10][15][20];


//Three dimensional array

Java S8 Programmer I (1Z0 - 808) Página 15


● List → Collections
✓ Sí almacena por orden de inserción.
✓ Sí admite elementos duplicados.
✓ No son sincronizadas (a menos que se adapte con Collections.synchronizedList)
★ ArrayList → List
■ Array autoredimensionable
■ Rápido para obtener elementos, lento para insertar o remover.
■ No trabaja con datos primitivos, pero sí con las wrapper class (Integer, String…).
■ Arrays Collection can hold both homogeneous and heterogeneous elements.
//DECLARING
List<String> arrayList = new ArrayList<>();
List<Integer> numList = Arrays.asList(1,2,3,4,5);
ArrayList<String> abecedario = new ArrayList<>(Arrays.asList("A", "B", "C"));

//BASIC OPERATIONS
arrayList.add("text"); //add elements
arrayList.get(0); //returns object at "0" position
arrayList.remove("text"); //remove elements
arrayList.removeIf(x -> x.equalsIgnoreCase("text"));//remove coincidences

//SORTING
missingNumbers.sort(Integer::compareTo);
//or…
numList.sort((x,y) -> x.compareTo(y));

//TRAVERSING, TRAVERSE (recorrer)


for(int num: numList){
System.out.println(num);
}

//or…
arrayList.forEach(e ->System.out.println(e));
//or…
arrayList.stream().forEach(e ->System.out.println(e));

//CONVERT to Integer[] from List<Integer>


Integer[] arrayInt = new Integer[numList.size()];
numList.toArray(arrayInt); //fills arrayInt with numList elements
//or... directly creates arrayInt with list elements, returns an Integer[0]
Integer[] arrayInt = numList.toArray(new Integer[0]);
//or... same but using Stream
Integer[] arrayInt = numList.stream().toArray(Integer[] ::new);

//CONVERT to List<Integer> from Integer[]


List<Integer> numList = Arrays.asList(arrayInt);

//CONVERT to List<int[]> from int[]


List<int[]> numList = Arrays.asList(arrayInt);

//SUM 2 arrays and REMOVE duplicates


HashSet<Integer> uniqueSumSet = new HashSet<>(numList1);
uniqueSumSet.addAll(numList2);
List<Integer> uniqueList = new ArrayList<>(uniqueSumSet);

★ LinkedList → List
■ Lista enlazada (Consiste en nodos donde cada uno contiene un dato a guardar y una referencia al siguiente nodo de la
lista)
■ Existen Single, double, circular and double circular linked list.
■ Rápido para insertar o remover elementos, lento para obtener.

LinkedList<Integer> linkedList = new LinkedList<Integer>();


LinkedList linkedList = new LinkedList(); //Sin usar generics

linkedList.add(1);
linkedList.get(0);
linkedList.remove("d");

Java S8 Programmer I (1Z0 - 808) Página 16


linkedList.removeFirst();
linkedList.removeLast();
linkedList.addFirst("a");
linkedList.addLast("a");

■ Hecho a mano:
// A simple Java program for traversal of a linked list
class LinkedList {
Node head; // head of list

/* Linked list Node. This inner class is made static so that


main() can access it */
static class Node {
int data;
Node next;
Node(int d)
{
this.data = d;
next = null;
} // Constructor
}

/* This function prints contents of linked list starting from head */


public void printList()
{
Node n = head;
while (n != null) {
System.out.print(n.data + " ");
n = n.next;
}
}

/* method to create a simple linked list with 3 nodes*/


public static void main(String[] args)
{
/* Start with the empty list. */
LinkedList llist = new LinkedList();

llist.head = new Node(1);


Node second = new Node(2);
Node third = new Node(3);

llist.head.next = second; // Link first node with the second node


second.next = third; // Link second node with the third node

llist.printList();
}
}

✓ Vector → List
■ Es igual que ArrayList, pero con la diferencia de que es sincronizada, es decir, se usa con hilos.
✓ Stack → Vector
■ Is a Last-in, First-out. (LIFO) data structure in which only the top element can be accessed. The data is added by push
and removed by pop on top.
■ Es sincronizado.

Stack<Integer> stack = new Stack<Integer>();


stack.push(1); //Inserts a new element
Integer deletedElement = (Integer) stack.pop(); //delete & return top element
Integer peekedElement = (Integer) stack.peek(); //return top element
stack.search(1); //return position of element

● Set → Collections
✓ No admite elementos duplicados.
✓ No son sincronizadas (a menos que se adapte con Collections.synchronizedSet)
✓ Dos instancias son iguales si contienen los mismos elementos.

★ Hashset: → Set
■ Almacena los elementos en tablas Hash.
■ No almacena por orden de inserción. Acepta elementos NULL.
■ Buen rendimiento.

Set<String> hs = new HashSet<String>();


hs.add("Hello"); // Checks if exists before inserting

Java S8 Programmer I (1Z0 - 808) Página 17


// Traversing elements
Iterator<String> itr = hs.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}

★ LinkedHashSet → Set
■ Usa un double link para almacenar el orden de inserción.
■ Set linkedHashSet = new LinkedHashSet(10);

★ SortedSet:→ Set
■ Es una interfaz que tiene métodos extras para mantener el orden de los elementos.

★ TreeSet:→ SortedSet
■ Ordena los elementos.
■ Más lento que HashSet.
■ Los elementos deben implementar la interfaz Comparable.
■ Usa una estructura de árbol para almacenar los elementos.
■ Set treeSet = new TreeSet();

● Map
✓ Asocia key-value.
✓ No contiene claves duplicadas.
✓ No son sincronizadas (a menos que se adapte con Collections.synchronizedMap)
★ HashMap:
■ Sin orden por qué?
■ Buen rendimiento
■ Tamaño inicial por default de 16, por rendimiento se recomienda definir el tamaño inicial.

Map<Integer, List> hashMap = new HashMap<>(); //usando generics


Map hashMap = new HashMap(); //Sin usar generics
hashMap.put(key, value); //puts or replaces
hashMap.get(key); //returns the value of that key
hashMap.remove(key); //returns the value removed
hashMap.remove(key, value); //removes if key and value are present

hashMap.putIfAbsent(key, value); //puts ONLY if doesn't exist (not replace)


hashMap.getOrDefault(key, DefaultValue); //if doesn't exist, returns this
hashMap.replace(key, oldValue, newValue); //replaces if key and oldValue are present
hashMap.replace(key, newValue); //replaces if key is present, returns oldValue

hashMap.keySet(); //returns list of keys as a Collection


hashMap.values(); //returns list of values as a Collection
hashMap.entrySet(); //returns list of keys/values as a Collection

// Traversing through keys only


for (Integer key : hashMap.keySet())
System.out.println(key + " " + hashMap.get(key));

// Traversing through values only


for (String value : hashMap.values())
System.out.println(value);

// Traversing through the whole HashMap


for (Map.Entry<Integer, String> entry : hashMap.entrySet())
System.out.println(entry.getKey() + " " + entry.getValue());

hashMap.computeIfPresent("One",(k,v) -> k+v); //performs an operation if the value


is present

★ TreeMap:
■ Sorted elements, Ordena las claves en función de su valor.
■ Más lento que HashMap.
■ Las claves deben implementar Comparable.

Map<Integer, String> treeMap = new TreeMap<Integer, String>();

★ LinkedHashMap

Java S8 Programmer I (1Z0 - 808) Página 18


■ Almacena claves en función del orden de inserción.
■ Poco más costosa que HashMap.
Map<Integer, String> linkedHashMap = new LinkedHashMap<Integer, String>();

● Queue → Collections
✓ Is a First-in, First-out. (FIFO) data structure. In this structure, new elements are inserted at one end and existing elements are
removed from the other end.
✓ No son sincronizadas
✓ Más usadas con PriorityQueue y LinkedList
Queue<Integer> q = new LinkedList<>();
q.add(1);
int removedele = q.remove(); // To remove the head of queue.
int head = q.peek(); // To view the head of queue

Iterator iterator = q.iterator();


while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}

★ PriorityQueue: → Queue
■ each element having a priority associated with it.
Map<Integer, String> linkedHashMap = new LinkedHashMap<Integer, String>();
Queue<String> pq = new PriorityQueue<>();
pq.offer(1); //inserts and attends immediately
pq.poll(); // To remove the head of queue.

Trees
✓ Data structure conformed by: Root, child and leaf (no more children).
★ Binary Tree:
■ Conformed by 0 to 2 child nodes (left & right).
■ Shape:
● Balanced: the height of the left and right subtree of any node differ by not more than 1.
● Unbalanced: the height of the left and right subtree of any node differ by more than 1.
■ Traversal:
● Inorder: 1) Left 2) Root 3) Right
● Preorder: 1) Root 2) Left 3) Right
● Postorder: 1) Left 2) Right 3) Root

Graphs
✓ A graph contains a set of nodes and edges. The nodes are also called vertices. Edges are used to connect nodes. Nodes are
used to store and retrieve data.

Java S8 Programmer I (1Z0 - 808) Página 19


Generic Types
A generic type is a generic class or interface that is parameterized over types. A generic class is defined with the following format:
class name<T1, T2, ..., Tn> { /* ... */ }

The type parameter section, delimited by angle brackets (< >), follows the class name. It specifies the type parameters (also called
type variables) T1, T2, ..., and Tn.
To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public
class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class.

public class Box<T> { // T stands for "Type"


private T t;

public void set(T t) { this.t = t; }


public T get() { return t; }
public void getType() {
System.out.println("T type is: " +
t.getClass().getSimpleName());
}
}

Java S8 Programmer I (1Z0 - 808) Página 20


Box<Integer> integerBox = new Box<Integer>(); // To instantiate, but
redundant
Box<Integer> integerBox = new Box(5); // using variable type inference
integerBox.getType(); //returns Integer

All occurrences of Object are replaced by T. A type variable can be any non-primitive type you specify: any class type, any interface
type, any array type, or even another type variable.

The most commonly used type parameter names are:


● E - Element (used extensively by the Java Collections Framework)
● K - Key (in maps)
● N - Number
● T - Type (a class)
● V - Value (in maps)
● S,U,V etc. - 2nd, 3rd, 4th types

Esto puede ser usado en todos los elementos de la interfaz Collection, para que el compilador agregue validaciones en tiempo de
compilación por ejemplo:

List<String> arrayList = new ArrayList<>();//<> is called 'diamond notation'


arrayList.add("text"); //now stores only Strings instead of Objects
arrayList.get(0); //returns Strings instead of Objects

arrayList.forEach(element ->{ //iterate elements


System.out.println(element);
});

Excepciones en Java
Una excepción es un evento que se produce cuando se ejecuta el programa de forma que interrumpe el flujo normal de
instrucciones.Throwable error son los errores en tiempo de ejecución producidos dentro de la JVM y no en nuestros programas, tales
como el OutOfMemoryError.

Java S8 Programmer I (1Z0 - 808) Página 21


Manejo de archivos
Crear/escribir/anexar contenido a archivos en la raiz del proyecto (Proyecto/fileName.txt)
File file = new File("fileName.txt");
try {
PrintWriter output = new PrintWriter(file); //Creates OR overwrites file
PrintWriter output = new PrintWriter(new FileWriter(file,true)); //Append new information to existing
file
output.println("File content"); //Writes in file
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace(System.out);
} catch (IOException e) {
e.printStackTrace(System.out);
}

Leer archivo
File file = new File("fileName.txt");
try {
BufferedReader input = new BufferedReader(new FileReader(file));
String reader = input.readLine();
while(reader != null){ //Reads while there's content in file
System.out.println(reader);
reader = input.readLine();
}
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace(System.out);
} catch (IOException e) {
e.printStackTrace(System.out);
}

Try-with-resource
Es un bloque try que declara uno o más recursos (objeto que debe ser cerrado después de que el programa terminó con él, ya sea de
forma exitosa o abrupta) asegurándose que todos los recursos son cerrados al final de cada sentencia. Cualquier objeto que
implemente java.lang.AutoCloseable, puede ser usado como un recurso.
static String readFirstLineFromFile(String path) throws IOException {
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
return br.readLine();
}
}
// FileReader y BufferedReader deben ser cerrados, antes se colocaba el cierre dentro del
bloque finally, pero con esto ya no es necesario.

Java S8 Programmer I (1Z0 - 808) Página 22


// Java 9
try (resource1;
resource2) {
}

Java S8 Programmer I (1Z0 - 808) Página 23


Novedades Java 8 (2014)
● Métodos por defecto en las interfaces
Antes de Java 8, en las interfaces solo podíamos tener constantes y métodos abstractos. A partir de Java 8 ya puede tener también
métodos por defecto que se declaran con public default y sí llevan cuerpo.

Estos métodos no se tienen que declarar en la clase que


implementa a la interfaz, sino que pueden ser utilizados
directamente. Pero sí pueden ser sobreescritos en caso de que
así se desee usando @Override.

Funciones Lambda
Son funciones anónimas que no necesitan una clase, su estructura es: (parámetros) -> {cuerpo lambda}
Trabajan en conjunto con las interfaces funcionales, para asignar diferentes comportamientos a un método abstracto.
@FunctionalInterface
public interface ICalculadoraLambda {
public int operacion (int x,int y);
}

ICalculadoraLambda iSuma = (x,y) -> x + y;


System.out.println(iSuma.operacion(4, 5));

ICalculadoraLambda iMultiplicacion= (x,y) -> x * y;


System.out.println(iMultiplicacion.operacion(4, 5));

Scope de variables en funciones lambda:


● Variable local: se comporta como variable final (solo lectura).
● Propiedades de lectura y escritura.

Interfaces funcionales (@FunctionalInterface)


Java 8: Son interfaces que tienen un solo método abstracto (sin cuerpo). Esto significa que cada interfaz creada que respeta esta
premisa se convierte automáticamente en una interfaz funcional. Se puede usar opcionalmente la anotación
@FunctionalInterface para obligar al compilador a marcar error si no se cumple con las reglas.
@FunctionalInterface
public interface IStrategy {

public String sayHelloTo(String name); //Abstract method


public default String sayHelloWord(){ //Default method
return "Hello word";
}
}

public class Main {


public static void main(String[] args) {
IStrategy strategy = (name) -> "Hello " + name;

System.out.println(strategy.sayHelloTo("Oscar Blancarte"));
System.out.println(strategy.sayHelloWord());
}
}

Cuando una expresión lambda es asignada a una interfaz, esta siempre implementará el método abstracto, es por esta razón por la
que solo puede existir un método abstracto y varios defaults.

Se clasifican de la siguiente manera:


★ Supplier (proveedores): son expresiones lambda que no tienen parámetros pero devuelven un resultado por medio del
método get(). Used for factory design pattern

Java S8 Programmer I (1Z0 - 808) Página 24


@FunctionalInterface
public interface Supplier<T> {//Generic Type
T get();
}
Supplier //Suplier<OUTPUT>
Supplier<Double> randomValue = () -> Math.random();
System.out.println(randomValue.get());
★ Consumer y BiConsumer: Consumer aceptan un solo valor, pero no devuelven ningún valor, solo ejecutan una operación en
dicho argumento. BiConsumer, aceptan 2 valores. They both use the accept() method. Fire and Forget.

@FunctionalInterface
public interface Consumer<T> {
//Performs this operation on the given argument
void accept(T t);
}

Consumer //Consumer<INPUT>
Consumer<Integer> display = a -> System.out.println(a);
display.accept(10);

BiConsumer //BiConsumer<INPUT, INPUT>


void accept(T t, U u);
BiConsumer<Integer, String > arrayLists = (age, name) ->
System.out.println(age+ " & " + name);
arrayLists.accept(20, "Chuy");

★ Predicate y BiPredicate: Predicate aceptan un solo valor y devuelven un valor booleano mientras que las BiPredicate aceptan
2 parámetros. They both use the test() method.
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Predicate //Predicate<INPUT>
Predicate<Integer> isAdult = age -> age>18;
System.out.println(isAdult.test(20));

BiPredicate //Predicate<INPUT, INPUT>


boolean test(T t, U u);
BiPredicate<Integer, String> areEquals = (n, s) -> (n == Integer.parseInt(s))?true:false;
System.out.println(areEquals.test(2, "2"));

★ Function y BiFunction: Function expressions accept one argument and return one value as a result, whereas BiFunction
expressions accept two arguments and return one result. They both use the apply() method.
@FunctionalInterface
public interface Function<T, R> {//Applies this function to the given argument
// R = return value, t = input argument
R apply(T t);
}

Function //Function<INPUT, RETURN>


Function<Integer, Double> halfOf = a -> a / 2.0;
System.out.println(halfOf.apply(10));

Function<String, Integer> stringLength = s -> s.length();


int length = stringLength.apply("Hello"); // Returns "Hello" length

//Example:
List<String> songTitles = Arrays. asList("humble", "element", "dna");
Function<String, String> capitalize = str -> str.toUpperCase() ;
songTitles.stream().map(capitalize).forEach(System.out::println);

BiFunction //BiFunction<INPUT, INPUT, RETURN>


R apply(T t, U u);

BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;


System.out.println("Sum = " + add.apply(2, 3));

//Example:

Java S8 Programmer I (1Z0 - 808) Página 25


BiFunction<Integer, String, String> biFunction = (key, value) -> {
if (key == 101)
return "sí";
else
return "no";
};

HashMap<Integer, String> scoreMap = new HashMap<>();


scoreMap.replaceAll(biFunction); //la función opera solo en los valores
(String), por lo que la biFunction debe también regresar String.

★ UnaryOperator y BinaryOperator: UnaryOperator recibe un argumento y devuelve un valor del mismo tipo. En las
BinaryOperator se reciben dos argumentos del mismo tipo y devuelve un valor del mismo tipo. Extiende de Function
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T,T>{

UnaryOperator //UnaryOperator<INPUT, RETURN>


UnaryOperator<Integer> multUnary = x -> x * 2;
System.out.println(multUnary.apply(2));

//Example:
List<String> dates = new ArrayList<String>();
UnaryOperator<String> replaceSlashes = date -> date. replace("/", "-");
dates.replaceAll(replaceSlashes); //Podría ser también con Function<String,
String> pero el método replaceAll de List solicita que sea UnaryOperator

BinaryOperator //BinaryOperator<INPUT, INPUT, RETURN>


BinaryOperator<Integer> multBinary = (x,y)-> x * y;
System.out.println(multBinary.apply(2,3));

● Referencias a métodos (Method References)


Las referencias a los métodos nos permiten reutilizar un método como expresión lambda. Para hacer uso de las referencias a
métodos basta con utilizar la siguiente sintáxis:
referenciaObjetivo::nombreDelMetodo.
File::canRead // en lugar de File f -> f.canRead();

Con las referencias a los métodos se ofrece una anotación más rápida para expresiones lambda simples y existen 3 tipos diferentes:

★ Métodos estáticos

(String info) -> System.out.println(info) //Expresión lambda sin referencias.


System.out::println //Expresión lambda con referencia a método estático.

★ Métodos de instancia de un tipo

(Student student, int index) -> student.getRegistry(index) //Expresión lambda sin referencias.
Student::getRegistry //Expresión lambda con referencia a método de un tipo.

Arrays.sort(nombres, String::compareToIgnoreCase);

★ Métodos de instancia de un objeto existente.

Student student -> getMarks(student) // Expresión lambda sin referencias.


this::getMarks // Expresión lambda con referencia a método de un objeto existente.

● Stream API
✓ Se agrega el método por default stream() en la clase Collection.
✓ Con parallelStream()se ejecutan operaciones en paralelo (multi-threading).
✓ Realiza operaciones funcionales sobre cualquier objeto de tipo Collection sin modificar el objeto original, sino que entrega
un tipo Stream.
✓ Sustituye iteraciones, como for, for-each, while.
✓ Permite operaciones encadenadas.
✓ Se dividen en intermediate operations (Stream<T> ) y terminal operations (regresa un resultado de un tipo definido).

Java S8 Programmer I (1Z0 - 808) Página 26


long count = list.stream().distinct().count();
//distinct() es intermediate operation porque regresa otro Stream, y count() es terminal
operation porque regresa el tamaño del stream.

✓ Matching: busca coincidencias y devuelven un valor booleano, dado un predicado.


boolean anyMatch = list.stream().anyMatch(e -> e.contains("h")); // cualquier coincidencia
boolean allMatch = list.stream().allMatch(e -> e.contains("h")); // todos coinciden
boolean noneMatch = list.stream().noneMatch(e -> e.contains("h")); // Ninguno coincide
Stream.empty().allMatch(Objects::nonNull); //For empty streams, the allMatch() method with
any given predicate will return true

✓ Filter: devuelve un nuevo Stream con solo los elementos que satisfacen el Predicate.
Stream<String> stream = list.stream().filter(element -> element.contains("d"));

✓ map(): convierten elementos de un Stream, aplicando una función a cada uno de los elementos de la colección, agregándolos
a un nuevo Stream.
numberList.stream().map(x -> Integer.valueOf(x) + 2)
//Returns a new Stream with all elements + 2

✓ reduce(): reduce una secuencia de elementos de acuerdo a una función y los acumula al valor inicial especificado.
List<Integer> list = Arrays.asList(1, 1, 1);
Integer reduced = list.stream().reduce(23, (a, b) -> a + b);
//sums 23 + [the list] = 26

List<String> letters = Arrays.asList("a", "b", "c", "d", "e");


String result = letters.stream().reduce("", String::concat); //returns "abcde"

Optional<Double> sum = products.stream().map(Product::getPrice)


.reduce(Double::sum);
sum.get(); //equivale a .reduce((a,b) -> a+b);

✓ collect(): reduce un Stream en un Collection o un Map. Puede usar toList(), toMap(), toSet()
List<String> resultList = numberList.stream().map(element ->
element.toUpperCase()).collect(Collectors.toList());//reduce el Stream a un
List

List names =
people.stream().map(Person::getName).collect(Collectors.toList()); //A partir
de una lista de personas, obtenemos una lista con todos los nombres.

✓ Collectors.groupingBy(): retorna un Map con la agrupación de la colección


Map<Double, List<Product>> productsGrouped =
products.stream().collect(Collectors.groupingBy(Product::getPrice)) //key =
cada uno de los diferentes precios agrupados
//value = lista con los productos que coincidan con cada Key

✓ Collectors.counting() ó summingDouble(): cuenta las coincidencias a partir de un criterio


Map<String, Double> productsCounted= products.stream()
.collect(Collectors.groupingBy(Product::getName, Collectors.counting()));
//ó Collectors.summingDouble(Product::getPrice)));
//key = Nombre del producto
//value = Conteo de coincidencias por nombre de producto.
//value = suma de productos coincidentes

✓ Collectors.summarizingDouble(): regresa un objeto DobleSummaryStatistics con estadísticas como conteo, suma, mínimo,
máximo, promedio, etc.
DobleSummaryStatistics statistics = products.stream()
.collect(Collectors.summarizingDouble(Product::getPrice));

✓ Stream of Array: un array puede ser convertido a Stream


String[] arr = new String[]{"a", "b", "c"};
Stream<String> streamOfArrayFull = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3);

✓ Stream builder: This allows the creation of a Stream by generating elements individually and adding them to the Builder
Stream<String> stream = Stream.<String>builder().add("a").add("b").build();
stream.forEach(System.out::println);

Java S8 Programmer I (1Z0 - 808) Página 27


✓ Generate: Acepta un Supplier<T> para generación de elementos, regresa una secuencia del tamaño especificado (si no, lo
genera infinitamente).
Stream<String> streamGenerated = Stream.generate(() -> "element")
.limit(10) //muestra solo 10 resultados
.skip(3); //omite los 3 primeros
//crea una secuencia de 10 strings con la palabra "element"

✓ Iterate: otra manera de crear un stream infinito usando el método iterate()


Stream<Integer> streamIterated = Stream.iterate(40, n -> n + 2).limit(20);
//crea una

Java 9
✓ dropWhile() permiten descartar o tomar elementos del stream mientras se comprueba una condición.
✓ TakeWhile()
✓ ofNullable(): devuelve un stream de un elemento o vacío dependiendo de si el objeto es null o no.
✓ iterate(): permiten generar un secuencia de valores similar a un bucle for.

● Marker interface
A marker interface is an interface that doesn’t have any methods or constants inside it. It provides run-time type information about
objects, so the compiler and JVM have additional information about the object.Is also called a tagging interface.
Though marker interfaces are still in use, they very likely point to a code smell, and we should use them carefully. The main reason for
this is that they blur the lines of what an interface represents, since markers don’t define any behavior. Newer development favors
annotations to solve some of the same problems.

https://www.baeldung.com/java-8-streams#:~:text=Java%208%20offers%20the%20possibility,%3A%20IntStream%2C%20LongStream
%2C%20DoubleStream

● Java.time
✓ Nueva API para fechas, horas, instantes y duraciones en formato ISO (yyyy-MM-dd).
✓ Incluye LocalDate (2022-08-07), LocalTime (10:36), LocalDateTime (2022-08-07T10:36), ZonedDateTime
(2022-08-07), Period, Duration
✓ Todas las clases son inmutables y Thread-safe.

★ LocalDate: representa una fecha en formato ISO (yyyy-MM-dd)

LocalDate localDate = LocalDate.now(); //fecha actual


LocalDate.of(2015, 02, 20); //fecha especificada
LocalDate.parse("2015-02-20"); //fecha especificada
LocalDate tomorrow = LocalDate.now().plusDays(1); //+1 día
LocalDate previousMonthSameDay = LocalDate.now().minus(1,
ChronoUnit.MONTHS); //-1 MONTH
DayOfWeek sunday = LocalDate.parse("2016-06-12").getDayOfWeek();
int twelve = LocalDate.parse("2016-06-12").getDayOfMonth();
boolean leapYear = LocalDate.now().isLeapYear(); //año bisiesto
boolean notBefore = LocalDate.parse("2016-06-12")
.isBefore(LocalDate.parse("2016-06-11")); //ó isAfter
LocalDateTime beginningOfDay =
LocalDate.parse("2016-06-12").atStartOfDay(); //(2016-06-12T00:00)
LocalDate firstDayOfMonth = LocalDate.parse("2016-06-12")
.with(TemporalAdjusters.firstDayOfMonth());//(2016-06-01)

★ LocalTime: representa una hora sin fecha (10:36)

LocalTime now = LocalTime.now(); //hora actual


LocalTime sixThirty = LocalTime.parse("06:30");

Java S8 Programmer I (1Z0 - 808) Página 28


LocalTime sixThirty = LocalTime.of(6,30);

LocalTime sevenThirty =
LocalTime.parse("06:30").plus(1,ChronoUnit.HOURS);
int sevenThirty = LocalTime.parse("06:30").getHour();
boolean sevenThirty =
LocalTime.parse("06:30").isBefore(LocalTime.parse("07:30"));
LocalTime sevenThirty = LocalTime.MAX //23:59:59.99

★ LocalDateTime: representa una combinación de hora y fecha (2016-06-12T00:00)

LocalDateTime now = LocalDateTime.now(); //fecha y hora actual


LocalDateTime.of(2015, Month.FEBRUARY, 20, 06, 30);
LocalDateTime.parse("2015-02-20T06:30:00");
LocalDateTime.plusDays(1);
LocalDateTime.minusHours(2);
LocalDateTime.getMonth();
//convierte objetos tipo Date y Calendar a Date y Time
LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
LocalDateTime.ofInstant(calendar.toInstant(),
ZoneId.systemDefault());
localDateTime.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
localDateTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatSty
le.MEDIUM)
.withLocale(Locale.UK)); // 25-Jan-2015, 06:30:00:

★ Period: usado para modificar los vsalores de una fecha u obtener diferencia entre dos fechas. Representa una cantidad de
tiempo en términos de años, meses y días.

LocalDate.parse("2007-05-10").plus(Period.ofDays(5));
int fiveDays = Period.between(initialDate, finalDate).getDays();
long fiveDays = ChronoUnit.DAYS.between(initialDate, finalDate);

★ Duration: Representa una cantidad de tiempo en términos de segundos y nanosegundos.

LocalTime.of(6, 30, 0).plus(Duration.ofSeconds(30)); //06:30:30


long thirty = Duration.between(initialTime, finalTime).getSeconds();
long thirty = ChronoUnit.SECONDS.between(initialTime, finalTime);

https://www.baeldung.com/java-8-date-time-intro

● Optional
✓ Objeto contenedor que puede o no contener un valor null.
✓ ofNullable() regresa Optional[valor] o Optional.empty
✓ isPresent() regresa true o false
✓ ifPresent() ejecuta un bloque si el valor es presente.
✓ get() regresa el valor, si está presente, si es null regresa NoSuchElementException
✓ orElse() si es null, regresa un valor por defecto
✓ orElseGet() regresa el valor si está presente, si es null, regresa el valor generado por un Supplier
✓ orElseThrow() regresa el valor si está presente, si es null, regresa la excepción generada por un Supplier
✓ of() regresa un Optional con el valor especificado
✓ empty() regresa un Optional.empty
✓ map regresa un Optional con el resultado de aplicar una función mapping, si es null, regresa Optional.empty

Java 9

Java S8 Programmer I (1Z0 - 808) Página 29


✓ or() If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying
function.
✓ ifPresentOrElse() helps us to perform the specified Consumer action the value of this Optional object. If a value is not
present in this Optional, then this method performs the given empty-based Runnable emptyAction, passed as the second
parameter
✓ stream() regresa un Stream con el valor si está presente, si es null, regresa un Stream vacío

Optional<String> op = Optional.ofNullable(result); //puede contener null


String value = op.orElse("0"); //si es nulo, regresa 0
op.orElseThrow(NumberFormatException::new); //regresa una exception del tipo
especificado

Optional<Integer> op = Optional.empty();
op.or(() -> Optional.of(100)) //returns Optional[100]

op.ifPresentOrElse( //regresa el valor, si no, un texto


(value) -> { System.out.println("Value is present, its: " + value); },
() -> { System.out.println("Value is empty"); });

op.orElseGet( () -> (int)(Math.random() * 10))); //si es nulo, regresa el


resultado de una operación

op.orElseThrow(ArithmeticException::new)); //si es nulo, regresa una excepción


del tipo ArithmeticException

Novedades Java 10 (marzo 2018)


● Inferencia de tipos (local-variable type inference) Java10
La inferencia de tipos es un proceso por el cual el compilador determina el tipo de una variable local que ha sido declarada sin una
declaración explícita de su tipo. El tipo es inferido a partir del valor inicial provisto a la variable. En Java existe a partir de la versión 10
y solo para las variables locales, no para atributos de una clase, ni como argumentos de función.
var contador=10;

● Métodos de copia
Se incluye el método estático copyOf() en interfaces de Collection para crear copias inmutables.

var copyArray = List.copyOf(arrayInt);


copyArray.add(10) //exception!!

● Métodos de reducción
La clase Collectors incluye otros 3 métodos además de toList(), toSet() y toMap() de Java 8 para reducir un Stream a
Collection. Dichos métodos son: método estático toUnmodificableSet(), toUnmodificableList(), toUnmodificableMap(),
para generar colecciones inmutables.

Novedades Java 11 (septiembre 2018)


● Inferencia de tipos en Lambdas
Incluye la palabra var para inferencia de tipos en expresiones lambdas. Debe inferirse en todos los parámetros, no solo en algunos.

(var a, var b)-> a*b; //valid!!


(var a, b)-> a*b; //invalid!!
(var a, int b)-> a*b; //invalid!!

● Nuevos métodos en String


✓ booleanIsBlank() devuelve true si la cadena está vacía o tiene solo espacios en blanco (es diferente a isEmpty(), que
revisa si la longitud de la cadena es 0).
var k = " "; //true!!

Java S8 Programmer I (1Z0 - 808) Página 30


✓ lines() método estático que regresa un Stream de líneas extraídas de un String multilínea, separado por enters.
String str = "A \n B \n C \n D";
Stream<String> lines = str.lines();
lines.forEach(System.out::println);

✓ repeat(n) retorna un String cuyo valor es la concatenación de el String dado, repetido n veces.
String str = "Abc";
System.out.println(str.repeat(3));//AbcAbcAbc

✓ Strip() retorna un String dado con todos los espacios al inicio y final removidos. Puede ser también StripLeading() o
StripTrailing().
String str = "Abc";
System.out.println(str.repeat(3));//AbcAbcAbc

● Comparación en StringBuilder
Es posible comparar dos StringBuilder lexicográficamente sin necesidad de transformarlos en String, ya que la clase dispone del
método compareTo.
sb1.CompareTo(sb2);
//-1: sb1 < sb2
// 0: sb2 = sb1
// 1: sb1 > sb2

Novedades Java 12

Java S8 Programmer I (1Z0 - 808) Página 31

También podría gustarte