miércoles, 2 de febrero de 2022

Clases Genéricas, Expresiones Regulares, Hilos(thread), BBDD(bases de datos)

Clases Genéricas

Java a tenido varios cambios en sus versiones, pero una de las cosas más útiles que añadido a sus métodos de trabajo han sido las clases genéricas, ya que han tenido un gran cambio para poder implementarlo en Java porque al momento de escribirlo, su sintaxis es totalmente nueva a otras maneras de escribir códigos causando muchos cambios en las clases.

Las clases genéricas proporcionan los medios para describir conceptos en forma independiente de varios tipos. Así se puede crear instancias de objetos con tipos específicos de la clase genérica. Esto nos permite una gran oportunidad de reutilizar códigos.
Una vez que tenemos una clase genérica, podemos utilizar una notación concisa para indicar el tipo actual a utilizarse en lugar del parámetro de tipo de la clase. En tiempo de compilación, el compilador Java asegura la seguridad de los tipos de nuestro código y utiliza las técnicas de borrado para permitir que nuestro código interactúe con la clase genérica.

En su esencia, el término genéricos significa tipos parametrizados. Los tipos parametrizados son importantes porque le permiten crear clases, interfaces y métodos en los que el tipo de datos sobre los que operan se especifica como parámetro. Una clase, interfaz o método que funciona con un tipo de parámetro se denomina genérico, como una clase genérica o método genérico.

Existen una convención en las letras a utilizar para definir los datos genéricos: 
E: Representa un elemento genérico en la documentación de las clases genéricas propias del leguaje java. 
K: Representa un elemento tipo clave dentro de un diccionario. 
V: Es el valor de un diccionario o colección. 
N: Significa que el elemento genérico puede ser cualquier tipo de número 
T: Cualquier tipo genérico. 
S, U, etc.: Cualquier otro tipo de dato.
La función primordial de las clases genéricas es permitir parametrizar las clases con cualquier tipo de dato.
A continuación un ejemplo de Clases Genéricas.
public final class generica
        Private static final generica g=new generica(); 
        Private generica() { 
            //Sentencias 
        
        Public static generica getGenerica(){ 
            Return g;
         }
 }

Expresiones Regulares

Una expresión regular define un patrón de búsqueda para cadenas de caracteres.

Una expresión regular es una secuencia especial de caracteres que ayuda a hacer coincidir o encontrar otras cadenas o conjuntos de cadenas, utilizando una sintaxis especializada contenida en un patrón. Java tiene soporte para el uso de expresiones regulares a través del paquete java.util.regex. Este tema es presentar y ayudar a los desarrolladores a comprender más con ejemplos sobre cómo se deben usar las expresiones regulares en Java.


Debemos agregar las siguientes importaciones antes de poder usar Regex:

import java.util.regex.Matcher
import java.util.regex.Pattern

Algunos ejemplos de uso de expresiones regulares pueden ser:
  • para comprobar que la fecha leída cumple el patrón dd/mm/aaaa
  • para comprobar que un NIF está formado por 8 cifras, un guión y una letra
  • para comprobar que una dirección de correo electrónico es una dirección válida.
  • para comprobar que una contraseña cumple unas determinadas condiciones.
  • para comprobar que una URL es válida.
  • para comprobar cuántas veces se repite dentro de la cadena una secuencia de caracteres determinada.

El patrón se busca en el String de izquierda a derecha. Cuando se determina que un carácter cumple con el patrón este carácter ya no vuelve a intervenir en la comprobación.


Símbolos comunes en expresiones regulares

Expresión
Descripción
.
Un punto indica cualquier carácter
^expresión
El símbolo ^ indica el principio del String. En este caso el String debe contener la expresión al principio.
expresión$
El símbolo $ indica el final del String. En este caso el String debe contener la expresión al final.
[abc]
Los corchetes representan una definición de conjunto. En este ejemplo el String debe contener las letras a ó b ó c.
[abc][12]
El String debe contener las letras a ó b ó c seguidas de 1 ó 2
[^abc]
El símbolo ^ dentro de los corchetes indica negación. En este caso el String debe contener cualquier carácter excepto a ó b ó c.
[a-z1-9]
Rango. Indica las letras minúsculas desde la a hasta la z (ambas incluidas) y los dígitos desde el 1 hasta el 9 (ambos incluidos)
A|B
El carácter | es un OR.  A ó B
AB
Concatenación. A seguida de B


Meta caracteres

Expresión
Descripción
\d
Dígito. Equivale a [0-9]
\D
No dígito. Equivale a [^0-9]
\s
Espacio en blanco. Equivale a [ \t\n\x0b\r\f]
\S
No espacio en blanco. Equivale a [^\s]
\w
Una letra mayúscula o minúscula, un dígito o el carácter _
Equivale a  [a-zA-Z0-9_]
\W
Equivale a [^\w]
\b
Límite de una palabra.

