lunes, 30 de junio de 2014

La clase ArrayList.





Hay veces que estamos programando, y estamos usando arreglos con almacenamiento estático (un arreglo es un grupo de variables que contienen valores, todas de un mismo tipo) , el problema con ellos es precisamente ese, que su almacenamiento es estático,  ¿Qué quiere decir esto?, bueno que una vez que los declaramos, antes de usarlo, debemos definir cuál va a ser su tamaño, y este no podrá cambiar cuando el programa este corriendo, esto es un problema frecuente en  programación, y entonces me trae a la mente varias preguntas.

v  ¿Qué pasa si no sé cuál va a ser el tamaño del arreglo que quiero?
v  Tal vez si sepa el tamaño pero, ¿si necesito que crezca durante la ejecución del programa?
v  ¿Habrá implementaciones en Java que resuelvan este problema?

Bueno con un poco de suerte y podemos resolver todas estas cuestiones con un sola publicación así que manos a la obra, a continuación le presentare una clase interesante llamada ArrayList, esta supone una manera un poco distinta de trabajar a comparación de los arreglos normales, sobre todo porque este tipo de almacenamiento es dinámico, a medias, puesto que si no existieran y tuvieramos un arreglo normal en donde ya hemos ocupado toda su capacidad, lo que deberiamos hacer es crear otro arreglo con el doble de capacidad para poder copiar todo al arreglo nuevo y tener asi mas capacidad,y pues la clase ArrayList nos ahorra todo ese trabajo.

En publicaciones posteriores hablaremos de la clase LinkedList , la cual implementa una lista ligada y aunque su finalidad es la misma sus propiedades son un poco distintas.


¿Cómo la importamos?

import java.util.ArrayList;

ArrayList es una clase muy interesante de java, puesto que si uno se pone a pensar, nos ahorra mucho tiempo en cuestiones de implementación, es decir, un arrayList es un arreglo pero tiene la ventaja de que su almacenamiento es dinámico, y esto significa que su tamaño puede crecer o decrecer en tiempo de ejecución, algo que con un arreglo normal no se puede hacer.

Bueno todo esto está muy bien, pero lo que queremos es el código para aprender a usar un ArrayList , está bien comencemos con las declaraciones, ¿Cómo es que declaramos una ArraList?, debemos instanciar la clase ArrayList de la siguiente manera.


        ArrayList <String> cadena=new ArrayList();
       ArrayList <Integer> entero=new ArrayList();
       ArrayList <Double> flotante =new ArrayList();

**IMPORTANTE:: ArrayList No acepta como parámetro , tipos de datos abstractos(char,int,double,float,byte,short,long), en vez de eso debemos utilizar las clases adaptadas e estos tipos de datos (Integer para int ,String para char y String,Double para double,etc.) estas se comportan igual y tienen la ventaja de tener métodos de implementación que nos pueden servir, pero eso es tema de otra entrada.
Ademas esta es otra ventaja de arrayList, PODEMOS HACER ARRAYS DE CUALQUIER OBJETO QUE EXISTA EN JAVA.

En el ejemplo de arriba hemos declarado tres ArrayList de distintos tipos, ahora veamos como agregar elementos a ellos.

Para agregar elementos a ellos debemos usar el método add(); en cual le pasaremos como parámetro el elemento que queramos meter al ArrayList, es importante mencionar que este método esta sobrecargado, ¿Qué quiere decir esto?, bueno que dependiendo de lo que le pasemos como parámetro es como actuara y es que hay dos formas de este método, si solo le pasamos como parámetro el elemento que queremos agregar , lo agregara el final de la lista , pero si le pasamos como parámetros primero un número, y después separado por una coma el elemento a agregar , el método agregara el elemento en el índice del numero pasado.
 Forma 1
      cadena.add("HOLA");
       entero.add(1);
       flotante.add(2.3);
Para esta forma, el método agregara estos elementos en la posición final del ArrayList

Forma 2
       cadena.add(1,"HOLA");
       entero.add(1,1);
       flotante.add(1,2.3);

Para esta otra forma el método agregara el elemento que se la pasó en la posición del índice que le pasamos en el primer número que le dimos al elemento. En el caso de cadena “HOLA” será agregado en la posición 1, en el caso de entero (1) será agregado en la posición 1, y en el caso de flotante (2.3) será agregado en la posición 1.


