You are on page 1of 25

Estructura de Datos IDAT

Luis Arias Hidalgo

Tema 4: Funciones y Procedimientos


Funciones. Las funciones son bloques de cdigo utilizados para dividir un programa en partes ms pequeas, cada una de las cules tendr una tarea determinada. para luego retornar al punto desde donde fue llamada. Es decir es un conjunto de sentencias que hacen un proceso y devuelven un valor. Algunas funciones hacen un proceso pero no devuelven nada , en este caso a la funcin se le conoce como mtodo o procedimiento Sintaxis: tipo_funcin nombre_funcin (tipo y nombre de argumentos) { bloque de sentencias }

tipo_funcin: puede ser de cualquier tipo de los que conocemos. El valor devuelto por la funcin ser de este tipo. Por defecto, es decir, si no indicamos el tipo, la funcin devolver un valor de tipo entero ( int ). Si no queremos que retorne ningn valor deberemos indicar el tipo vaco ( void ). nombre_funcin: es el nombre que le daremos a la funcin. tipo y nombre de argumentos: son los parmetros que recibe la funcin. Los argumentos de una funcin no son ms que variables locales que reciben un valor. Este valor se lo enviamos al hacer la llamada a la funcin. Pueden existir funciones que no reciban argumentos. bloque de sentencias: es el conjunto de sentencias que sern ejecutadas cuando se realice la llamada a la funcin. Las funciones pueden ser llamadas desde la funcin main o desde otras funciones. Nunca se debe llamar a la funcin main desde otro lugar del programa. Por ltimo recalcar que los argumentos de la funcin y sus variables locales se destruirn al finalizar la ejecucin de la misma. Ejemplo /* 1) */ /* 2) */ /* 3) */ /* 4) */ int sumar(int a , int b) { return a + b; }

1) cabecera del mtodo : int sumar(int a,int b) tipo del resultado : int nombre del mtodo : sumar lista de parmetros : int a,int b 2) comienzo del bloque o cuerpo del mtodo 3) Instruccin : se retorna la suma de a y b 4) fin del bloque

-1-

Estructura de Datos IDAT

Luis Arias Hidalgo

