Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Properties propiedades;
File ficheroEntrada;
int numVidas;
EstadoCivil ec = EstadoCivil.casado;
ec = EstadoCivil.soltero;
switch(ec)
{ case
soltero:
System.out.println("Es soltero"); break;
case casado:
System.out.println("Es casado"); break;
case divorciado:
System.out.println("Es divorciado");
Java
break; Lenguaje Java 13
Otras características
• Imports estáticos
import static java.lang.Math;
…
double raiz = sqrt(1252.2);
• Argumentos variables
public void miFunc(String param, int... args) {
for(int i: args) { … }
}
• Anotaciones (metainformación)
• P.ej., @deprecated
Java Lenguaje Java 14
Convenciones generales
• Indentar el código uniformemente
• Limitar la anchura de las líneas de código (para impresión)
• Utilizar líneas en blanco para separar bloques de código
• Utilizar espacios para separar ciertos elementos en una
línea
• Documentación:
• Utilizar /*... */ para esconder código sin
borrarlo
• Utilizar // ... para detalles de la implementación
• Utilizar javadoc para describir la interfaz de
programación
Java Lenguaje Java 15
Modificadores de acceso
• Las clases y sus elementos admiten unos
modificadores de acceso:
• privado: el elemento es accesible sólo desde la
clase en que se encuentra
• protegido: el elemento es accesible desde la propia
clase, desde sus subclases, y desde clases del
mismo paquete
• público: el elemento es accesible desde cualquier
clase
• paquete: el elemento es accesible desde la propia
clase, o desde clases del mismo paquete.
Java Lenguaje Java 16
Modificadores de acceso
• private se utiliza para elementos PRIVADOS
• protected se utiliza para elementos
PROTEGIDOS
• public se utiliza para elementos
PUBLICOS
• Nopublic
se especifica
class MiClasenada
{ para
elementos PAQUETE
private int n;
protected void
metodo() { ... }
• Todo fichero Java debe tener una y solo una
clase pública, llamada igual que el fichero (más
otras clases internas que pueda tener)
Java Lenguaje Java 17
Modificadores de acceso
default
sí sí sí
private
sí
// NO if
(cadena.equals(“Hola”)) ... // SI
Java Lenguaje Java 30
Object: representar en cadenas
• Muchas veces queremos imprimir un objeto como
cadena. Por ejemplo, si es un punto geométrico, sacar su
coordenada X, una coma, y su coordenada Y
• La clase Object proporciona un método toString para
definir cómo queremos que se imprima un objeto.
Podremos redefinirlo a nuestro gusto
public class Punto2D {
...
public String toString()
{
return “(“ + x + ”,” + y + ”)”;
}
}
...
Punto2D p = ...;
System.out.println(p); // Imprimirá (x, y) del punto
• Ejemplo: proyección de un
return descripcion;
}
public void setDescripcion(String descripcion) {
punto3D en un punto2D.
this.descripcion = descripcion;
}
public int getX() {
return x;
• usamos copyProperties:
{ private int x; private
int y; private int z;
private String
descripcion;
/* ...y los getters y
setters para los
cuatro campos */
BeanUtils.copyProperties(punto2D, punto3D); }
Java Colecciones -
40
Introducción
• Java proporciona un amplio conjunto de clases
útiles para desarrollar aplicaciones
Java Colecciones -
42
Listas de elementos
• La interfaz List hereda de Collection
• Operaciones propias de una colección tipo lista
• Los elementos tienen un orden (posición en la lista)
• Así, tendremos otros nuevos métodos, además
de los de Collection:
• void add(int posicion, Object o)
• Object get(int indice)
• int indexOf(Object o)
• Object remove(int indice)
• Object set(int indice,
Object o)
Java Colecciones -
43
Tipos de listas
• ArrayList: implementa una lista de elementos mediante un array de
tamaño variable
• NO sincronizado
• Vector: existe desde las primeras versiones de Java, después se
acomodó al marco de colecciones implementando la interfaz List.
• Similar a ArrayList, pero SINCRONIZADO. Tiene métodos
anteriores a la interfaz List:
• void addElement(Object o) / boolean removeElement(Object
o)
• void insertElementAt(Object o, int posicion)
• void removeElementAt(Object o, int posicion)
• Object elementAt(int posicion)
• void setElementAt(Object o, int posicion)
• • int size()
LinkedList: lista doblemente enlazada. Útil para simular pilas o
colas
• void addFirst(Object o) / void addLast(Object o)
• Object getFirst() / Object getLast()
• Object removeFirst() / Object removeLast()
Java Colecciones -
44
Conjuntos
• Grupos de elementos donde no hay repetidos
• Consideramos dos objetos de una clase iguales
si su método equals los da como iguales
• o1.equals(o2) es true
• Los conjuntos se definen en la interfaz Set, que,
como List, también hereda de Collection
• El método add definido en Collection
devolvía un booleano, que en este caso
permitirá saber si se insertó el elemento en el
conjunto, o no (porque ya existía)
Java Colecciones -
45
Tipos de conjuntos
• HashSet: los objetos del conjunto se almacenan en una
tabla hash.
• El coste de inserción, borrado y modificación suele ser
constante
• La iteración es más costosa, y el orden puede diferir
del orden de inserción
• LinkedHashSet: como la anterior, pero la tabla hash
tiene los elementos enlazados, lo que facilita la
• iteración
TreeSet: guarda
• El coste de los elementos
las operaciones en un árbol
es logarítmico
Java Colecciones -
46
Mapas
• No forman parte del marco de colecciones
• Se definen en la interfaz Map, y sirven para
relacionar un conjunto de claves (keys) con sus
respectivos valores
• Tanto la clave como el valor pueden ser cualquier
objeto
• Object get(Object clave)
• Object put(Object clave, Object valor)
• Object remove(Object clave)
• Set keySet()
• int size()
Java Colecciones -
47
Tipos de mapas
• HashMap: Utiliza una tabla hash para almacenar los pares
clave=valor.
• Las operaciones básicas (get y put) se harán en
tiempo constante si la dispersión es adecuada
• La iteración es más costosa, y el orden puede diferir del orden de
inserción
• Hashtable: como la anterior, pero SINCRONIZADA.
Como Vector, está desde las primeras versiones de Java
• Enumeration keys()
• TreeMap: utiliza un árbol para implementar el mapa
• El coste de las operaciones es logarítmico
• Los elementos están ordenados ascendentemente por clave
Java Colecciones - 48
Genéricos
• Colecciones de tipos concretos de datos
• A partir de JDK 1.5
• Aseguran que se utiliza el tipo de datos
correcto
ArrayList<String> a = new
ArrayList<String>();
a.add("Hola");
String s = a.get(0);
• Podemos utilizar genéricos en nuestras propias
clases
Java Colecciones - 49
Enumeraciones e iteradores
Java Colecciones - 50
Enumeraciones
Java Colecciones - 51
Enumeraciones
• Con lo anterior, un bucle completo típico para
recorrer una colección utilizando su enumeración
de elementos sería:
// Obtener la enumeracion
Enumeration enum = coleccion.elements();
while (enum.hasMoreElements())
{
Object item = enum.nextElement();
...// Convertir item al objeto
adecuado y
// hacer con el lo que convenga
}
Java Colecciones - 52
Iteradores
• La interfaz Iterator permite iterar
secuencialmente sobre los elementos de una
colección
• Para recorrer secuencialmente los elementos de la
colección
Object itemutilizaremos su método next:
= iter.next();
Java Colecciones - 53
Iteradores
• Con lo anterior, un bucle completo típico para
recorrer una colección utilizando su iterador
sería:
// Obtener el iterador
Iterator iter = coleccion.iterator();
while (iter.hasNext())
{
Object item = iter.next();
...// Convertir item al objeto
adecuado y
// hacer con el lo que convenga, por ejemplo
iter.remove();
}
Java Colecciones - 54
Bucles sin iteradores
• Nueva versión del for en JDK 1.5
• Permite recorrer tanto arrays como colecciones
• Previene salirse del rango de forma segura
Java Colecciones - 55
Polimorfismo e interfaces
• Hacer referencia siempre mediante la interfaz
• Permite cambiar la implementación sin afectar al
resto del programa
Java Colecciones - 57
Comparación de objetos
Los objetos deben ser correctamente
comparables para ser compatibles con las
estructuras de datos y algoritmos.
Comparación de igualdad: equals( )
Comparación de mayor o menor: clase
Comparator o interfaz Comparable
Java Colecciones - 58
Sobrecarga de Equals
Object.equals(Object o)
Java Colecciones - 59
Evitar la sobrecarga de Equals si:
Cada instancia es intrínsecamente única.
Por ejemplo, instancias de hilos, que
representan entidades activas, y no tan sólo
un conjunto de valores.
Cuando no es necesaria una comparación
lógica. Por ejemplo, dos números aleatorios,
donde la igualdad puede ocurrir pero su
comprobación no es necesaria.
Una superclase ya sobrecarga equals, y el
comportamiento de éste es apropiado para la
clase actual.
Java Colecciones - 60
Propiedades que debe cumplir
Java Colecciones - 63
Comparador externo: Comparator
Puede extenderse o bien desde una clase
externa, o bien desde la propia clase cuyos
objetos deben ser comparados
public class ComparaPersonaPorNombre implements
Comparator<Persona>{
public int compare(Persona p1, Persona p2) {
return p1.apellido.compareToIgnoreCase(p2.apellido);
}
}
...
List personas = new ArrayList<Persona>(); personas.add(p1);
personas.add(p2); personas.add(p3); //...
Collections.sort(personas); //Comparable.compareTo
Collections.sort(personas, new ComparaPersonaPorNombre());
//Comparator.compare
Java Colecciones - 64
Ejemplo: Wrappers de colecciones
• Objetos que envuelven la instancia de una
colección existente
• Implementa la misma interfaz (p.ej List)
• No conocemos la clase concreta del wrapper
• Cambia el comportamiento de algunos
métodos
• Sincronizar acceso a la colección
List Collections.synchronizedList(List l)
List Collections.unmodifiableList(List l)
Java Colecciones - 65
Wrappers
• Los tipos simples (int, char, float, double,
etc) no pueden incluirse directamente en
colecciones, ya que éstas esperan subtipos de
Object en sus métodos
• Para poderlos incluir, se tienen unas clases
auxiliares, llamadas wrappers, para cada tipo
básico, que lo convierten en objeto complejo
• Estas clases son, respectivamente, Integer,
Character, Float, Double, etc.
• Encapsulan al tipo simple y ofrecen métodos
útiles para poder trabajar con ellos
Java © 2012-2013 Depto. Ciencia de la Computación e IA Colecciones - 66
Wrappers
• Si quisiéramos incluir un entero en un
ArrayList, lo podríamos hacer así:
int a;
ArrayList al = new ArrayList();
al.add(new Integer(a));
Integer n = 10;
int num = n;
• Traza
e.printStackTrace();
try {
...
} catch(IOException e) {
throw new MiExcepcion("Mensaje de error", e);
Errores en cascada
fo ( int i = 0; i < 4; i++ ){}
Ejemplo: Prueba.java:24: '.class' expected
fo ( int i = 0; i < 4; i++ )
^
Prueba.java:24: ')' expected
fo
( int i = 0; i < 4;
i++ )
^
Prueba.java:24: not a statement
f
o ( int i = 0; i < 4;
i++ )
^
Pueba.java:24: ';'
expected
found
f
o ( int i = 0; i <
4; i++ )
^
Prueba.java:24: unexpected type
required: value
:
class
f
o ( int i = 0; i < 4; i++ )
Warnings
Ayudan a mejorar el estilo y la corrección
del código
Eclipse:
permite
aumentar
niveles de
warning
Herramientas de análisis
Herramientas (externas) de análisis de código
fuente
Detecta código
duplicado,
código inalcanzable,
código subóptimo,
expresiones
complicadas,
y otras posibles
fuentes de bugs
Plugin para Eclipse
Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
public V getValue() {
Uso }
return value;
Métodos genéricos
También los métodos se pueden
parametrizar con tipos
genéricos
public static <T> Entry<T,T> twice(T value) {
return new SimpleImmutableEntry<T,T>(value, value);
}
// O bien
public T getSomeObject() {
return someObject;
}
}
Borrado de tipos
porque durante la compilación, tras
comprobar que los tipos están bien, éstos
se eliminan, el siguiente código pasa a ser:
try { try {
//Código que lanza o bien //Código que lanza o bien
//MiExcepcion<String>, o bien //MiExcepcion<String>, o bien
//MiExcepcion<Integer> //MiExcepcion<Integer>
} }
catch(MiExcepcion<String> ex) { catch(MiExcepcion ex) {
// A // A
} }
catch(MiExcepcion<Integer> ex) { catch(MiExcepcion ex) {
// B // B
} }
Lenguaje Java Avanzado
• Flujos de procesamiento
Realizan algún procesamiento con los datos
Impresión: PrintWriter, PrintStream
Conversores de datos: DataOutputStream,
DataInputStream
Bufferes: BufferedReader
Acceso a los flujos
• Todos los flujos tienen una serie de métodos básicos
Flujos Métodos
InputStream, Reader read, reset, close
OutputStream, Writer write, flush, close
Flujos Métodos
BufferedReader readLine
DataOutputStream writeInt, writeUTF,...
PrintStream, print, println
PrintWriter
Objetos de la E/S estándar
• En Java también podemos acceder a la entrada, salida
y salida de error estándar
• Accedemos a esta E/S mediante flujos
• Estos flujos se encuentran como propiedades estáticas
de la clase System
• En la salida de error
System.err.println(“Error”);
Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
Flujos de ficheros
• Canales de datos para acceder a ficheros
Entrada Salida
FileReader FileWriter
Caracteres
FileInputStream FileOutputStream
Binarios
• Se puede acceder a bajo nivel directamente de la misma
forma que para cualquier flujo
• Se compone de
protocolo://servidor[:puerto]/recurso
• P.ej. http://www.ua.es/es/index.html
Se conecta al servidor www.ua.es
A través del puerto por defecto (puerto 80)
Utilizando protocolo HTTP para
comunicarse Solicita el recurso
/es/index.html
URLs en Java
• Se encapsulan en la clase URL
URL url = new URL("http://www.ua.es/es/index.html");
ByteArrayOutputStream
baos = new
ByteArrayOutputStream()
;
dos.close();
baos.close();
Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
Descodificación
• Para descodificar estos datos del flujo
realizaremos el proceso inverso
• Utilizamos un flujo DataInputStream
dis.close();
bais.close();
Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
Entrada/Salida de objetos
• Si queremos enviar un objeto a través de un
flujo deberemos convertirlo a una secuencia de
bytes
• Con los
que
escribir o
leer
Lenguaje Java
Sesión 5: Hilos
Índice
• Creación de hilos y ciclo de vida
• Sincronización de hilos
• Bloques vigilados
• Interbloqueos
• Interfaz Lock
• Variables atómicas y colecciones
• Ejecutores y pools
Hilos
Cada hilo es un flujo de ejecución
independiente
Tiene su propio contador de
programa
Instanciar el hilo
Thread t = new Thread(new MiHilo());
t.start();
Implementar Runnable
public class MiHilo implements Runnable { public
Implementar Runnable
void run() {
// Codigo de la tarea a ejecutar en el hilo
}
}
Instanciar el hilo
Thread t = new Thread(new MiHilo());
t.start();
Ciclo de vida de los hilos
for (int i = 0;
i < importantInfo.length; i+
+) {
drop.put(importantInfo[i]);
try {
Thread.sleep(random.nextInt(
5000));
} catch (InterruptedException e)
{}
}
drop.put("DONE");
}
}
Consumidor import java.util.Random;
public class Producer implements Runnable {
private Drop drop;
for (int i = 0;
i < importantInfo.length; i+
+) {
drop.put(importantInfo[i]);
try {
Thread.sleep(random.nextInt(
5000));
} catch (InterruptedException e)
{}
}
drop.put("DONE");
}
}
// ...
public synchronized void put(String message) {
Recurso // Wait until message has
// been retrieved.
while (!empty) {
public class Drop {
try {
// Message sent
wait();
from producer
// to consumer. } catch
private String (InterruptedException
message; e) {}
// True if }
consumer should // Toggle status.
wait empty = false;
// for producer // Store message.
to send
public message,
synchronized String take() { this.message =
// false
// Wait if until message is message;
producer
// available.
should
// Notify
waitwhile
for (empty) {
} consumer that
// consumertry { to
retrieve message.wait(); status
private boolean empty
} catch // has changed.
= true; (InterruptedException notifyAll();
e) {} }
} //Main class:
// Toggle status.
public class ProducerConsumerExample {
empty = true;
public static void main(String[] args) { Drop
// Notify
drop = new Drop();
producer that
(new Thread(new Producer(drop))).start(); (new
// status has changed.
Thread(new Consumer(drop))).start();
notifyAll();
}
return message;
}
}
// ...
Interbloqueos
Deadlock: hilo A queda a la espera de que B
lo desbloquee, a la vez que B queda a la
espera de que A lo desbloquee: se
interbloquean sin usar CPU
Livelock: hilo A realiza acción que causa que
B realice otra acción que a su vez vuelve a
causar la acción de A: se interbloquean
ocupando la CPU
Stravation (inanición): otros hilos
“hambrientos” ocupan el recurso (o CPU) que
nuestro hilo necesita para seguir
funcionando
Mecanismos de alto nivel
Implementaciones que proporciona Java para
facilitar la programación con concurrencia
– Interfaz Lock
– Colecciones concurrentes
– Variables atómicas
– Ejecutores y pools
– Otros muchos en el paquete java.util.concurrent
La interfaz Lock
En lugar de synchronized:
synchronized(this){
// acceder al recurso
}
Adquirir un objeto Lock y después liberarlo
Lock l = ...;
l.lock();
try {
// acceder al recurso protegido por l
} finally {
l.unlock();
}
La interfaz Lock
Añade algunos métodos más versátiles
– tryLock( ) : rechaza darnos el lock si éste no
está disponible en el instante o bien tras un
tiempo de espera especificado. Permite evitar
deadlocks.
– lockInterruptibly( ) : rechaza darnos el lock si
otro hilo envía una interrupción antes de que
el lock haya sido adquirido
– Da soporte a un mecanismo de wait/notify a
través de objetos Condition que dejarían el hilo
a la espera de que se cumpla la condición
class BufferLimitado {
final Lock lock = new ReentrantLock();
int poolSize = 2;
int maxPoolSize = 2; //Encolar otra tarea más que declaramos aquí mismo:
long keepAliveTime = 10; threadPool.execute( new Runnable() {
public void run() {
final ArrayBlockingQueue<Runnable> queue = for (int i = 0; i < 10; i++) {
new ArrayBlockingQueue<Runnable>(5); try {
System.out.println("i = " + i);
ThreadPoolExecutor threadPool = Thread.sleep(1000);
new ThreadPoolExecutor(poolSize, } catch (InterruptedException ie){
maxPoolSize, keepAliveTime,
TimeUnit.SECONDS, queue); }
}
Runnable myTasks[3] = ....; }
// y le asignamos tareas });
//Ejecuta las tareas que queden pero ya no acepta nuevas:
threadPool.shutdown();
Sobrecarga de ThreadPoolExecutor
class PausableThreadPoolExecutor //Método nuevo:
extends ThreadPoolExecutor { public void pause()
{ pauseLock.lock()
;
private boolean isPaused; //Sección
private ReentrantLock pauseLock = new ReentrantLock(); sincronizada
private Condition unpaused = pauseLock.newCondition(); try {
isPaused = true;
//Sobrecargamos el método: } finally
protected void beforeExecute(Thread t, Runnable r) { { pauseLock.unlock
super.beforeExecute(t, r); ();
pauseLock.lock(); //Sección sincronizada }
//Método nuevo:
try { }
public void resume()
while (isPaused) unpaused.await(); { pauseLock.lock();
//Bloquearlo //Sección sincronizada
} catch (InterruptedException ie) try {
{ t.interrupt(); isPaused = false;
} finally unpaused.signalAll();
{ pauseLock.unlock //Desbloquea hilos
(); bloqueados
} } finally
} { pauseLock.unlock
();
} }
//Nota: para pausar cada hilo el programador debe }
//implementar la lógica necesaria
Lenguaje Java
FIN