**IMPORTANTE
Si usamos la segunda forma del add, si en la posición en la que le estamos indicando que insertaremos un elemento, ya existía algo, lo que hara es mover todos los elementos hacia adelante para que el nuevo pueda entrar, es decir no borra ningún elemento , solo los recorre, si lo que queremos es que borre el elemento que ya estaba , lo que debemos hacer es  usar el metodo set() explicado mas adelante.


Bueno bueno ya sabemos agregar elementos al ArrayList, ¿pero que hay si queremos obtener el valor de un elemento en el ArrayList?, si este es el caso entonces debemos usar otro método llamado get();,a este método basta con pasarle como parámetro el índice del elemento que queremos obtener , y el se encargara de obtenerlo y dárnoslo.
Por ejemplo si quisiéramos mostrar en consola los elementos que agregamos arriba, bastaría con hacer lo siguiente:

        System.out.println(cadena.get(1));
        System.out.println(entero.get(1));
        System.out.println(flotante.get(1));

Y el resultado obtenido seria el siguiente :
Resultado de imprimir la posición número 1 del Array





Bien estos dos métodos son básicos para empezar a usar los ArrayList, pero metámonos un poco más en los beneficios que nos da esta clase.
Hay más métodos que nos facilitan las cosas a la hora de programar, los siguientes son algunos de ellos.
isEmpty();
Devuelve true (verdadero) si es que el ArrayList que lo está llamando esta vacío.
contains(Object o);
Devuelve verdadero, si y solo si el elemento que se le pasa como parámetro se encuentra en el ArrayList, caso contrario devuelve falso.
indexOf(Object o);
Devuelve el índice de la primera ocurrencia del elemento pasado como parámetro, caso contrario devolverá un -1
lastIndexOf(Object o);
Devuelve el ultimo índice de las ocurrencias de elemento pasado como parámetro, caso contrario devolverá -1
remove(Object o);
remove (int index);
Este método actúa de acuerdo a lo que le pasemos como parámetro, es decir si le pasamos un objeto de la clase que es el ArrayList, lo buscara en el ArrayList y eliminara la PRIMERA ocurrencia de este y devolverá true, si no hay elemento devuelve false que significa que la lista no tenía ningún elemento como el que se le paso y por ende la lista no fue cambiada.

Sin embargo si le pasamos como parámetro un número, este lo tomara como un índice y eliminara lo que se encuentra en esa posición.
set(int index, Object o);
Define en el índice pasado como parámetro el objeto que también se pasó, es decir si le pasamos 1 , “hola”; pondrá en la posición 1 del ArrayList el texto hola, sin importar lo que haya ahí.
size();
Devuelve un entero con el tamaño del ArrayList.


Bien hasta ahora hemos visto muchos métodos que nos sirven para la clase ArrayList a continuación veremos un ejemplo, poniendo a prueba todo lo que hemos dicho hasta ahora.

   import java.util.ArrayList;

/**
 *
 * @author Luis
 */
public class ProbandoArrays {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        /**
         * Para esta prueba crearemos tres ArrayList
         */
        ArrayList cadena = new ArrayList();
        ArrayList entero = new ArrayList();
        ArrayList flotante = new ArrayList();
        /**
         * Una vez agregados llenaremos con diez posiciones cada uno el array de
         * String lo llenaremos con la forma HOLA X donde X es un número del 1
         * al 10 el array de enteros lo llenaremos con números del 1 al 10 y el
         * de flotantes lo llenaremos con números del 1.3 al 10.3 es importante
         * mencionar que el metodo add() agregará siempre al final de la lista
         */
        for (int i = 0; i <= 10; i++) {
            cadena.add("HOLA " + i);
            entero.add(i);
            flotante.add(i + 0.3);
        }

        //  Si quisieramos impimir el array completo haríamos lo siguiente 
        System.out.println(cadena);
        System.out.println(entero);
        System.out.println(flotante);

        // En cambio si ontener un elemento específico para usarlo o impimirlo
        //usaremos el método get();, imaginemos que queremos imprimir el elemento que esta
        // en la posición  4 de cada array, entonces debemos hacer lo siguiente
        System.out.println(cadena.get(4));
        System.out.println(entero.get(4));
        System.out.println(flotante.get(4));