En Java debemos usar una doble barra invertida \\
Por ejemplo para utilizar  \w tendremos que escribir \\w. Si queremos indicar que la barra invertida en un carácter de la expresión regular tendremos que escribir  \\\\.

Cuantificadores

Expresión  
Descripción
{X}
Indica que lo que va justo antes de las llaves se repite X veces
{X,Y}
Indica que lo que va justo antes de las llaves se repite mínimo X veces y máximo Y veces. También podemos poner {X,} indicando que se repite un mínimo de X veces sin límite máximo.
*
Indica 0 ó más veces. Equivale a {0,}
+
Indica 1 ó más veces. Equivale a {1,}
?
Indica 0 ó 1 veces. Equivale a {0,1}

Para usar expresiones regulares en Java se usa el package java.util.regex
Clase Pattern: Un objeto de esta clase representa la expresión regular. Contiene el método compile(String regex) que recibe como parámetro la expresión regular y devuelve un objeto de la clase Pattern.
La clase Matcher: Esta clase compara el String y la expresión regular. Contienen el método matches(CharSequence input) que recibe como parámetro el String a validar y devuelve true si coincide con el patrón. El método find() indica si el String contienen el patrón.

Contiene las clases Pattern y Matcher y la excepción PatternSyntaxException.

A continuación un ejemplo de Expresiones Regulares:
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern; 
public class Ejemplo1 {
            public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            String email;
            System.out.print("Introduce email: ");
            email = sc.nextLine();
          Pattern pat = Pattern.compile("^[\\w-]+(\\.[\\w-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$
            Matcher mat = pat.matcher(email);
            if(mat.find()){
                System.out.println("Correo Válido");
            }else {
                System.out.println("Correo No Válido");
         }
    }
}

Hilos (thread)

Un thread es un único flujo de control dentro de un programa. Algunas veces es llamado contexto de ejecución porque cada thread debe tener sus propios recursos, como el program counter y el stack de ejecución, como el contexto de ejecución. Sin embargo, todo thread en un programa aún comparte muchos recursos, tales como espacio de memoria  y archivos abiertos.

Se puede crear un hilo instanciando un objeto de tipo Thread. La clase Thread encapsula un objeto que se puede ejecutar. Como se mencionó, Java define dos formas en las que puede crear un objeto ejecutable:

Los hilos se pueden crear utilizando dos mecanismos:

  1. Extender la clase Thread
  1. Implementar la interfaz Runnable

La mayoría de los ejemplos utilizarán el enfoque que implementa Runnable.

La interfaz Runnable abstrae una unidad de código ejecutable. Puede construir un hilo en cualquier objeto que implemente la interfaz Runnable. Runnable define solo un método llamado run(), la cual se declara así.

public void run()

Dentro de run(), se definirá el código que constituye el nuevo hilo. Es importante entender que run() puede llamar a otros métodos, usar otras clases y declarar variables como el hilo principal. La única diferencia es que run() establece el punto de entrada para otro hilo de ejecución concurrente dentro de su programa.

  • start(); Indica que comience un hilo y se ejecutado
  • run(): Constituye en el cuerpo del hilo en ejecución, es el único método de la interfaz Runnable 
  • stop(); Provoca que el hilo se detenga de manera inmediata
  • suspend(): Provoca que se detenga su ejecución sin destruir sistema subyacente, ni el estado del hilo en ejecución
  • resume(); Sirve para revivir un hilo suspendido
  • setPriority(int): Asigna un prioridad al hilo, donde toman normalmente las prioridades definidas en la clase Thread:
    MIN_PRIORITY = 1
    NORM_PRIORITY = 5
    MAX_PRIORITY = 10

El método sleep() también tiene una segunda forma, que le permite especificar el período en términos de milisegundos y nanosegundos si necesita ese nivel de precisión. En run(), sleep() pausa el hilo durante 400 milisegundos cada vez a través del bucle. Esto permite que el hilo se ejecute con la lentitud suficiente para que pueda verlo ejecutar.

La implementación de Runnable es una forma de crear una clase que pueda instanciar objetos hilos. Extender de Thread es la otra. En este ejemplo, verá cómo extender Thread creando un programa funcionalmente similar al programa UsoHilos que se mostró anteriormente.

Cuando una clase extiende de Thread, debe anular el método run(), que es el punto de entrada para el nuevo hilo. También debe llamar a start() para comenzar la ejecución del nuevo hilo. Es posible anular otros métodos Thread, pero no es necesario.

NOTA: Es mucho más simple crear y destruir una thread que un proceso.

A continuación un ejemplo de Hilos:

public class MainRunnable implements Runnable {
            private Cliente cliente;
            private Cajera cajera;
            private long initialTime;

