logbitup.gif (360 bytes)

 Curso JAVA 
 Unidad 6: "Utilidades"
 

logbitdn.gif (787 bytes)

  www.bit.es - Calendario de cursos - Solicitud de información

Curso Java
Curso Analista Programador entorno Java

Objetivos de la Unidad:



1.- Introducción

2.- Las clases envoltorio (Wrappers)

3.- Clase Vector

4.- Clase Hashtable

Inciso: Noción de atributos estáticos

Supongamos que queremos manejar a los objetos gráficos mediante un identificador que decidimos sea tipo String. Ello permitiría bautizar a los objetos para su uso en tiempo de ejecución, como cuando en un programa de flow-chart se le asigna un nombre a cada objeto. Una solución sería que al crear un objeto automáticamente se insertara en una Hashtable que denominaremos ht la pareja nombre-ref. al objeto tal y como se muestra en el ejemplo anterior. La pregunta es ¿dónde declarar y definir ht?. ht es un atributo de la clase Aplicacion pero resulta que no hay ninguna instancia de la clase Aplicacion. En realidad ht no es atributo de ningún objeto concreto y por lo tanto puede existir al margen de la existencia o no de objetos de una clase. En definitiva la solución es:

public class Aplicacion
{
   static Hashtable ht = new Hashtable();
   ...

El segundo punto a implementar es que el constructor adecuado inserte al objeto en ht. Como es una caracteristica que queremos para todos los ObjGraf se añadirá el constructor ObjGraf. y nombre será una nueva propiedad de todos los ObjGraf por lo que habrá que añadir por lo menos su setter:

protected ObjGraf(int xInicial, int yInicial, String nombre)
{
   setX(xInicial);
   setY(yInicial);
   setNombre(nombre);
   Aplicacion.ht.put(nombre, this);
}

Ello forzará a añadir nuevos constructores para Rectangulo y Circulo que admitan la propiedad nombre. Luego habría que modificar el constructor ObjGraf(int, int) de modo que cree un valor por defecto para la propiedad nombre como "SinNombre", se apoye en el otro constructor (el de mayor detalle) y garantize que todos los objetos ObjGraf estarán en la Hashtable:

protected ObjGraf(int xInicial, int yInicial)
{
   this(xInicial, yInicial, "SinNombre");
}

Finalmente para redondear habría que garantizar que al destruirse un objeto éste fuera eliminado automáticamente de la Hashtable. Para ello hay que sobreescribir el método finalize. Como queremos que sea un comportamiento de todos los ObjGraf sobreescribiremos el de ObjGraf que quedaría como:

protected void finalize() throws Throwable
{
  Aplicacion.ht.remove(nombre);
}

Las propiedades estáticas y los métodos estáticos tienen en común la existencia per-se independientemente de un objeto específico. Los métodos estáticos no reciben el parámetro implícito this. Un método estático corresponde al concepto clásico de función o subrutina (que tampoco recibían ningún parámetro implícito this).

5.- Culturilla:

6.- Clases Properties y Dictionary

7.- Interfaz Enumeration

8.- Clase StringTokenizer

9.- Clase Runtime

10.- Clases System, Date y Math

import java.util.*;

public class PruebaFechas
{
  public static void main(String args[]) throws Exception
  {
    Calendar calHoy = Calendar.getInstance();
    calHoy.setTime(new Date());

    // Fecha al cabo de 5 días
    cal = (Calendar)calHoy.clone();
    Date d = cal.getTime();
    long nuevoTime = d.getTime() + (5 * 86400000L); // 3600 * 24 * 1000
    d = new Date(nuevoTime);
    System.out.println(d.toString());

    // Dias de diferencia entre dos fechas
    cal.set(2000, 11, 28); // 0: Enero, ..., 11: Diciembre
    d = cal.getTime();

    long dif = d.getTime() - new Date().getTime();
    System.out.println("Dias entre fechas: " + dif / 86400000L); // 3600 * 24 * 1000

    // Otra forma de calcular la fecha al cabo de 5 días
    cal = (Calendar)calHoy.clone();
    cal.add(Calendar.DAY_OF_MONTH, 5);
    System.out.println("Dia despues de 5 dias: " + cal.getTime());

    // Y Otra forma de calcular la fecha al cabo de 5 días
    cal = (Calendar)calHoy.clone();
    cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) + 5);
    System.out.println("Dia despues de 5 dias: " + cal.getTime());

    // Otra forma de calcular la fecha al cabo de 1 semana
    Calendar cal = (Calendar)calHoy.clone();
    cal.set(Calendar.WEEK_OF_MONTH, cal.get(Calendar.WEEK_OF_MONTH) + 1);
    System.out.println("Dia despues de una semana: " + cal.getTime());

  }
}

11.- Protocolo Observer/Observable (Patrón de diseño Observer)
 