        // algo importante es recordar que en los ArrayList los elmentos se empiezan
        //a contar desde la posicion 0.
        /**
         * ahora imagina que quieres agregar un elemento en una posicion
         * especifica del Array, bueno para eso existen dos métodos , y usaremos
         * el que nos convenga según el caso, si lo que queremos es insertar el
         * elemento en una posicion y queremos que los demás elementos se
         * recorran entonces usaremos el metodo add(indice,elemnto);, pero si lo
         * que queremos es agregar en una posicion el elmento y borrar lo que ya
         * había es esa posicion debemos usar el metodo set(indice,elemento);
         */
        System.out.println("\nAgregando un elemento en la posicion 5 y recorriendo todos los de más con el metodo add();");
        cadena.add(5, "Elemento agregado");
        entero.add(5, 9999);
        flotante.add(5, 333.44);
        System.out.println("Podemos ver que los elementos se recorrieron para dejar entrar al nuevo elemento\n");
        System.out.println(cadena);
        System.out.println(entero);
        System.out.println(flotante);

        System.out.println("\n Quitando el elemento de la posicion 2 con el método set();");
        cadena.set(2, "Eliminado y remplazado");
        entero.set(2, 000000000);
        flotante.set(2, .33333333333);
        System.out.println("El elemento fue remplazado, es decir eliminado, y cambiado por otro nuevo sin que los de más se recorrier\n");
        System.out.println(cadena);
        System.out.println(entero);
        System.out.println(flotante);

        /**
         * Que tal si queremos saber si existe algún elemento en la lista, con
         * una arreglo normal tendríamos que hacer un for e ir buscando el
         * elemento, ArrayList nos ahorra esto, o tan lo menos lo hace invisible
         * para nosotros y nos presenta el método contains(); , tenemos que
         * pasarle como parámetro el elemento a buscar , y nos devolvera true si
         * es que se encuentra y -1 o false si es que no esta el elemento
         */
        System.out.println("\n\nBucando elementos en el array con el metodo contains();");

        System.out.println("Buscamos en el array cadena la palabra HOLA 0 entonces nos devuleve: " + cadena.contains("HOLA 0"));
        System.out.println("Buscamos en el array cadena la palabra HOLA entonces nos devuleve: " + cadena.contains("HOLA"));

        System.out.println("\nBuscamos en el array entero el número 0 entonces nos devuleve: " + entero.contains(0));
        System.out.println("Buscamos en el array entero el número 10000 entonces nos devuleve: " + entero.contains(1000));

        System.out.println("\nBuscamos en el array flotante el número 1.3 entonces nos devuleve: " + flotante.contains(1.3));
        System.out.println("Buscamos en el array flotante el número 39.9 entonces nos devuleve: " + flotante.contains(39.9));

        /**
         * y que tal si quisieramos saber la posición en la que se encuentra un
         * elemento en el arreglo, el método indexOf(); y el método
         * lastIndexOf(); nos ayudan con eso, el primero nos devuleve el indice
         * de la primera ocurrencia de la busqueda, y el otro el indice de la
         * ultima ocurrencia, si el elemento no se encuentra en la lista ,
         * simplemente devuelve -1
         */
        System.out.println("\n obteniendo indices de busquedas con los métodos indexOf(); y lastIndexOf();");
        System.out.println("\n buscando el indice de la palabra HOLA 8 en el Array cadena : " + cadena.indexOf("HOLA 8"));
        //agregaremos otro 8 al array entero para que haya dos elementos iguales y porblemos el método lastIndexOf();
        entero.add(8);
        System.out.println("\n buscando la ultima ocurrencia de 8 en el Array entero : " + entero.lastIndexOf(8));
        System.out.println("\n buscando un elemento que no existe en el Array flotante : " + flotante.indexOf(3333.3333));
        /**
         * Por último imaginemos que queremos eliminar un elemento de la lista y
         * que los demas elementos se recorriran para no dejar ese espacio
         * vacío, bueno en este caso debemos usar el metodo remove(); y debemos
         * pasarle como parámetro el elemento a eleminar o la posición del
         * elmento, el método se encargara de eliminarlo y de recorrer los demas
         * elementos, para que no haya espacios vacíos
         */
        System.out.println("\n\n Eliminando elementos de  los ArrayList");

        System.out.println("\nEliminando de el ArrayList cadena por elemento   HOLA 0 ");
        cadena.remove("HOLA 0");
        System.out.println("\nEliminando de el ArrayList entero el elemento en la posicion 4");
        entero.remove(4);
        System.out.println("\nEliminando del ArrayList flotante el elemento 6.3");
        flotante.remove(6.3);

        System.out.println("Imprimiendo los Arrays Modificados: ");