            public MainRunnable (Cliente cliente, Cajera cajera, long initialTime) {
                        this.cajera = cajera;
                        this.cliente = cliente;
                        this.initialTime = initialTime;
            }
            public static void main(String[] args) {
                        Cliente cliente1 = new Cliente("Cliente 1", new int[] { 2, 2, 1, 5, 2, 3 });
                        Cliente cliente2 = new Cliente("Cliente 2", new int[] { 1, 3, 5, 1, 1 });

                        Cajera cajera1 = new Cajera("Cajera 1");
                        Cajera cajera2 = new Cajera("Cajera 2");
                         // Tiempo inicial de referencia
                        long initialTime = System.currentTimeMillis();

                        Runnable proceso1 = new MainRunnable(cliente1, cajera1, initialTime);
                        Runnable proceso2 = new MainRunnable(cliente2, cajera2, initialTime);

                        new Thread(proceso1).start();
                        new Thread(proceso2).start();
}
            @Override
            public void run() {
                        this.cajera.procesarCompra(this.cliente, this.initialTime);
            }

BBDD (bases de datos)

Una Base de Datos es una serie de tablas que contienen información ordenada en alguna estructura que facilita el acceso a esas tablas, ordenarlas y seleccionar filas de las tablas según criterios específicos. Las bases de datos generalmente tienen índices asociados a alguna de sus columnas, de forma que el acceso sea lo más rápido posible.

Las Bases de Datos son, sin lugar a dudas, las estructuras más utilizadas en ordenadores; ya que son el corazón de sistemas tan complejos como el censo de una nación, la nómina de empleados de una empresa, el sistema de facturación de una multinacional, o el medio por el que nos expiden el billete para las próximas vacaciones.

El lenguaje en que se ha escrito la consulta es SQL, actualmente soportado por casi todas las bases de datos a lo largo del mundo. Los estándares de SQL han sido varios a lo largo de los años y muchas de las bases de datos para PC soportan alguno de esos tipos. El estándar SQL-92 es el que se considera origen de todas las actualizaciones. Hay que tener en cuenta, que hay posteriores versiones de SQL, perfeccionadas y extendidas para explotar características únicas de bases de datos particulares; así que no conviene separarse del estándar básico si se pretende hacer una aplicación que pueda atacar a cualquier tipo de base de datos. Al final del capítulo, el lector puede encontrar una pequeña revisión del lenguaje SQL.

JDBC es una especificación de un conjunto de clases y métodos de operación que permiten a cualquier programa Java acceder a sistemas de bases de datos de forma homogénea. Lógicamente, al igual que ODBC, la aplicación de Java debe tener acceso a un driver JDBC adecuado. Este driver es el que implementa la funcionalidad de todas las clases de acceso a datos y proporciona la comunicación entre el API JDBC y la base de datos real.

La necesidad de JDBC, a pesar de la existencia de ODBC, viene dada porque ODBC es un interfaz escrito en lenguaje C, que al no ser un lenguaje portable, haría que las aplicaciones Java también perdiesen la portabilidad. Y además, ODBC tiene el inconveniente de que se ha de instalar manualmente en cada máquina; al contrario que los drivers JDBC, que al estar escritos en Java son automáticamente instalables, portables y seguros.

JDBC define ocho interfaces para operaciones con bases de datos, de las que se derivan las clases correspondientes. La figura siguiente, en formato OMT, con nomenclatura UML, muestra la interrelación entre estas clases según el modelo de objetos de la especificación de JDBC.


La clase que se encarga de cargar inicialmente todos los drivers JDBC disponibles es DriverManager. Una aplicación puede utilizar DriverManager para obtener un objeto de tipo conexión, Connection, con una base de datos. La conexión se especifica siguiendo una sintaxis basada en la especificación más amplia de los URL, de la forma

Por ejemplo, si se utiliza mySQL el nombre del subprotocolo será msql. En algunas ocasiones es necesario identificar aún más el protocolo. Por ejemplo, si se usa el puente JDBC-ODBC no es suficiente con jdbc:odbc, ya que pueden existir múltiples drivers ODBC, y en este caso, hay que especificar aún más, mediante jdbc:odbc:fuente de datos.

Una vez que se tiene un objeto de tipo Connection, se pueden crear sentencias, statements, ejecutables. Cada una de estas sentencias puede devolver cero o más resultados, que se devuelven como objetos de tipo ResultSet.

Y la tabla siguiente muestra la misma lista de clases e interfaces junto con una breve descripción.



Tipos de datos Java a lenguaje SQL:



No hay comentarios.:

Publicar un comentario

Clases Genéricas, Expresiones Regulares, Hilos(thread), BBDD(bases de datos)

Clases Genéricas Java a tenido varios cambios en sus versiones, pero una de las cosas más útiles que añadido a sus métodos de trabajo han s...