Está en la página 1de 22

Módulo 4: Conceptos avanzados de programación orientada

a objetos

Teoría
 Libros recomendados certificaciones
o Portadas

Portada_OCA_JavaSE8_Study_Guide.pdf

Portada - OCA_OCP_JavaSE8_Practice_Tests.pdf

 Generics & Collections


o Ejercicio hecho en clase Generics

Animal.java

package hoy_prueba5;

/**
*
* @author javilukt
*/
public class Animal {
@Override
public String toString(){
return "Soy una instancia de animal";
}
}

ClaseConAnimal.java

package hoy_prueba5;

/**
*
* @author javilukt
*/
public class ClaseConAnimal {
Animal a;

@Override
public String toString(){
return "Soy una instancia de clase con campo animal";
}

}
ClaseConCosa.java

package hoy_prueba5;

/**
*
* @author javilukt
*/
public class ClaseConCosa {
Cosa c;

@Override
public String toString(){
return "Soy una instancia de clase con campo cosa";
}
}

ClaseConPersona.java

package hoy_prueba5;

/**
*
* @author javilukt
*/
public class ClaseConPersona {
Persona p;

@Override
public String toString(){
return "Soy una instancia de clase con campo persona";
}
}

ClaseGenerica.java

/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-
default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to
edit this template
*/
package hoy_prueba5;

/**
*
* @author javilukt
* @param <T>
*/
public class ClaseGenerica<T> {
T t;

ClaseGenerica(T t) {
this.t = t;
}

T getT() {
return t;
}

@Override
public String toString(){
return "Soy una instancia de " + getClass().getSimpleName() + " con
campo "
+ t.getClass().getSimpleName();
}
}

Cosa.java

package hoy_prueba5;

/**
*
* @author javilukt
*/
public class Cosa {
@Override
public String toString(){
return "Soy una instancia de cosa";
}

Persona.java

package hoy_prueba5;

/**
*
* @author javilukt
*/
public class Persona {
@Override
public String toString(){
return "Soy una instancia de persona";
}
}

Test.java

package hoy_prueba5;

/**
*
* @author javilukt
*/
public class Test {

public static void main(String[] args) {


ClaseGenerica<Persona> cgp = new ClaseGenerica<>(new Persona());
ClaseGenerica<Cosa> cgc = new ClaseGenerica<>(new Cosa());
System.out.println(cgp);
System.out.println(cgc);
}

o Generic Class

<aside> 🔵 Generic Classes

Ejemplo: el campo a es de un tipo T que puede variar.

class A<T> {
private T a;
public A(T a) {this.a = a;}
public T getInfo() {return a;}
public void putInfo(T a) {this.a = a;}
}

Ejemplo: “doblemente” genéricos

class A<T, U> {


private T a;
private U b;
public A(T a, U b) {this.a = a; this.b = b;}
}
// Para usarla
X x = new X();
Y y = new Y();
A<X, Y> item = new A<>(x, y);

<aside> 🔹 Mucho cuidado generics ayudan en tiempo de compilación, pero


no en tiempo de ejecución.

</aside>

<aside> 🔹 Legacy code - raw generics Collecciones escritas sin usar


generics. El compilador da warning.

</aside>

</aside>
o Basics

<aside> 🔵 Array & ArrayList

Elementos permitidos:

 Array: referencias a objetos y primitivos.