        System.out.println(cadena);
        System.out.println(entero);
        System.out.println(flotante);

    }

}
Esto es todo por esta entrada, más adelante se publicarán entradas de ArrayList más avanzadas en las que pondremos a prueba las funcionalidades de esta maravillosa clase de la API de Java.

sábado, 28 de junio de 2014

Números Grandes en Java

Manejo básico de BigInteger.

En el API de Java,  paquete java.math se encuentra la clase BigInteger.
import java.math.BigInteger;

La clase BigInteger nos permite procesar números con N cantidad de dígitos, donde N es un número considerablemente alto.

*BigInteger solo permite valores del tipo entero.
**Para números decimales con una cantidad grande de dígitos se utiliza BigDecimal.*Se explicara en otra entrada al blog.

Importancia del Biginteger.

La importancia de BigInteger radica en la cantidad de dígitos en un número, teniendo en cuenta que:

Nombre        Rango Aproximado

byte              -128 a 127
short             -32768 a 32767
int                  -2147483648 a 2147483647
long               -9223372036854775808 a 9223372036854775807

Donde la mayor cantidad de dígitos que se puede tener en números enteros es en el uso de un long con la cantidad de 19 dígitos.

Uso del Biginteger.

Para hacer uso de un BigInteger se crea de las siguientes maneras:

·         Forma 1:

Uso de las variables estáticas en BigInteger, la clase tiene 3 variables estáticas que nos facilitan la inicialización del objeto.

Crea el BigInteger con valor de inicio:

1   [ uno ] - BigInteger.ONE
10 [ diez ] - BigInteger.TEN;
0   [ cero ] - BigInteger.ZERO;

BigInteger forma1 = BigInteger.ZERO;

·         Forma 2:

En la creación del objeto BigInteger se manda como parámetro el número como cadena de caracteres o datos de tipo numérico convertido a String, o simplemente leer desde teclado usando Scanner.

Parámetro pasado como cadena:
String numero = “123456789101112”;
BigInteger forma2 = new BigInteger(numero);

Parámetro pasado como long:
long num = 9223372036854775807L;
BigInteger forma2 = new BigInteger(num+"");

Parámetro leído desde teclado usando Scanner:
            Scanner s = new Scanner (System.in);
            BigInteger num = s.nextBigInteger();

Operaciones básicas con BigInter:

Suma – add() –

        Se usa el método .add() para sumar 2  números del tipo BigInteger.

        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");
       
        BigInteger resultado = uno.add(dos);
        System.out.println("Resultado de suma de 2 objetos BigInteger : "+resultado);

Resta – subtract() –

        Se usa el método .subtract() para restar 2  números del tipo BigInteger.

        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.subtract(dos);
        System.out.println("Resultado de resta de 2 objetos BigInteger : " + resultado);

Multiplicación – multiply () –

        Se usa el método .multiply () para multiplicar 2  números del tipo BigInteger.

        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.multiply(dos);
   System.out.println("Resultado de multiplicación de 2 objetos BigInteger : " + resultado);

División – divide () –

        Se usa el método .divide () para dividir 2  números del tipo BigInteger.

        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.divide(dos);
       System.out.println("Resultado de división de 2 objetos BigInteger : " + resultado);

Residuo Modulo – mod () –

        Se usa el método .mod() para obtener el residuo de 2  números del tipo BigInteger.

        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("4");

        BigInteger resultado = uno.mod(dos);
       System.out.println("Resultado del residuo de 2 objetos BigInteger : " + resultado);

Operaciones de Bits  .xor() - and() - or() –

        Se usan los métodos .xor() - and() - or()  del objeto BigInteger para operaciones de bits.

        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.xor(dos);
        System.out.println("Resultado del xor de 2 objetos BigInteger : " + resultado);
       
        resultado = uno.or(dos);
        System.out.println("Resultado del or de 2 objetos BigInteger : " + resultado);
       
        resultado = uno.and(dos);
        System.out.println("Resultado del and de 2 objetos BigInteger : " + resultado);