Si se coloca las palabras public static antes del mtodo se logra un comportamiento de tipo global. 1.- Crear una function que devuleva la suma de 2 numeros class suma { public static void main(String arg[ ]) { int x,y; x = 12; y = 34; int s = suma(x,y); System.out.println("La suma es : " + s); } //Aqui se define la funcion public static int suma(int a,int b) { return a + b; } } Resultado:

1.- Crear una function que devuelva TRUE si un numero es par caso contario devuelva FALSE class metodo1 { public static void main(String arg[ ]) { int a = 5; if ( par(a) == true) { System.out.println(a + " es par "); } else { System.out.println(a + " es impar"); } } public static boolean par(int num) { boolean p = false; if (num % 2 == 0) { p = true; } return p; } }

-2-

Estructura de Datos IDAT

Luis Arias Hidalgo

3.- implementar un programa en java que determine los 100 primeros nmeros palndromes a partir de un nmero ingresado por teclado en adelante, llamando al mtodo : invertir_num.

class palindromes { public static void main(String Arg[ ]) { int numero = 0; int contador = 0; numero = Integer.parseInt(JOptionPane.showInputDialog(Ingrese numero)); System.out.println("\nLos 100 primeros palindromes a contar del " + numero); System.out.println("\n"); while (contador < 100) { if ( invertir_num(numero) == numero) { System.out.print(numero + "\t"); contador++; } numero++; } } public static int invertir_num ( int num ) { int div_entera,resto,num_inv; num_inv = 0; div_entera = num; resto = 0; while (div_entera != 0) { resto = div_entera % 10; div_entera = div_entera / 10; num_inv = num_inv * 10 + resto; } return num_inv; } }

-3-

Estructura de Datos IDAT


Paso de valores a funciones

Luis Arias Hidalgo

En el paso de parmetros a funciones hay dos aproximaciones clsicas: el paso por valor y paso por referencia.

Paso por valor significa que cuando un argumento se pasa a una funcin, la funcin recibe una
copia del valor original. Por lo tanto, si la funcin modifica el parmetro, slo la copia cambia y el valor original permanece intacto.

Paso por referencia significa que cuando un argumento se pasa a una funcin, la funcin
recibe la direccin de memoria del valor original, no la copia del valor. Por lo tanto, si la funcin modifica el parmetro, el valor original en el cdigo que llam a la funcin cambia. Ejercicios Resueltos 1. Imprimir nombre y promedio de un alumno, capturar 3 calificaciones y nombre en un procedimiento, calcular promedio en una funcin y mostrar los resultados. Pasando parmetros por valor package ejemplo1; import javax.swing.JOptionPane; public class Main { static double promedio (int n1, int n2, int n3){ double prom; prom = (n1+n2+n3)/3; return prom; } static int pedirnum(){ String nota =JOptionPane.showInputDialog("Ingrese Nota1:"); return Integer.parseInt(nota); } public static void main(String[] args) { String nota; int n1,n2,n3; double prom; n1 = pedirnum();n2 = pedirnum();n3 = pedirnum(); prom = promedio(n1,n2,n3); JOptionPane.showMessageDialog( null,prom,"Resultado",JOptionPane.INFORMATION_MESSAGE ); } }

-4-

Estructura de Datos IDAT

Luis Arias Hidalgo

2. Crear una tabla de multiplicar, capturar datos de entrada en funcin, control de ciclo en el principal, operaciones en una funcin, muestra de datos en el principal. import javax.swing.JOptionPane; public class Main { public int pedirnum(){ String nota =JOptionPane.showInputDialog("Ingrese Nota1:"); return Integer.parseInt(nota); } public String tabla(int num,int por){ return (num + " x " +por + " = "+num*por); } public static void main(String[] args) { int i,n = pedirnum(); for (i=0;i<=12;i++){ System.out.println(tabla(n,i)); } } } Ejercicios resueltos 1.- Hacer un programa que ejecute un procedimiento, el cual imprime una variable y su valor. import java.io.*; public class Ejemplo { public static void main(String[] args) { int x; x = 10; proc1(); System.out.println("x="+x); } static void proc1(){ int y; y = 20; System.out.println("y="+y); }; } // cierra clase

-5-

Estructura de Datos IDAT

Luis Arias Hidalgo

2.- Hacer un programa que muestre datos (enteros y cadenas) mediante procesos, una funcin operacin que regrese de a cuerdo al parmetro recibido: el doble si es nmero o agregue la palabra IDAT si es cadena. La captacin de variables ser mediante funciones. import javax.swing.JOptionPane; public class Ejercicio1 { public static void main(String args[]){ Ejercicio1 x = new Ejercicio1(); x. mostrar(123); x.mostrar("hola"); x.mostrar( x.operacion(5) ); x.mostrar( x.operacion("Hola") ); String s = x.pedir("Ingrese cadena"); int i = x.pedir("ingrese numero", 5); x. mostrar(s); x.mostrar(i); } public void mostrar(String msj){ JOptionPane.showMessageDialog(null,msj); } public void mostrar(int msj){ JOptionPane.showMessageDialog(null,+msj); } public int operacion(int var){ return var*2; } public String operacion(String cad){ return cad + " IDAT"; } public int pedir(String msj, int i){ String var =JOptionPane.showInputDialog(msj); return Integer.parseInt(var); } public String pedir(String msj){ return JOptionPane.showInputDialog(msj); } }

3.- Construir un programa que contenga el siguiente men con las opciones: 1-Pasar de Soles a Dolares 2-Calcular el area de un triangulo 3-Calcular el precio de una venta (cantidad * precio) 0-Salir

-6-

Estructura de Datos IDAT


import javax.swing.JOptionPane; public class NewClass { public static void main(String args[]){ String menu="Menu de Opciones"+ "\n1.-Soles a Dolares"+ "\n2.-Area de un tringulo"+ "\n3.-Boleta de venta"+ "\n0.-Salir"; int op; do{ NewClass x = new NewClass(); double opcion = x.pedirnum(menu); op = (int)opcion; switch(op){ case 1:SolesDolar();break; case 2:Triangulo();break; case 3:Boleta();break; } }while(op!=0); } static double pedirnum(String msj){ String nota =JOptionPane.showInputDialog(msj); return Double.parseDouble(nota); } static String pedirlet(String msj){ String nota =JOptionPane.showInputDialog(msj); return nota; } public void mostrar(String msj){ JOptionPane.showMessageDialog(null,msj); } public void mostrar(double msj){ JOptionPane.showMessageDialog(null,msj); } public static void SolesDolar(){ double soles=pedirnum("Ingrese Cantidad en Soles"); NewClass x = new NewClass(); x.mostrar(soles*3.12); } public static void Triangulo(){ NewClass x = new NewClass(); double b = pedirnum("Ingrese Base"); double h = pedirnum("Ingrese Altura"); double area = b*h/2; x.mostrar("El area es : " + area); } public static void Boleta(){ NewClass x = new NewClass(); double can = pedirnum("Ingrese Cantidad"); double costo= pedirnum("Ingrese Costo"); double total = can*costo; x.mostrar("El total es" + total); } }

Luis Arias Hidalgo

-7-

Estructura de Datos IDAT


Funciones de Cadenas (Clase String)

Luis Arias Hidalgo

Dentro de un objeto de la clases String o StringBuffer, Java crea un array de caracteres de una forma similar a como lo hace el lenguaje C++. A este array se accede a travs de las funciones miembro de la clase. Los strings u objetos de la clase String se pueden crear explcitamente o implcitamente. Para crear un string implcitamente basta poner una cadena de caracteres entre comillas dobles. Por ejemplo, cuando se escribe System.out.println("El primer programa"); Java crea un objeto de la clase String automticamente. Para crear un string explcitamente escribimos String str=new String("El primer programa"); Tambin se puede escribir, alternativamente String str="El primer programa"; Para crear un string nulo se puede hacer de estas dos formas String str=""; String str=new String(); Un string nulo es aqul que no contiene caracteres, pero es un objeto de la clase String. Sin embargo, String str; est declarando un objeto str de la clase String, pero an no se ha creado ningn objeto de esta clase. Cmo se obtiene informacin acerca del string Una vez creado un objeto de la clase String podemos obtener informacin relevante acerca del objeto a travs de las funciones miembro. Para obtener la longitud, nmero de caracteres que guarda un string se llama a la funcin miembro length. String str="El primer programa"; int longitud=str.length(); Podemos conocer si un string comienza con un determinado prefijo, llamando al mtodo startsWith, que devuelve true o false, segn que el string comience o no por dicho prefijo String str="El primer programa"; boolean resultado=str.startsWith("El");

-8-

Estructura de Datos IDAT


En este ejemplo la variable resultado tomar el valor true.

Luis Arias Hidalgo

De modo similar, podemos saber si un string finaliza con un conjunto dado de caracteres, mediante la funcin miembro endsWith. String str="El primer programa"; boolean resultado=str.endsWith("programa"); Si se quiere obtener la posicin de la primera ocurrencia de la letra p, se usa la funcin indexOf. String str="El primer programa"; int pos=str.indexOf('p'); Para obtener las sucesivas posiciones de la letra p, se llama a otra versin de la misma funcin pos=str.indexOf('p', pos+1); El segundo argumento le dice a la funcin indexOf que empiece a buscar la primera ocurrencia de la letra p a partir de la posicin pos+1. Otra versin de indexOf busca la primera ocurrencia de un substring dentro del string. String str="El primer programa"; int pos=str.indexOf("pro"); Vemos que una clase puede definir varias funciones miembro con el mismo nombre pero que tienen distinto nmero de parmetros o de distinto tipo. La comparacin de strings nos da la oportunidad de distinguir entre el operador lgico == y la funcin miembro equals de la clase String. En el siguiente cdigo String str1="El lenguaje Java"; String str2=new String("El lenguaje Java"); if(str1==str2){ System.out.println("Los mismos objetos"); }else{ System.out.println("Distintos objetos"); } if(str1.equals(str2)){ System.out.println("El mismo contenido"); }else{ System.out.println("Distinto contenido"); } Esta porcin de cdigo devolver que str1 y str2 son distintos objetos pero con el mismo contenido. str1 y str2 ocupan posiciones distintas en memoria pero guardan los mismos datos. Cambiemos la segunda sentencia y escribamos String str1="El lenguaje Java"; String str2=str1; System.out.prinln("Son el mimso objeto "+(str1==str2);

-9-

Estructura de Datos IDAT

Luis Arias Hidalgo

Los objetos str1 y str2 guardan la misma referencia al objeto de la clase String creado. La expresin (str1==str2) devolver true. Asi pues, el mtodo equals compara un string con un objeto cualquiera que puede ser otro string, y devuelve true cuando dos strings son iguales o false si son distintos. String str="El lenguaje Java"; boolean resultado=str.equals("El lenguaje Java"); La variable resultado tomar el valor true. La funcin miembro comapareTo devuelve un entero menor que cero si el objeto string es menor (en orden alfabtico) que el string dado, cero si son iguales, y mayor que cero si el objeto string es mayor que el string dado. String str="Toms"; int resultado=str.compareTo("Alberto"); La variable entera resultado tomar un valor mayor que cero, ya que Toms est despus de Alberto en orden alfabtico. String str="Alberto"; int resultado=str.compareTo("Toms"); La variable entera resultado tomar un valor menor que cero, ya que Alberto est antes que Toms en orden alfabtico. En muchas ocasiones es necesario extraer una porcin o substring de un string dado. Para este propsito hay una funcin miembro de la clase String denominada substring. Para estraer un substring desde una posicin determinada hasta el final del string escribimos String str="El lenguaje Java"; String subStr=str.substring(12); Se obtendr el substring "Java". Una segunda versin de la funcin miembro substring, nos permite extraer un substring especificando la posicin de comienzo y la el final. String str="El lenguaje Java"; String subStr=str.substring(3, 11); Se obtendr el substring "lenguaje". Recurdese, que las posiciones se empiezan a contar desde cero. Para convertir un nmero en string se emplea la funcin miembro esttica valueOf (ms adelante explicaremos este tipo de funciones). int valor=10; String str=String.valueOf(valor);

- 10 -

Estructura de Datos IDAT

Luis Arias Hidalgo

La clase String proporciona versiones de valueOf para convertir los datos primitivos: int, long, float, double. Cuando introducimos caracteres en un control de edicin a veces es inevitable que aparezcan espacios ya sea al comienzo o al final. Para eliminar estos espacios tenemos la funcin miembro trim String str=" 12 "; String str1=str.trim(); Para convertir un string en nmero entero, primero quitamos los espacios en blanco al principio y al final y luego, llamamos a la funcin miembro esttica parseInt de la clase Integer (clase envolvente que describe los nmeros enteros) String str=" 12 "; int numero=Integer.parseInt(str.trim()); Para convertir un string en nmero decimal (double) se requieren dos pasos: convertir el string en un objeto de la clase envolvente Double, mediante la funcin miembro esttica valueOf, y a continuacin convertir el objeto de la clase Double en un tipo primitivo double mediante la funcin doubleValue String str="12.35 "; double numero=Double.valueOf(str).doubleValue(); Se puede hacer el mismo procedimiento para convertir un string a nmero entero String str="12"; int numero=Integer.valueOf(str).intValue(); El mtodo split devuelve un array de String. Es muy til cuando tenemos un conjunto de elementos separados por comas. Por ejemplo: String colores = "rojo,amarillo,verde,azul,morado,marrn"; String[] arrayColores = colores.split(","); // En este momento tenemos un array en el que cada elemento es un color. for (int i = 0; i < arrayColores.length; i++) { System.out.println(arrayColores[i]); } La salida ser: rojo amarillo verde azul morado marrn La clase StringBuffer En la seccin dedicada a los operadores hemos visto que es posible concatenar cadenas de caracteres, es, decir, objetos de la clase String. Ahora bien, los objetos de la clase String son

- 11 -

Estructura de Datos IDAT

Luis Arias Hidalgo

constantes lo cual significa que por defecto, solamente se pueden crear y leer pero no se pueden modificar. Imaginemos una funcin miembro a la cual se le pasa un array de cadenas de caracteres. Los arrays se estudiarn en la siguiente pgina.

public class CrearMensaje{ public String getMensaje(String[] palabras){ String mensaje=""; for(int i=0; i<palabras.length; i++){ mensaje+=" "+palabras[i]; } return mensaje; } //... }

Cada vez que se aade una nueva palabra, se reserva una nueva porcin de memoria y se desecha la vieja porcin de memoria que es ms pequea (una palabra menos) para que sea liberada por el recolector de basura (grabage collector). Si el bucle se realiza 1000 veces, habr 1000 porciones de memoria que el recolector de basura ha de identificar y liberar. Para evitar este trabajo extra al recolector de basura, se puede emplear la clase StringBuffer que nos permite crear objetos dinmicos, que pueden modificarse. public class CrearMensaje{ public String getMensaje(String[] palabras){ StringBuffer mensaje=new StringBuffer(); for(int i=0; i<palabras.length; i++){ mensaje.append(" "); mensaje.append(palabras[i]); } return mensaje.toString(); } //... } La funcin append incrementa la memoria reservada para el objeto mensaje con una palabra ms sin crear nueva memoria, cada vez que se ejecuta el bucle. La funcin toString, que veremos ms adelante, convierte un objeto en una cadena de caracteres.

- 12 -

Estructura de Datos IDAT


Ejercicios resueltos de la Clase String // 1.- Constructores de la clase String. import javax.swing.*; public class ConstructoresString { public static void main( String args[] ) { char arregloChar[] = { 'c', 'u', 'm', 'p', 'l', 'e', ' ', 'a', '', 'o', 's' }; byte arregloByte[] = { ( byte ) 'a', ( byte ) '', ( byte ) 'o', ( byte ) ' ', ( byte ) 'n', ( byte ) 'u', ( byte ) 'e', ( byte ) 'v', (byte) 'o' }; String s = new String( "hola" ); // usar constructores de String String s1 = new String(); String s2 = new String( s ); String s3 = new String( arregloChar ); String s4 = new String( arregloChar, 7, 4 ); String s5 = new String( arregloByte, 4, 5 ); String s6 = new String( arregloByte ); // anexar objetos String a salida String salida = "s1 = " + s1 + "\ns2 = " + s2 + "\ns3 = " + s3 + "\ns4 = " + s4 + "\ns5 = " + s5 + "\ns6 = " + s6;

Luis Arias Hidalgo

JOptionPane.showMessageDialog( null, salida, "Constructores de la clase String", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } }

- 13 -

Estructura de Datos IDAT

Luis Arias Hidalgo

// 2.- Este programa demuestra los mtodos length, charAt y getChars // de la clase String. import javax.swing.*; public class VariosString { public static void main( String args[] ) { String s1 = "hola a todos"; char arregloChar[] = new char[ 4 ]; String salida = "s1: " + s1; // probar mtodo length salida += "\nLongitud de s1: " + s1.length(); // iterar a travs de los caracteres en s1 y mostrar al revs salida += "\nLa cadena invertida es: "; for ( int cuenta = s1.length() - 1; cuenta >= 0; cuenta-- ) salida += s1.charAt( cuenta ) + " "; // copiar caracteres de la cadena a arregloChar s1.getChars( 0, 4, arregloChar, 0 ); salida += "\nEl arreglo de caracteres es: "; for ( int cuenta = 0; cuenta < arregloChar.length; cuenta++ ) salida += arregloChar[ cuenta ]; JOptionPane.showMessageDialog( null, salida, "Mtodos de String para manipular caracteres", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } } // fin de la clase VariosString

// 3.- Los mtodos equals, equalsIgnoreCase, compareTo y regionMatches de String. import javax.swing.JOptionPane; public class CompararString { public static void main( String args[] ) { String s1 = new String( "hola" ); // s1 es una copia de "hola" String s2 = "adis"; String s3 = "Feliz Cumpleaos"; String s4 = "feliz cumpleaos"; String salida = "s1 = " + s1 + "\ns2 = " + s2 + "\ns3 = " + s3 + "\ns4 = " + s4 + "\n\n"; // probar igualdad if ( s1.equals( "hola" ) ) // true

- 14 -

Estructura de Datos IDAT


salida += "s1 es igual a \"hola\"\n"; else salida += "s1 es distinta de \"hola\"\n"; // probar igualdad con == if ( s1 == "hola" ) // false; no son el mismo objeto salida += "s1 es igual a \"hola\"\n"; else salida += "s1 es distinta de \"hola\"\n"; // probar igualdad (ignorar maysculas) if ( s3.equalsIgnoreCase( s4 ) ) // true salida += "s3 es igual a s4\n"; else salida += "s3 es distinta de s4\n"; // probar compareTo salida += "\ns1.compareTo( s2 ) es " + s1.compareTo( s2 ) + "\ns2.compareTo( s1 ) es " + s2.compareTo( s1 ) + "\ns1.compareTo( s1 ) es " + s1.compareTo( s1 ) + "\ns3.compareTo( s4 ) es " + s3.compareTo( s4 ) + "\ns4.compareTo( s3 ) es " + s4.compareTo( s3 ) + "\n\n";

Luis Arias Hidalgo

// probar regionMatches (susceptible a maysculas) if ( s3.regionMatches( 0, s4, 0, 5 ) ) salida += "Los primeros 5 caracteres de s3 y s4 concuerdan\n"; else salida += "Los primeros 5 caracteres de s3 y s4 no concuerdan\n"; // probar regionMatches (ignorar maysculas) if ( s3.regionMatches( true, 0, s4, 0, 5 ) ) salida += "Los primeros 5 caracteres de s3 y s4 concuerdan"; else salida += "Los primeros 5 caracteres de s3 y s4 no concuerdan"; JOptionPane.showMessageDialog( null, salida, "Comparaciones entre cadenas", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } } // fin de la clase CompararString // 4.- String methods startsWith and endsWith. import javax.swing.*; public class InicioFinString { public static void main( String args[] ) { String cadenas[] = { "empez", "empezando", "termin", "terminando" }; String salida = ""; // probar el mtodo startsWith for ( int cuenta = 0; cuenta < cadenas.length; cuenta++ )

- 15 -

Estructura de Datos IDAT


if ( cadenas[ cuenta ].startsWith( "em" ) ) salida += "\"" + cadenas[ cuenta ] + "\" empieza con \"em\"\n"; salida += "\n"; // probar mtodo startsWith, empezando desde la posicin // 2 de la cadena for ( int cuenta = 0; cuenta < cadenas.length; cuenta++ ) if ( cadenas[ cuenta ].startsWith( "pez", 2 ) ) salida += "\"" + cadenas[ cuenta ] + "\" empieza con \"pez\" en la posicin 2\n"; salida += "\n"; // probar el mtodo endsWith for ( int cuenta = 0; cuenta < cadenas.length; cuenta++ ) if ( cadenas[ cuenta ].endsWith( "do" ) ) salida += "\"" + cadenas[ cuenta ] + "\" termina con \"do\"\n";

Luis Arias Hidalgo

JOptionPane.showMessageDialog( null, salida, "Comparaciones con la clase String", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } } // fin de la clase InicioFinString // 5.- String searching methods indexOf and lastIndexOf. import javax.swing.*; public class MetodosIndexString { public static void main( String args[] ) { String letras = "abcdefghijklmabcdefghijklm"; // probar indexOf para localizar un caracter en una cadena String salida = "'c' se encuentra en el ndice " + letras.indexOf( 'c' ); salida += "\n'a' se encuentra en el ndice " + letras.indexOf( 'a', 1 ); salida += "\n'$' se encuentra en el ndice " + letras.indexOf( '$' ); // probar lastIndexOf para buscar un caracter en una cadena salida += "\n\nLa ltima 'c' se encuentra en el ndice " + letras.lastIndexOf( 'c' ); salida += "\nLa ltima 'a' se encuentra en el ndice " + letras.lastIndexOf( 'a', 25 ); salida += "\nEl ltimo '$' se encuentra en el ndice " + letras.lastIndexOf( '$' ); // probar indexOf para localizar una subcadena en una cadena

- 16 -

Estructura de Datos IDAT


salida += "\n\n\"def\" se encuentra en el ndice " + letras.indexOf( "def" ); salida += "\n\"def\" se encuentra en el ndice " + letras.indexOf( "def", 7 ); salida += "\n\"hola\" se encuentra en el ndice " + letras.indexOf( "hola" );

Luis Arias Hidalgo

// probar lastIndexOf para encontrar una subcadena en una cadena salida += "\n\nEl ltimo \"def\" se encuentra en el ndice " + letras.lastIndexOf( "def" ); salida += "\nEl ltimo \"def\" se encuentra en el ndice " + letras.lastIndexOf( "def", 25 ); salida += "\nEl ltimo \"hola\" se encuentra en el ndice " + letras.lastIndexOf( "hola" ); JOptionPane.showMessageDialog( null, salida, "Mtodos de bsqueda de String", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } } // fin de la clase MetodosIndexString // 6.- Los mtodos substring de la clase String. import javax.swing.*; public class SubString { public static void main( String args[] ) { String letras = "abcdefghijklmabcdefghijklm"; // probar mtodos substring String salida = "La subcadena desde el ndice 20 hasta el final es " + "\"" + letras.substring( 20 ) + "\"\n"; salida += "La subcadena desde el ndice 3 hasta 6 es " + "\"" + letras.substring( 3, 6 ) + "\""; JOptionPane.showMessageDialog( null, salida, "Mtodos substring de la clase String", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } } // fin de la clase SubString // El mtodo concat de la clase String. import javax.swing.*; public class ConcatenacionString {

- 17 -

Estructura de Datos IDAT


public static void main( String args[] ) { String s1 = new String( "Feliz " ); String s2 = new String( "Cumpleaos" ); String salida = "s1 = " + s1 + "\ns2 = " + s2;

Luis Arias Hidalgo

salida += "\n\nResultado de of s1.concat( s2 ) = " + s1.concat( s2 ); salida += "\ns1 despus de la concatenacin = " + s1; JOptionPane.showMessageDialog( null, salida, "El mtodo concat de String", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); }

} // fin de la clase ConcatenacionString

- 18 -

Estructura de Datos IDAT


Funciones de Fecha (Clase Date)

Luis Arias Hidalgo

Trabajar con fechas en java no es algo del otro mundo ni tiene demasiadas complicaciones, pero la cantidad de formas que hay para hacerlo puede confundirnos, o peor an, puede que slo conozcamos la ms mala para hacerlo. Con estos artculos pretendo explicar un poco que clases tiene el lenguaje para trabajar con fechas, los mtodos ms usados y algunas sugerencias para realizar un trabajo adecuado que nos facilite el mantenimiento de nuestras aplicaciones. 1.- Las clases java.util.Date y java.sql.Date. Son dos de las clases ms usadas cuando una aplicacin implica el trabajo con fechas: java.util.Date: Segn la documentacin "La clase java.util.Date representa un instante de tiempo especfico, con precisin de milisegundos"; esto ms que ser una especie de "autoadulacin" para la clase, quiere decir que no solo se trata de una simple cadena al estilo yyyy/MM/dd, sino que almacena hasta milisegundos y que es posible trabajar con ellos. Antes del jdk1.1 la clase java.util.Date tena dos funciones adicionales a la que conocemos ahora, una de ellas era la interpretacin de datos que tenan que ver con fechas, como aos, das, segundos, entre otros. La otra era el formateo (la forma como se muestra) y parseo (convertir un String a java.util.Date). Pero debido a las dificultades que presentaban estas funcionalidades a la hora de internacionalizar los programas, esos mtodos ya est obsoletos y la clase java.util.Calendar se encarg de esto; as que en este momento esta clase, slo hace lo que se mencion al principio: "representa un instante de tiempo especfico, con precisin de milisegundos"; ms adelante veremos como ampliar esta funcionalidad. Por ahora veamos las convenciones que sigue esta clase: * El ao "y" est representado por un entero igual a ("y" - 1900). Por ejemplo el ao 2004 se representa como 104 (2004 - 1900). * Los meses son representados por nmeros entre 0 y 11, donde enero es 0 y diciembre es 11. * Los das y minutos se representan de forma corriente. Entre 1 - 31 y 0 - 59 respectivamente. * Las horas van entre 0 y 23, donde la medianoche es 0 y el medio da 12. * Los segundos van entre 0 y 61. 61 solo ocurre cuando se agrega el segundo adicional para ajustar la diferencia entre el reloj atmico y el tiempo de rotacin de la tierra. No sobra mencionar que los mtodos para obtener el ao, mes y da de esta clase ya estn obsoletos y lo nico que hacen es llamar a la clase java.util.Calendar para que esta se encargue de hacerlo (una delegacin). java.sql.Date: Esta clase hereda de java.util.Date y es la representacin de la fecha cuando trabajamos con JDBC (Java DabaBase Connectivity), es decir, son los campos almacenados en una base de datos cuyo tipo es una fecha que puede o no incluir la hora, aunque la clase java.sql.Date siempre lo hace. Al igual que su clase padre, tiene una precisin de milisegundos, con la excepcin que al mostrarla en la salida estndar con el formato por defecto solo muestra el da, mes y ao. Hay que anotar tambin que para campos que almacenen solamente horas existen otras clases para manejarlos. En resumen ambas clases, slo se encargan de almacenar la cantidad de milisegundos que han pasado desde las 12 de la noche del primero de enero de 1970 en el meridiano de Greenwich. Aqu vienen dos puntos importantes: a) Si la fecha que almacena cualquiera de las clases es menor a las 00:00:00 enero 1 de 1970 GMT, su valor el milisegundos ser negativo. b) La fecha es susceptible a la zona horaria. Por ejemplo en Colombia los milisegundos no se empiezan a contar desde enero 1 de 1970, sino a partir de las 19:00 de diciembre 31 de 1969. Esto es importante por que si transportamos una fecha relativa de una zona a otra, podemos llegar a tener problemas al confiar en los milisegundos que se tienen; adems como la clase intenta representar el "Tiempo Universal Coordinado" (UTC) suma 0.9 segundos cada ao para ajustar la diferencia entre el reloj atmico y la velocidad de rotacin de la tierra. Esto se traduce en que muy dificilmente podemos basarnos en valores como 0 o 60000 para realizar validaciones, pues esos milisegundos no son controlables cuando creamos la instancia de una fecha, peor an, los milisegundos no son ni siquiera iguales para la misma fecha en la misma zona horaria.