 ArrayList: referencias a objetos.

ArrayList

List<String> l = new ArrayList<>();


l.add("uno");
l.add("dos");

l.size(); // tamaño

Array

// 3 formas equivalentes
String[] a = new String[2];
a[0] = "uno"; a[1] = "dos";

String[] a = new String[]{"uno", "dos"};

String[] a = {"uno", "dos"};

a.length; // tamaño

Array ←→ ArrayList

String[] a = {"uno", "dos"};


List<String> l = Arrays.asList(a);
l.set(1, "DOS");
String[] aa = **(String[])**l.toArray();

</aside>

<aside> 🔵 Searching & Sorting

Array

int[] a = {6, 9, 1, 8};


Arrays.sort(a);
System.out.println(Arrays.binarySearch(6, a)); // 1
System.out.println(Arrays.binarySearch(7, a)); // -3
List

List<Integer> l = Arrays.asList(6, 9, 1, 8);


Collections.sort(l);
System.out.println(Collections.binarySearch(6, l)); // 1
System.out.println(Collections.binarySearch(7, l)); // -3

</aside>

<aside> 🔵 Wrapper Classes & Autoboxing

Wrapper Classes

Boolean b = new Bolean(true);


Byte by = new Byte((byte)3);
Short s = new Short((short)3);
Integer i = new Integer(3);
Long l = new Long(3);
Float d = new Float(3.0);
Double d = new Double(3.0);
Character d = new Character('a');

Autoboxing - Unboxing

List<Integer> l = new ArrayList<>();


l.add(3); **// autoboxing**
l.add(new Integer(3));
int n = l.get(1); **// unboxing**

Mucho cuidado

// distinguir
l.remove(1); // borra el elemento de indice 1
l.remove(new Integer(3);); // borra primera coincidencia de
objeto

</aside>

<aside> 🔵 Diamond Operator

List<String> l = new ArrayList<>();


// también en 2 líneas
List<String> l;
l = new ArrayList<>();

</aside>

o Using List, Set and Map


<aside> 🔵 Collections

Conjunto de objetos contenidos en un objeto.

4 interfaces principales en java.util.*

1. List: ordenada y permite duplicados.


2. Set: no ordenada y no permite diplicados.
3. Map: mapea keys con values, sin permitir keys duplicadas.

Interfaces y subinterfaces de collections


</aside>

<aside> 🔵 Métodos del interfaz Collections

<aside> 🔹 E es típico cuando usamos generics en Collections

</aside>

boolean add(E element):

 según el collection type devolverá siempre true o habrá una lógica


relativa al éxito.

List<String> l = new ArrayList<>();


l.add("one"); // devuelve siempre true
Set<String> s = new HashSet<>();
s.add("one"); // devuelve true
s.add("one"); // devuelve false, ya existía

boolean remove(Object object):

 elimina el primer valor que hace match.


 devolverá true si éxito, o false si fracaso.
 boolean remove(int i) → si la Collection lo soporta la búsqueda es
por indice.

List<String> l = new ArrayList<>();


l.add("one"); list.add("two");
l.remove("one"); // devuelve true
l.remove("one"); // devuelve false

boolean isEmpty() & int size()

List<String> l = new ArrayList<>();


l.add("one"); list.add("two");
l.isEmpty(); // devuelve false
l.size(); // devuelve 2

void clear():

 Vacía la Collection

List<String> l = new ArrayList<>();


l.add("one"); list.add("two");
l.clear();
l.isEmpty(); // devuelve true

boolean contains(Object object):

 Saber si un objeto está en una colección


List<String> l = new ArrayList<>();
l.add("one"); list.add("two");
l.contains("one"); // devuelve true
l.contains("four"); // devuelve false

</aside>

<aside> 🔵 **List Interface**

 ArrayList, buena selección cuando hay mucha lectura, ya que:


1. Tiempo de rescate de cualquier elemento es constante.
2. Add o Remove es mas lento de acceso.
 LinkedList implements List, Queue

Es una buena elección cuando se utiliza como cola, ya que:

1. R/W/D: mismo tiempo cuando es en los extremos.


2. Trabajar con alguna posición central requiere tiempo lineal.

<aside> 🔹 List Methods

void add(E element): añade elementos al final.

void add(int index, E element): añade elementos en una posición.

E get(int index): lee elemento en una posición.

int indexOf(Object o): devuelve el índice de un elemento si lo encuentra.

int lastIndexOf(Object o): devuelve el último indice de un elemento si lo


encuentra.
void remove(int index): borra un elemento basado en índice.

E set(int index, E e): cambia el valor de un elemento dado su índice.

List<String> l = new ArrayList<>();


l.add("zero"); l.add("one"); l.add("two");
l.set(2,"TWO");
l.remove("TWO"); // borrado por valor
l.remove(0); // borrado por índice

</aside>

<aside> 🔹 Recorriendo una List

Lo más práctico

List<String> l = new ArrayList<>();


l.add("zero"); l.add("one"); l.add("two");
for (String s : l);

</aside>

</aside>

<aside> 🔵 Set Interface