Código Completo:

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        crearBigIntegerMetodo1();
        crearBigIntegerMetodo2();
        operacionSuma();
        operacionResta();
        operacionMultiplicacion();
        operacionDivision();
        operacionResiduo();
        operacionesDeBits();
    }

    public static void crearBigIntegerMetodo1() {
        // Formas de instanciar un BigInteger :
        // Forma 1:
        BigInteger num1 = BigInteger.ONE;
        BigInteger num2 = BigInteger.TEN;
        BigInteger num3 = BigInteger.ZERO;

        System.out.println("Valor de num1 : " + num1);
        System.out.println("Valor de num2 : " + num2);
        System.out.println("Valor de num3 : " + num3);
    }

    public static void crearBigIntegerMetodo2() {
        // Formas de instanciar un BigInteger :
        // Forma 2:        
        Scanner s = new Scanner(System.in);

        String numero = "9223372036854775807000000";
        BigInteger porString = new BigInteger(numero);
        System.out.println("BigInteger creado por cadena String : " + porString);

        long Long = 9223372036854775807L;
        BigInteger porLong = new BigInteger(Long + "");
        System.out.println("BigInteger creado por long : " + porLong);

        System.out.println("Ingrese un número BigInteger : ");
        BigInteger leidoPorTeclado = s.nextBigInteger();
        System.out.println("El BigInteger leído por teclado es : " + leidoPorTeclado);
    }

    public static void operacionSuma() {
        // Se usa el método .add() del objeto BigInteger.
        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.add(dos);
        System.out.println("Resultado de suma de 2 objetos BigInteger : " + resultado);
    }

    public static void operacionResta() {
        // Se usa el método .subtract() del objeto BigInteger.
        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.subtract(dos);
        System.out.println("Resultado de resta de 2 objetos BigInteger : " + resultado);

    }

    public static void operacionMultiplicacion() {
        // Se usa el método .multiply() del objeto BigInteger.
        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.multiply(dos);
        System.out.println("Resultado de multiplicación de 2 objetos BigInteger : " + resultado);

    }

    public static void operacionDivision() {
        // Se usa el método .divide() del objeto BigInteger.
        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.divide(dos);
        System.out.println("Resultado de división de 2 objetos BigInteger : " + resultado);
    }

    public static void operacionResiduo() {
        // Se usa el método .divide() del objeto BigInteger.
        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("4");

        BigInteger resultado = uno.mod(dos);
        System.out.println("Resultado del residuo de 2 objetos BigInteger : " + resultado);
    }

    public static void operacionesDeBits() {
        // Se usa el método .xor() - and() - or() del objeto BigInteger.
        BigInteger uno = new BigInteger("9223372036854775807");
        BigInteger dos = new BigInteger("9223372036854775807");

        BigInteger resultado = uno.xor(dos);
        System.out.println("Resultado del xor de 2 objetos BigInteger : " + resultado);
        
        resultado = uno.or(dos);
        System.out.println("Resultado del or de 2 objetos BigInteger : " + resultado);
        
        resultado = uno.and(dos); 
        System.out.println("Resultado del and de 2 objetos BigInteger : " + resultado);
    }
}

Con esto concluye el tema de manejo básico de clase BigInteger, demostrando que es una gran ayuda para realizar operaciones con números con dígitos muy grandes.

Cualquier duda- comentario – sugerencia estoy a sus órdenes. 

miércoles, 25 de junio de 2014

Métodos de la clase Math en Java.

Cuando estamos programando, muchas veces surge la necesidad de recurrir a una función matemática, por suerte existe una clase de java que tiene muchas funciones matemáticas ya implementadas dentro de sus métodos. Estoy hablando de la clase Math, es una clase que tiene métodos estáticos, y una que otra constante que nos servirán para poder trabajar.

¿A qué me estoy refiriendo con métodos estáticos?
En su forma mas simple, es que para usarlos , no necesitamos de crear un objeto de esta clase, simplemente debemos si es que queremos usar un método de la clase Math, llamar a la clase , poner un punto y llamar al método deseado 

Ejemplo
  Math.random();

De esta manera obtenemos el resultado de la función que hayamos llamado.

Bien entonces empecemos por desarmar a la clase Math....

Primero que nada nombraré a dos contantes muy útiles que estan declaradas aquí una es la constante PI, y la otra en numero de euler E.

Los valores de estas dos constantes son los siguientes: 

PI
3.141592653589793
E
2.718281828459045

para poder utilizarlas debemos llamar a la clase Math seguida de un punto y en mayúsculas el nombre de la constante. aquí podemos ver un ejemplo de como llamarlas.

   
   System.out.println("La constante PI es igual a: "+ Math.PI);
   System.out.println("La constante E es igual a: "+ Math.E);

Con este ejemplo  podremos imprimir los valores de estas dos contantes en la pantalla. como se muestra a continuación:

Constantes de la clase Math