- 19 -

Estructura de Datos IDAT

Luis Arias Hidalgo

Ambas clases se pueden instanciar directamente mediante new(), pero la clase java.sql.Date necesita un parmetro en el constructor: el tiempo en milisegundos, as que las siguientes instrucciones son vlidas: java.util.Date fechaActual = new java.util.Date(); //Fecha actual del sistema java.sql.Date inicioLocal = new java.sql.Date(0); //Milisegundo cero //tambin se puede crear una instancia de java.util.Date con parmetros iniciales java.util.Date otraFecha = new java.util.Date(1000); //El primer segundo a partir del inicio Prueba a imprimir cada uno de estos valores y fjate en la diferencia de formatos entre java.sql.Date y java.util.Date. Se puede pasar de java.sql.Date a java.util.Date de dos fomas, una de ellas es con una asignacin simple: java.util.Date utilDate = null; java.sql.Date sqlDate = new java.sql.Date(0); utilDate = sqlDate; /* aunque es java.util.Date, si la imprimes tendr el formato de java.sql.Date, recordemos que java.sql.Date hereda de java.util.Date */ System.out.println(utilDate); Tambin se pueden tomar los milisegundos de java.sql.Date y pasarlos al constructor de java.util.Date: java.util.Date utilDate = null; java.sql.Date sqlDate = new java.sql.Date(0); utilDate = new java.util.Date(sqlDate.getTime()); //esta vez se mostrar con el formato de java.util.Date System.out.println(utilDate); Para pasar de java.util.Date a java.sql.Date se deben tomar los milisegundos de la primera y pasarlos al constructor de la segunda: java.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime()); //Con formato de java.sql.Date System.out.println(sqlDate); Para comparar fechas usamos el mtodo compareTo() que internamente compara los milisegundos entre ellas usando directamente los mtodos getTime() de ambas clases. java.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime()); if (utilDate.compareTo(sqlDate) == 0){ System.out.println("IGUALES"); }else{ System.out.println("DIFERENTES"); } O lo que es equivalente: java.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime()); if (utilDate.getTime() == sqlDate.getTime()){ System.out.println("IGUALES"); }else{ System.out.println("DIFERENTES"); } 2. Las clases Time y Timestamp. Ambas clases pertenecen al API JDBC y son la encargadas de representar los campos de estos tipos en una base de datos. Esto no quiere decir que no se puedan usar con otros fines. Al igual