 HashSet, utiliza una hashTable, es decir, una tabla con hashCode. Así:
1. Add and Check si está: tiempo constante.
2. Orden: no existe.
3. Es el más común.

 TreeSet almacena los elementos en una estructura en árbol ordenada.


1. Orden: si.

<aside> 🔹 Methods: suficiente con los de Collection

Set<-integer> s = new HashSet<>();


s.add(6); // devuelve true
s.add(10); // devuelve true
s.add(6); // devuelve false
s.add(8); // devuelve true
for (Integer i : s)
System.out.print(i + " ");
// El orden puede ser cualquiera
// 6 8 10
Set<-integer> s = new TreeSet<>();
s.add(6); // devuelve true
s.add(10); // devuelve true
s.add(6); // devuelve false
s.add(8); // devuelve true
for (Integer i : s)
System.out.print(i + " ");
// Directamente ordenado
// 6 8 10

</aside>

<aside> 🔹 Métodos específicos para TreeSet

Métodos más interesantes que aporta:

 E lower(E e): mayor que cumple < e, si no hay null.


 E floor(E e): mayor que cumple <= e, si no hay null.
 E ceiling(E e): menor que cumple >= e, si no hay null.
 E higher(E e): menor que cumple > e, si no hay null.

NavigableSet<Integer> s = new TreeSet<>();


for (int i=1; i < 21; i++) s.add(i);
s.lower(10); // 9
s.floor(10); // 10
s.ceiling(20); // 20
s.higher(20); // null

</aside>

</aside>

<aside> 🔵 **Map interface**

TreeMap: sorted y navigable.

HashMap: almacena las keys en una HashTable (usa el método hashCode()


para mayor eficiencia encontrando elementos.

18. Add and obtener por key: tiempo constante.


19. Orden: no existe.
20. Es el más común.

TreeMap: almacena las keys en una estructura ordenada de árbol.

21. keys: siempre ordenadas.


22. Add and check if: O(log n).

<aside> 🔹 Methods Map (recordar que NO implements Collections)


 void clear(): deja vacío el Map.
 boolean isEmpty(): devuelve si Map vacío.
 int size(): devuelve el número de entradas (key/value pairs).
 V get(Object key): devuelve el valor mapeado por key.
 V put(K key, V value): añade o reemplaza el par key/value.
Devuelve el valor anterior o null.
 V remove(Object key): borra el elemento según key. Devuelve el
valor borrado o null si no había esa key.
 boolean containsKey(Object key): si la key está en el Map.
 boolean containsValue(Object value): si el value está en el Map.
 Set<K> keySet(): devuelve un Set con todas las keys.
 Collection<V> values(): devuelve una Collection con toso los
values.

Map<String, String> m = new HashMap<>();


m.put("2", "dos");
m.put("1", "uno");
m.put("3", "tres");
m.get("2"); // dos
for(String key: m.keySet())
System.out.print(key + " ");
// 2 1 3 en elorden de inserción.
Map<String, String> m = new TreeMap<>();
m.put("2", "dos");
m.put("1", "uno");
m.put("3", "tres");
m.get("2"); // dos
for(String key: m.keySet())
System.out.print(key + " ");
// 1 2 3 ordenado

</aside>

</aside>

o Comparator vs. Comparable

<aside> 🔵 Orden:

En String(usando el unicode character mapping):

1. Números
2. Letras mayúsculas
3. Letras minúsculas

Mucho cuidado:
 interfaz Comparable: define el orden por defecto entre objetos de una
clase mediante el método de instancia int compareTo(MyClass A)
 clase Comparator: permite usar un orden especial entre objetos ya sea
por:
1. Por no tener implementado Comparable.
2. Por necesitar alterar el orden de Comparable. </aside>

<aside> 🔵 Comparable

Tres reglas al implementar el método compareTo:

6. return 0: igualdad
7. return negativo: si current object menor que argumento.
8. return positivo: si current object mayor que argumento.

public interface Comparable<T> {public int compareTo(T o);}

<aside> 🔹 Ejemplo completo: clase nueva con concepto de orden

9. La clase
10. import java.util.*;
11. class A implements Comparable<A>{
12. private String s;
13. public A(String s){this.s = s;}
14. public String toString(){return s;}
15. public int compareTo(A a){
16. return s.compareTo(a.s);
17. }
18. // public static ... verlo abajo
19. }
20. Usando la clase y el orden
21. public static void main(String[] args){
22. List<A> l = new ArrayList<<();
23. l.add(new A("hola"));
24. l.add(new A("adios"));
25. Collections.sort(l);
26. System.out.print(l); // adios hola
27. }

</aside>

<aside> 🔹 Consistencia compareTo vs. equals

Es muy importante pq puede ser que algunas Collection se comporten de


forma extraña si no hay consistencia.

Debe ser: x.equals(y) is true ←→ x.compareTo(y) is 0

import java.util.*;
class LegacyA implements Comparable{
private String s;
public int compareTo(Object o){
LagacyA a = (LegacyA)o;
return s.compareTo(a.s);
}
}

</aside>

</aside>

<aside> 🔵 Comparator

Comparator<A> c = new Comparator<A>() {


public int
compare(A a1, A a2) {
return
d1.i - d2.i;
}

<aside> 🔹 Ejemplo completo: clase nueva con concepto de orden

28. La clase
29. import java.util.*;
30. class A implements Comparable<A>{
31. private String s;
32. private int i;
33. public A(String s, int ){this.s = s; this.i
= i;}
34. public String toString(){return s;}
35. public int compareTo(A a){
36. return s.compareTo(a.s);
37. }
38. // public static ... verlo abajo
39. }
40. Usando la clase y el orden
41. public static void main(String[] args){
42. Comparator<A> byI = new Comparator<A>() {
43.
public int compare(A a1, A a2) {
44.
return a1.i - a2.i;
45.
}
46. }; // no olvidar el ;
47. List<A> l = new ArrayList<<();
48. l.add(new A("hola", 1));
49. l.add(new A("adios", 2));
50. Collections.sort(l);
51. System.out.print(l); // adios hola
52. Collections.sort(l, byI);
53. System.out.print(l); // hola adios
54. }
55. Otra forma de escribir el comparator
56. Comparator<A> byI = (a1, a2) -> a1.i - a2.i;
57. Comparator<A> byI = (A a1, A a2) -> a1.i - a2.i;
58. Comparator<A> byI = (a1, a2) -> {return a1.i -
a2.i;};
59. Comparator<A> byI = (A a1, A a2) -> {return a1.i -
a2.i;};
60.
61. Típica trampa de examen: nombre de método cambiado
62. Comparator<A> byI = new Comparator<A>() {
63.
public int **compareTo**(A a1, A a2) {
64.
return d1.i - d2.i;
65.
}
66. };

</aside>

</aside>

<aside> 🔵 Resumen

Comparación de Comparable y Comparator

<aside> 🔹 La forma más fácil de comparar múltiples campos


</aside>

</aside>

o Searching and Sorting

<aside> 🔵 Aplicable a sort() y binarySearch(): ambos admiten


Comparator.

Si no es Comparable no puedo ordenar

import java.util.*;
public class SortA {
static class A{int id;}
public static void main(String... args) {
List<A> lA = new ArrayList<>();
lA.add(new A());
Collections.sort(lA); // no compila
// A no comparable
}
}

Solución: usar un Comparator y pasarlo al sort.

Comparator<A> c = (a1, a2) -> r1.id - r2.id;


Collections.sort(lA, c);

</aside>
<aside> 🔵 Ejemplos

Cambiando la función de orden al binarySearch → resultado impredecible.

import java.util.*;
List<String> l = Arrays.asList("Adios", "Hola");
Comparator<String> c = Comparator.reverseOrder();
Collections.binarySearch(l, "Hola", c); // salida impredecible

Clase que no implementa comparable metida en un TreeSet → no fallo


compilación, pero lanzará Exception.

public class UseTreeSet {


static class Rabbit{ int id; }
public static void main(String[] args) {
Set<Duck> ducks = new TreeSet<>();
ducks.add(new Duck("Puddles"));
Set<Rabbit> rabbit = new TreeSet<>();
rabbit.add(new Rabbit()); // throws an exception
}
}

Se puede indicar a las colecciones que necesitan orden el uso de un


nComparator específico.

Set<Rabbit> rabbit = new TreeSet<>(new Comparator<Rabbit>() {


public int compare(Rabbit r1, Rabbit r2) {
return r1.id = r2.id;
}});
rabbit.add(new Rabbit());

</aside>

 Teoría Exceptions
 Stream
<aside> 🔵 ¿Qué es?

1. pipeline de operaciones que transforman datos


2. Se utilizan para transformar conjuntos de datos
3. Se compone de:
1. Fuente para el Stream
2. Operaciones intermedias
3. Una operación terminal

</aside>

<aside> 🔵 Operaciones

4. intermedias
1. map → trasnforma los elementos del Stream
2. filter → filtra los elementos del Stream.
3. distinct → filtro especial para dejar solo elementos únicos.
4. sorted → ordena los elementos del Stream.
5. peek → obtiene los elementos del Stream, para hacer algo con ellos
pero sin alterarlo.
6. limit → limita el número de elementos del Stream a un número
determinado.
5. terminales:
1. reduce → para acumular elementos
2. collect → para generar list, set o map
3. forEach → hacer algo con cada elemento
6. Se utilizan para transformar conjuntos de datos </aside>

<aside> 🔵 Ejemplos
</aside>

 DateTimeJava

Test.java

package localdatetime;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.Period;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.TimeZone;

/**
*
* @author javilukt
*/
public class Test {

public static void main(String[] args) {


LocalDate d1 = LocalDate.now();
System.out.println(d1);
LocalDate d2= LocalDate.of(1966,9,15);
System.out.println(d2);
LocalTime t1 = LocalTime.now();
System.out.println(t1);
LocalTime t2 = LocalTime.of(15,30,20,1300);
System.out.println(t2);
LocalDateTime dt1 = LocalDateTime.of(1966,9,15,15,30,20,1300);
System.out.println(dt1);
LocalDateTime ldt2 = LocalDateTime.of(d1, t1);
System.out.println(dt1);
ZonedDateTime zdt = ZonedDateTime.now();
System.out.println(zdt);
TimeZone z1 = TimeZone.getDefault();
System.out.println(z1);
LocalDate d3= LocalDate.of(1966,Month.SEPTEMBER,15);
System.out.println(d3);
Period p = Period.ofDays(10);
d3.minus(p);
DateTimeFormatter dtf1 = DateTimeFormatter.ISO_DATE_TIME;
DateTimeFormatter dtf2 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
DateTimeFormatter dtf3 = DateTimeFormatter.ofPattern("MM/dd/yyyy");
DateTimeFormatter dtf4 = DateTimeFormatter.ofPattern("MM/dd/yyyy
'at' hh:mm:ss");
DateTimeFormatter dtf5 =
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);

dtf1.format(dt1);

También podría gustarte