Vamos con la parte interesante, los MÉTODOS, existen gran variedad de metodos en esta clase , con distintas finalidades, los iremos nombrando, pero antes debemos tener en cuenta lo siguiente.
               
·     Las funciones trigonométricas (seno, coseno, tangente, etc) miden en radianes, no en grados, de modo que más de una vez deberemos usar "toRadians" y "toDegrees" si nos resulta más cómodo pensar en grados.

Por suerte esos dos métodos "toRadians()" y "toDegrees()" también pertenecen a esta clase y también podemos usarlos de igual manera. Una vez teniendo en claro lo anterior, podemos ir nombrando los métodos que nos interesan para trabajar con funciones matemáticas a través de la clase Math.

Empecemos por las  funciones trigonométricas

 En la clase Math podemos encontrar las siguientes :
       
  • acos()             Arco coseno
  • asin()              Arco seno
  • atan()             Arco tangente entre -PI/2 y PI/2
  • cos(double)   Coseno
  • sin(double)    Seno
  • tan(double)    Tangente

Si quisiéramos imprimir estas funciones con valores aleatorios haríamos lo siguiente:

   
        System.out.println("Arcocoseno de 45º = " + Math.acos(Math.toRadians(45)));
        System.out.println("Arcoseno de 45º = " + Math.asin(Math.toRadians(45)));
        System.out.println("Arcotangente de 45º = " + Math.atan(Math.toRadians(45)));
        System.out.println("Coseno de 45º = " + Math.cos(Math.toRadians(45)));
        System.out.println("Seno de 45º = " + Math.sin(Math.toRadians(45)));
        System.out.println("Tangente de 45º = " + Math.tan(Math.toRadians(45)));          

Es importante poner atención a como se saco por ejemplo el seno de 45 grados,
Observa que usamos primero la función Math.sin(); y como argumento le pasamos el 45 pero convertido a radianes con la función Math.toRadians(45); , esto por que como ya habíamos mencionado, las funciones trigonométricas de esta clase miden los valores en radianes.


La salida  para el código anterior es la siguiente:


Resultados de usar las funciones trigonométricas de la clase Math










Es hora de ver otros métodos interesantes de la clase Math, como lo son, los redondeos:

Estos son una parte importante de analizar, puesto que muchas veces tendremos que ver maneras de redondear de distintas maneras un numero. Para nuestra suerte la clase Math también tiene distintos métodos que permiten redondear de distintas maneras, veamos cuales son :

  • ceil()                       Entero mayor más cercano
  • floor()                      Entero menor más cercano
  • rint(double)            Entero más próximo
  • round()                   Entero más cercano (redondeo de la forma habitual)


si quisiéramos probar estas funciones , imprimiendo las con valores random , seria como sigue 

  
        //Redondeo con el método ceil 
        System.out.println("Redondear 1.9 al valor mayor entero mas cercano " + Math.ceil(1.9));
        System.out.println("Redondear 1.2 al valor mayor entero mas cercano " + Math.ceil(1.2));
        System.out.println("Redondear 1.5 al valor mayor entero mas cercano " + Math.ceil(1.5));
        //Redondeo con el Método floor
        System.out.println("Redondear 1.9 al valor menor entero mas cercano " + Math.floor(1.9));
        System.out.println("Redondear 1.2 al valor menor entero mas cercano " + Math.floor(1.2));
        System.out.println("Redondear 1.5 al valor menor entero mas cercano " + Math.floor(1.5));
        //Aproximación al entero más próximo  con el método rint
        System.out.println("Entero mas proximo de 1.2 = " + Math.rint(1.2));
        System.out.println("Entero mas proximo de 1.5 = " + Math.rint(1.5));
        System.out.println("Entero mas proximo de 1.9 = " + Math.rint(1.9));
        //Redondeo habitual con el metodo round
        System.out.println("Redondero habitual de 1.2 = " + Math.round(1.2));
        System.out.println("Redondero habitual de 1.5 = " + Math.round(1.5));
        System.out.println("Redondero habitual de 1.9 = " + Math.round(1.9));


El resultado de este código seria el siguiente:
Distintos Redondeos con métodos de la clase Math











Aunque estos métodos de redondeo son muy buenos, no son los únicos ,puesto que Java tienes mas clases implementadas para ello, estas las abarcaremos en publicaciones posteriores.