- 20 -

Estructura de Datos IDAT

Luis Arias Hidalgo

que java.sql.Date, son hijas (heredan) de java.util.Date, es decir, su ncleo son los milisegundos. La clase Time es un envoltorio de la clase java.util.Date para representar los datos que consisten de horas, minutos, segundos y milisegundos, mientras Timestamp representa estos msmos datos ms un atributo con nanosegundos, de acuerdo a las especificaciones del lenguaje SQL para campos de tipo TIMESTAMP. Como ambas clases heredan del java.util.Date, es muy fcil pasar de un tipo de dato a otro; similar a la clase java.sql.Date, tanto Time como Timestamp se pueden instanciar directamente y su constructor tiene como parmetro el nmero de milisegundos; como es de imaginarse, cuando se muestra alguna de las clases mediante su mtodo toString() se ven los datos que intentan representar; La clase Time slamente muestra la hora, minutos y segundo, mientras timestamp agrega fracciones de segundo a la cadena. Para convertir entre tipos de datos diferentes debemos usar los milisegundos de una clase y asignarlos a las instancias de las otras, y como la clase java.util.Date es superclase de todas, a una instancia de esta podemos asignar cualquiera de las otras, manteniendo los mtodos de la clase asignada, es decir, si asignamos un Time a una java.util.Date, al imprimir se ver el mismo formato de la clase Time. Con este cdigo: java.util.Date utilDate = new java.util.Date(); //fecha actual long lnMilisegundos = utilDate.getTime(); java.sql.Date sqlDate = new java.sql.Date(lnMilisegundos); java.sql.Time sqlTime = new java.sql.Time(lnMilisegundos); java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(lnMilisegundos); System.out.println("util.Date: "+utilDate); System.out.println("sql.Date: "+sqlDate); System.out.println("sql.Time: "+sqlTime); System.out.println("sql.Timestamp: "+sqlTimestamp); Se obtiene la siguiente salida: util.Date: Thu May 20 19:01:46 GMT-05:00 2004 sql.Date: 2004-05-20 sql.Time: 19:01:46 sql.Timestamp: 2004-05-20 19:01:46.593 Note que an cuando todos los objetos tienen los mismos milisegundos el formato con el que se muestran dependen de la clase que realmente los contiene. Es decir, no importa que a un objeto del tipo java.util.Date se le asigne uno del tipo Time, al mostrar a travs de la consola se invocar el mtodo toString() de la clase time: utilDate = sqlTime; System.out.println("util.Date apuntando a sql.Time: ["+sqlTime+"]"); utilDate = sqlTimestamp; System.out.println("util.Date apuntando a sql.Timestamp: ["+sqlTimestamp+"]"); Arroja: util.Date apuntando a sql.Time: [19:29:47] util.Date apuntando a sql.Timestamp: [2004-05-20 19:29:47.468] Pero si en vez de solo apuntar, creamos nuevas instancias con los milisegundos los formatos con que se muestran son los mismos. Note que lo verdaderamente importante ocurre cuando creamos la instancia de java.util.Date usando los milisegundos del objeto sqlTime, pues aunque este ltimo nicamente muestra horas, minutos y segundos, siempre ha conservado todos los datos de la fecha con que se cre. utilDate = new java.util.Date(sqlTime.getTime()); System.out.println("util.Date con milisegundos de sql.Time: ["+utilDate+"]"); utilDate = new java.util.Date(sqlTimestamp.getTime()); System.out.println("util.Date con milisegundos de sql.Timestamp: ["+utilDate+"]"); Fjese en el formato de salida: util.Date con milisegundos de sql.Time: [Thu May 20 19:54:42 GMT-05:00 2004] util.Date con milisegundos de sql.Timestamp: [Thu May 20 19:54:42 GMT-05:00 2004]