En el JDK el patrón de diseño Observer aparece en varias ocasiones. La gestión de eventos JDK 1.1 está basada en él (Observable = Componente emisor y Observer = Listeners), así como el mecanismo de actualización de datos del modelo en la separación modelo/vista de Swing. Además se incluyen unas clases genéricas para que las apliquemos en nuestros casos. Sin embargo aunque ya estaban en el JDK 1.02 no han sido utilizadas de forma genérica por Sun en el desarrollo del propio JDK.  

import java.util.*;
 

public class PruebaObservable
{
  public static void main(String[] args)
  {
    ElQueNotifica x = new ElQueNotifica();   // El Observado
    ElNotificado y = new ElNotificado();     // El Observador

    x.addObserver(y);

    x.indicarCambio();
    x.notifyObservers(" Desde main");
  }
}
 

public class ElQueNotifica extends Observable
{
  public void indicarCambio()
  {
    setChanged();
  }
}

// El observador (en este caso ElNotificado) es el que recibe noticaciones
// cada vez que hay un cambio en el observado (en este caso ElQueNotifica)
// mediante la llamada el update(). En cierto modo update() es un evento.
public class ElNotificado implements Observer
{

  public void update(Observable obj, Object arg)
  {
    System.out.println("Recibida notificación. Parámetro recibido: " + arg);
  }
}
 

12.- Resumen operativo de la unidad: Una clase de utilidades


Es recomendable disponer de una clase de propósito general con funciones de utilidades. A continuación se propone una posible clase de utilidades basada en funciones estáticas con servicios de conversión de tipos entre otros.

import java.util.*;
import java.text.*;
public class Util
{
  public Util()
  {
    Locale locale = new Locale("es", "ESP");
    Locale.setDefault(locale);
  }
  // conversiones String to ...
  public static int stringToInt (String s)
  {
    int a = 0;
    try
    {
      a = Integer.parseInt(s);
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.stringToInt()");
    }
    return a;
  }
  public static double stringToDouble (String s)
  {
    double x = 0;
    try
    {
      x = Double.valueOf(s).doubleValue();
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.stringToDouble(). Recibida: " + s);
    }
    return x;
  }
  public static Date stringToDate (String s)
  {
    Date d = null;
    try
    {
      SimpleDateFormat sd = new SimpleDateFormat();
      sd.applyPattern("dd/MM/yy");
      d = sd.parse(s);
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.stringToDate(). Recibida: " + s);
    }
    return d;
  }
  public static String stringToStringBD (String s)
  {
    String sBD = "";
    try
    {
      Date d = stringToDate (s);
      sBD = fechaToStringBD(d);
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.stringToStringBD(). Recibida: " + s);
    }
    return sBD;
  }
  public static String stringBDToString (String sBD)
  {
    String s = "";
    try
    {
      Date d = stringBDToDate (sBD);
      s = fechaToString(d);
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.stringBDToString(). Recibida: " + sBD);
    }
    return s;
  }
  public static Date stringBDToDate (String s)
  {
    Date d = null;
    try
    {
      d = (Date) java.sql.Date.valueOf(s);
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.stringBDToDate(). Recibida: " + s);
    }
    return d;
  }
  // conversiones ... to String
  public static String fechaToString(Date d)
  {
    String s = "";
    try
    {
      SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
      s = sdf.format(d);
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.fechaToString(). Recibida: " + d);
    }
    return s;
  }
  public static String fechaToStringBD(Date d)
  {
    String s = "";
    try
    {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      s = sdf.format(d);
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.fechaToStringBD(). Recibida: " + d);
    }
    return s;
  }
  public static String doubleToString(double d)
  {
    String s = "";
    try
    {
      DecimalFormat df = new DecimalFormat("#,##0.00");    // .00 => 2 decimales fijos
      s = df.format(d);                                    // .## => 2 decimales máximo
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.doubleToString(). Recibido: " + d);
    }
    return s;
  }
  // obtenciones de fechas en diveros formatos
  public static Date getFecha(int dia, int mes, int anyo)
  {
    Date d = null;
    try
    {
      Calendar c = Calendar.getInstance();
      c.set(anyo, mes-1, dia);
      d = c.getTime();
    }
    catch (Exception e)
    {
      System.out.println("Capturada en Util.getFecha(). Recibidos: dia = "
                          + dia + ", mes = " + mes + ", anyo = " + anyo);
    }
    return d;
  }

  public static int diasDeUnMes(int mes, int anyo)
  {
    GregorianCalendar gc = new GregorianCalendar();
    gc.set(anyo, (mes-1), 1);
    return gc.getActualMaximum(Calendar.DAY_OF_MONTH);
  }
  public static String getFechaString(int dia, int mes, int anyo)
  {
    return fechaToString(getFecha(dia, mes, anyo));
  }
  public static String getFechaString()
  {
    return fechaToString(new Date());
  }
  public static String nvl(String s)
  {
    return s == null ? "" : s.trim();
  }
}
 

13.- Fin de la parte sobre el lenguaje

En http://www.chimu.com/publications/JavaSmalltalkSyntax.html se expone una tabla comparativa entre Java i Smaltalk, lenguaje pionero en muchos aspectos del que Java ha incorporado diversos aspectos.
 


Unidad anterior - Unidad siguiente