Por ultimo veremos algunos otros métodos interesantes :
  • abs()                       Valor absoluto
  • exp()                       Exponencial
  • log()                        Logaritmo natural (base e)
  • max( , )                   Máximo de dos valores
  • min( , )                    Mínimo de dos valores
  • pow( , )                   Primer número elevado al segundo
  • random()                Número aleatorio (al azar) entre 0.0 y 1.0
  • sqrt()                       Raíz cuadrada
  • toDegrees()           Pasa de radianes a grados (a partir de Java 2)
  • toRadians()            Pasa de grados a radianes (a partir de Java 2)
Ejemplo para poder usarlos :
  
         System.out.println("Valor absoluto de 1 = " + Math.abs(1) + "\n Valor absoluto de -1 = " + Math.abs(-1));
         System.out.println("Exponencial  de un numero " + Math.exp(3));
         System.out.println("Logaritmo natural base e" + Math.log(3));
         System.out.println("Maximo de 6 y 7 " + Math.max(6, 7));
         System.out.println("Minimo de 6 y 7 " + Math.min(6, 7));
         System.out.println("5^2 = " + Math.pow(5, 2));
         System.out.println("Número aleatorio " + Math.random());
         System.out.println("Raiz cuadrada de 25 = " + Math.sqrt(25));
         System.out.println("Raiz cuadrada de 213 =" + Math.sqrt(213));
         System.out.println("45º convertidos a radianes = " + Math.toRadians(45));
         System.out.println("180 radianes covertidos a grados = " + Math.toDegrees(180));

y el resultado que proporcionan :
Algunos métodos útiles de la clase Math











Entonces podemos concluir que la clase Math tienen bastantes buenos métodos que podemos implementar a la hora de querer usar alguna formula matemática, recordemos que si ya existe el método para que reinventar la rueda, sin nada mas que agregar, espero sus comentarios dudas, y hasta las próxima.

Lectura por teclado : Uso básico del Objeto Scanner.

El tema central es la lectura por teclado, utilizando el objeto Scanner que se encuentra en la API de java.

El paquete donde se cuentra es :
       java.util.Scanner
A la hora de utilizarlo quedaría de esta manera :
      import  java.util.Scanner;

Teniendo en cuenta esto, vamos a empezar:

Primero: 
  • ¿Qué es lo que queremos leer? 
  • ¿Qué es lo que podemos leer con Scanner?
Nos centraremos en el uso básico del Scanner.
Contestando la primera pregunta:

¿Qué es lo que queremos leer con Scanner?

La mayoría de los usuarios quieren ingresar en un programa, dependiendo su finalidad:
  • Números.
  • Palabras.
El primer punto, los números hay diferentes tipos: enteros , decimales , números pequeños, extremadamente grandes, etc...

Sobre las palabras, son generales y se pueden utilizar de diversas maneras, según el objetivo del programa.

Por el lado de los números, lo que le debe de importar al programador es que finalidad va a tener su programa. El tipo de número que tiene que utilizar.

¿Qué es lo que podemos leer con Scanner?

En Java existen los tipos de datos primitivos.

  • Hablando de valores números se presentan: 

Nombre   Tipo       Ocupa       Rango Aproximado

byte         Entero     1 byte      -128 a 127

short        Entero     2 bytes    -32768 a 32767

int            Entero     4 bytes    -2147483648 a 2147483647

long         Entero     8 bytes    -9223372036854775808 a 9223372036854775807

Nombre            Tipo              Ocupa       Rango Aproximado

float        Decimal simple     4 bytes       ± 3.4x10-38 a ± 3.4x1038

double    Decimal doble      8 bytes       ± 1.8x10-308 a ± 1.8x10308

*Es importante que el programador tenga en cuenta el rango aproximado  del tipo de dato a utilizar. Dado que  si no se manejan correctamente pueden desbordarse y dar valores incorrectos

**Desbordarse : superar su rango aproximado, por ende dar un valor incorrecto.

En Java, para cada tipo de dato existe una clase asociada en la API. Todas ellas se encuentran en java.lang las cuales vienen por defecto.

Tipo de Dato       Clase en Java

byte                          Byte
short                         Short
int                             Integer
long                          Long
float                          Float
double                      Double

Todos los tipos de datos numéricos, cuando los creamos vienen con 0 [cero] como valor por defecto.

Los valores del tipo numérico entero es un número real, pueden ser positivos o negativos.

Los valores del tipo numérico decimal son números  que llevan un punto decimal y que pueden ser positivos o negativos.


  • Hablando de cadenas de caracteres Java presenta:

Nombre       Tipo                Ocupa       Rango Aproximado       Clase en Java

char           Carácter simple      2 byte       Caracteres Unicode        Character

  • Hablando de datos lógicos se encuentra: 

Nombre           Tipo               Ocupa       Rango          Clase en Java

boolean          Dato lógico     1 byte       true - false         Boolean


¿ Y cómo leemos esos valores con el Scanner?

Primero se crea una instancia del objeto Scanner. Lo que recibe en el constructor es el flujo del teclado. *Se agrega System.in [flujo de entrada].

     Scanner s = new Scanner (System.in); 


Concluido lo anterior, Scanner tiene métodos para lectura de los datos primitivos presentados, con la facilidad de utilizar la variable del Scanner y llamar al método para el correspondiente tipo de dato.

       Numérico : 

       Tipo de Dato     Forma de Lectura
       
        byte                     .nextByte();
        short                    .nextShort();
        int                        .nextInt();
        long                     .nextLong();
        float                     .nextFloat();
        double                .nextDouble();

        Cadena de Caracteres:

       Tipo de Dato     Forma de Lectura

        char              No Aplica con Scanner.
        String          .next()
        String          .nextLine()

        Dato Lógico

       Tipo de Dato     Forma de Lectura

        boolean             .nextBoolean();

*Para leer Cadena de caracteres se utiliza el objeto String y los métodos antes mencionados. La diferencia radica en :

.next() - Lee una linea que el usuario introduzca hasta donde se encuentre un espacio.

   Ejemplo :
       String ejemplo = s.next()       // El usuario ingresa por teclado :   hola mundo

  Cuando el usuario imprima la variable ejemplo se mostrará :
    hola    // El método next() solo lee hasta encontrar un espacio en blanco.

.nextLine() - Lee una linea completa que introduzca el usuario, no importando si esta separada por espacios.

**Para leer un tipo de dato lógico, solo se acepta que el usuario ingrese true-false, tanto en mayúsculas como minúsculas, de otra manera se arrojará una excepción

Se crean 6 variables numéricas con sus respectivo tipo de dato:

byte                 
     byte a = s.nextByte();

short
     short corto = s.nextShort();

int
     int entero = s.nextInt();

long
     long largo = s.nextLong();

float
     float flotante= s.nextFloat();

double
     double doble = s.nextDouble();

Para finalizar, solo se mandan a imprimir. El código quedaría de la siguiente manera:


    public static void leerDatosNumericos() {
        
        Scanner s = new Scanner(System.in);
        
        byte a = s.nextByte();
        short corto = s.nextShort();
        int entero = s.nextInt();
        long largo = s.nextLong();
        float flotante = s.nextFloat();
        double doble = s.nextDouble();

        System.out.println("El byte es : " + a);
        System.out.println("El short es : " + corto);
        System.out.println("El int es : " + entero);
        System.out.println("El long es : " + largo);
        System.out.println("El float es : " + flotante);
        System.out.println("El double es : " + doble);
    }

Para leer cadenas de texto, se usan los métodos antes mencionados :

String cadena = s.next();
String cadena2 = s.nextLine();


*Problema : Al leer con Scanner, en algunos métodos de lectura dejan basura, ya sea el retorno de carro [\r]  o nueva linea [\n]. En el buffer del flujo de entrada se queda la basura mencionada.

**Para  resolver lo anterior , basta con poner el método leer Cadena Completa [s.nextLine()] para que quite la basura. El problema mencionado surge a la hora de leer con un .next() o después de leer un número y siempre, en ambos casos siga el leer un String. En C o C++ existe algo parecido, el fflush () , por si están acostumbrados a esos lenguajes una comparación.


Finalizando el método de lectura de cadenas de la siguiente manera:

    public static void leerCadenas() {
        Scanner s = new Scanner(System.in);

        String cadena1 = s.next();
        
        s.nextLine(); // Para limpiar el buffer
        
        String cadena2 = s.nextLine();

        System.out.println("Cadena 1 : " + cadena1);
        System.out.println("Cadena 2 : " + cadena2);
        
    }

Para leer tipos de dato lógicos es de la siguiente manera:

    public static void leerDatoLogico() {
        Scanner s = new Scanner(System.in);
        
        boolean boleano = s.nextBoolean();
        
        System.out.println("El boolean es : "+boleano);
    }

Con esto termina el tema. Lectura básica del teclado con el Objeto Scanner.