- 21 -

Estructura de Datos IDAT

Luis Arias Hidalgo

Para finalizar esta primera entrega veamos el cdigo para mostrar la diferencia entre dos fechas en horas, minutos y segundos. Esta no es la mejor forma para hacerlo, pero cabe bien para mostrar de forma prctica todos los conceptos anteriormente estudiados. import java.util.HashMap; import java.util.Map; public class Prueba { public static Map getDiferencia(java.util.Date fecha1, java.util.Date fecha2){ java.util.Date fechaMayor = null; java.util.Date fechaMenor = null; Map resultadoMap = new HashMap(); /* Verificamos cual es la mayor de las dos fechas, para no tener sorpresas al momento * de realizar la resta. */ if (fecha1.compareTo(fecha2) > 0){ fechaMayor = fecha1; fechaMenor = fecha2; }else{ fechaMayor = fecha2; fechaMenor = fecha1; } //los milisegundos long diferenciaMils = fechaMayor.getTime() - fechaMenor.getTime(); //obtenemos los segundos long segundos = diferenciaMils / 1000; //obtenemos las horas long horas = segundos / 3600; //restamos las horas para continuar con minutos segundos -= horas*3600; //igual que el paso anterior long minutos = segundos /60; segundos -= minutos*60; //ponemos los resultados en un mapa :-) resultadoMap.put("horas",Long.toString(horas)); resultadoMap.put("minutos",Long.toString(minutos)); resultadoMap.put("segundos",Long.toString(segundos)); return resultadoMap; } public static void main(String[] args) { //5:30:00 de Noviembre 10 - 1950 GMT-05:00 java.util.Date fecha1 = new java.util.Date(-604070999750L); //6:45:20 de Noviembre 10 - 1950 GMT-05:00 java.util.Date fecha2 = new java.util.Date(-604066478813L); //Luego vemos como obtuve esas fechas System.out.println(getDiferencia(fecha1, fecha2)); } }

- 22 -

Estructura de Datos IDAT


Diferencia entre fechas Fecha1: Fri Nov 10 05:30:00 GMT-05:00 1950 Fecha2: Fri Nov 10 06:45:21 GMT-05:00 1950 {segundos=20, horas=1, minutos=15}

Luis Arias Hidalgo

Notas: 1. Existe un error de un segundo, lo cual no sucede cuando trabajamos con fechas posteriores a 1970, Por qu?. 2. Este procedimiento funciona igual para todos los hijos de java.util.Date: java.sql.Date, java.util.Time y java.util.Timestamp. 3. Todos los ejemplos los hemos hecho creando nuevas instancias de las clases. He omitido el traer informacin desde una base de datos para no complicar el cdigo; pero todo lo que hemos hecho debe funcionar igual de ambas formas (con base de datos y usando constructores). En la prxima entrega veremos como realizar operaciones completas entre fechas utilizando las clases Calendar y GregorianCalendar.

Funciones Matematicas (Clase Math) La clase Math representa la librera matemtica de Java. Las funciones que contiene son las de todos los lenguajes, parece que se han metido en una clase solamente a propsito de agrupacin, por eso se encapsulan en Math, y lo mismo sucede con las dems clases que corresponden a objetos que tienen un tipo equivalente (Character, Float, etc.). El constructor de la clase es privado, por los que no se pueden crear instancias de la clase. Sin embargo, Math es public para que se pueda llamar desde cualquier sitio y static para que no haya que inicializarla. Si se importa la clase, se tiene acceso al conjunto de funciones matemticas estndar: Math.abs( x ) para int, long, float y double Math.sin( double ) Math.cos( double ) Math.tan( double ) Math.asin( double ) Math.acos( double ) Math.atan( double ) Math.atan2( double,double ) Math.exp( double ) Math.log( double ) Math.sqrt( double ) Math.ceil( double ) Math.floor( double ) Math.rint( double ) Math.pow( a,b ) Math.round( x ) para double y float Math.random() devuelve un double Math.max( a,b ) para int, long, float y double Math.min( a,b ) para int, long, float y double Math.E para la base exponencial Math.PI para PI

- 23 -

Estructura de Datos IDAT

Luis Arias Hidalgo

He aqu un ejemplo, Mates.java, de uso de algunas funciones de la clase Math: class Mates { public static void main( String args[] ) { int x; double rand,y,z; float max; rand = Math.random(); x = Math.abs( -123 ); y = Math.round( 123.567 ); z = Math.pow( 2,4 ); max = Math.max( (float)1e10,(float)3e9 ); System.out.println( rand ); System.out.println( x ); System.out.println( y ); System.out.println( z ); System.out.println( max ); } }

- 24 -

Estructura de Datos IDAT


Laboratorio 4 : Funciones y Metodos

Luis Arias Hidalgo

1. Construir una funcin que nos regrese el triple de cualquier nmero. 2. Construir un procedimiento que ordene ascendentemente 3 numeros y los muestre. 3. Escribir dos funciones Entrada() y Salida() que incluyan todas las operaciones de entrada de datos y salida. 4. Escribir una funcin "EsMultiplo" que sirva para determinar si un nmero es mltiplo de otra. 5. Disear una funcin "aMayusculas()" que convierta una cadena de texto en maysculas. 6. Escribir una funcin que intercambie el valor de dos variables ingresadas por pantalla. 7. Escribir un programa que imprima los caracteres ascii del 32 al 127. 8. Escribir una funcin que calcule la potencia de los parmetros ingresados. 9. Haga un programa java que pida un nmero, visualice sus al divisores, la cantidad de divisores y la suma de los mismos. 10. Construir una funcin que nos regrese la letra I o P si el nmero que recibi fue impar o par respectivamente. 11. Construir un programa que pida un nmero, calcule el factorial y muestre la suma de las cifras del factorial resultante. 12. Escribe una funcin llamada media2 que reciba dos reales y devuelva el real que representa la media aritmtica de ambos nmeros. Escribe luego un programa utilizando la funcin del ejercicio anterior que lea dos reales por teclado y devuelva la media aritmtica de ambos. 13. Escribe un procedimiento que escriba en pantalla los n primeros nmeros primos. El procedimiento recibe n como parmetro. Construye una funcin para ver si un nmero es primo o no, y usa esa funcin para construir el procedimiento. 14. Escribe una funcin que reciba un nmero como parmetro y devuelva el nmero que se obtiene al invertir el orden de los dgitos del nmero original. Por ejemplo, si la funcin recibe el nmero 356 devolver el nmero 653. 15. Construir un programa que emita una factura si el artculo es importado, una funcin lo graba con el 20% de IGV si es nacional, la misma funcin lo graba con el 15% de IGV si no lo es. 16. Crear un programa que tenga el siguiente men: a. b. c. d. e. Ingrese nombre Ingrese sexo (M,F) Ingrese Edad. Saludo (Buenos das Seor o Seorita , segn sea el caso ) Salir

17. Crear las siguientes opciones en un men a. Matemtica i. Volumen de un cubo ii. Volumen de una esfera b. Lenguaje i. Mostrar la longitud de una cadena ingresada. ii. Agregar a la frase introducida la cadena Hola como estas c. Salir

- 25 -