P. 1
Manual Java

Manual Java

|Views: 610|Likes:
Publicado porFelipe Ordenes Odi

More info:

Published by: Felipe Ordenes Odi on Nov 06, 2010
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

12/31/2012

pdf

text

original

1

Java:
del Grano a su Mesa
A
AAn
nnd
ddr
rre
ees
ss M
MMu
uun
nno
ooz
zz O
OO.
..







V Ve er rs si io on n 1 1. .3 3
Java: del Grano a su Mesa (Version 1.3)
Tabla de Contenidos

2
Tabla de Cont enidos

TABLA DE CONTENI DOS 2
I NTRODUCCI ÓN 3
AGRADECI MI ENTOS 4
CAPÍ TULO I : PRI NCI PI OS BÁSI COS DE J AVA 5
CAPÍ TULO I I : CONCEPTOS BÁSI COS 21
CAPÍ TULO I I I : ENTRADA Y SALI DA 26
CAPÍ TULO I V: ASI GNACI ONES, EXPRESI ONES Y TI POS DE DATOS 30
CAPÍ TULO V: MÉTODOS Y FUNCI ONES 33
CAPÍ TULO VI : CONDI CI ONALES 37
CAPÍ TULO VI I : CI CLOS DE PROGRAMA 44
CAPÍ TULO VI I I : CADENAS DE TEXTO Y LI TERALES 48
CAPÍ TULO I X: PATRONES DE PROGRAMACI ÓN 56
CAPÍ TULO X: ARREGLOS Y MATRI CES 59
CAPÍ TULO XI : RECURSI VI DAD 69
CAPÍ TULO XI I : CLASES Y OBJETOS 72
CAPÍ TULO XI I I : ORDENAMI ENTO Y BÚSQUEDA 101
CAPÍ TULO XI V: ARCHI VOS DE TEXTO 121
CAPÍ TULO XV: I NTERFACES GRÁFI CAS AWT 127
CAPÍ TULO XVI : I NTERFACES GRÁFI CAS SWI NG 159
CAPÍ TULO XVI I : EXCEPCI ONES Y CONTROL DE ERRORES 160
CAPÍ TULO XVI I I : TI POS Y ESTRUCTURAS DE DATOS 177
CAPÍ TULO XI X: ARCHI VOS DE ACCESO ALEATORI O 214
CAPÍ TULO XX: BASES DE DATOS 221
CAPÍ TULO XXI : CONCURRENCI A 245
CAPÍ TULO XXI I : I NTERNETWORKI NG 254
CAPÍ TULO XXI I I : PAQUETES DE CLASES 291
CAPÍ TULO XXI V: DI SEÑO DE SOFTWARE UML 298
REFERENCI AS 324

Java: del Grano a su Mesa (Version 1.3)
Introduccion

3
I nt r oducción
Est e document o est á or ient ado al apoyo de per sonas que no t engan conocimient o con el
lenguaj e J ava, ni t ampoco con concept os de pr ogr amación.

Todos los capít ulos est án r ealizados con un f or mat o de clases, plant enado pr imer o una
mot ivación que gener alment e es un pr oblema que es deseable r esolver y que t iene su solución
con los concept os obt enidos a t r avés del capít ulo, luego el desar r ollo del t ema y por últ imo
algunos pr oblemas r esuelt os y pr opuest os par a pr act icar con los concept os obt enidos.

Como est á r ecopilado por clases de cát edr a de un pr of esor de la Univer sidad de Chile, exist e
una posibilidad que hayan inconsist encias ent r e los capít ulos, que ser án solucionados en
post er ior es ediciones de est e apunt e.

Su uso es liber ado a nivel académico, t ant o por alumnos del cur so de Comput ación I como
pr of esor es que deseen usar est e mat er ial como apoyo a sus clases.

También, la idea es dar más her r amient as en español par a aquellos pr ogr amador es inexper t os
que est án ingr esando en el mundo de J ava.

Java: del Grano a su Mesa (Version 1.3)
Introduccion

4
Agr adecimient os
A mi esposa, Ver ónica, quien compr endió et er nament e las lar gas noches en los cuales pr epar aba
las clases del año 2001, 2002 y 2003 (las que f alt aban).

Además, par a mis alumnos del cur so de CC10A – Comput ación I sección 03 del año 2001, de la
Escuela de I ngenier ía de la Univer sidad de Chile, quienes mot ivar on el desar r ollo del cont enido
de est e apunt e.

También a mis alumnos del cur so de CC10A – Comput ación I sección 03 del año 2002, gr acias a
quienes logr é mej or ar , complet ar inf or mación y compilar la en est e apunt e.

De maner a especial, agr adezco a Daniel Muñoz, quien me hizo r ef lexionar en el nombr e de est e
apunt e y cambiar lo desde su ver sión or iginal “J ava: Pr ogr amación y Lenguaj e” a “J ava: del
Gr ano a su Mesa”.

A Giselle, Pablo, Claudia y Mar ko quienes hici er on cont r ol de calidad de mi apunt e.

Por últ imo a los pr of esor es y alumnos quienes ut i lizan est e apunt e, ya que gr acias a ellos podr é
r ecibir coment ar ios y apor t es a mi cor r eo elect r ónico (andmunoz@dcc.uchile.cl) par a mej or ar
más aún su ayuda académica y comput acional.

A t odos, gr acias.

Andr és Muñoz O.
I ngenier o de Sof t war e
Pr of esor Univer sidad de Chile

Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

5
Capít ulo I : Pr incipios Básicos de J ava
Pr incipios Básicos
¿Qué es J ava?
J AVA es un lenguaj e de pr ogr amaci ón cr eado por SUN Micr osyst ems (ht t p:/ / www.sun.com),
muy par ecido al est ilo de pr ogr amación del lenguaj e “C” y basado en lo que se llama
Pr ogr amación al Obj ect o.
Pr ogr amación al Obj et o
Los pr incipios de l a pr ogr amación al obj et o es “modelar ” y r epr esent ar , a t r avés de element os
de pr ogr amación, obj et os que exist en en la r ealidad (t angible o int angibles). Por ej emplo, un
lenguaj e en donde se pueda modelar una calculador a con t odas las oper aciones que pueda
r ealizar .

Es así como se encapsula y r epr esent a un obj et o de la siguient e f or ma (not ación UML
1
):










Est e dibuj o r epr esent a las f unciones que uno puede r ealizar con una calculador a.

1
Unif ied Model Language: Un lenguaj e par a modelamient o or ient ado al obj et o que ver emos más
adelant e en el cur so.
Calculador a

Suma
Rest a
Mult iplica
Divide
...
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

6
Pr ogr amación en J ava
Los pr ogr amas en J ava son ar chi vos de t ext o planos con ext ensión .j ava (se ut iliza cualquier
pr ogr ama que escr iba ar chivos de t ext o como son el Not epad de Windows, Wor dpad, Text pad
e inclusive Wor d cuando guar da en f or mat o t ext o) que deben ser compilados con una J VM
(J ava Vir t ual Machine) y conver t idos en un ar chivo .class, con el cuál pueden ser ej ecut ados.






Los ar chivos .class son binar ios, por lo que no se pueden abr ir con ningún pr ogr ama.
Un Ar chivo J ava
Un ar chivo .j ava debe cont ener la siguient e est r uct ur a base:


// Area de inclusión de librerıas (package) [Opcional]
import <package>.*;

// Definición de la clase
[public] class <nombre de la clase> {
// Definición de métodos
[static] [public/protected/private] <tipo de dato> <nombre>
(<param1>, <param2>, ..., <paramN>) {
...
}
}

Clase
La est r uct ur a ant er ior ment e vist a la llamar emos Clase y r epr esent ar á algún obj et o o ent idad,
t angible o int agible que quer amos modelar .

En un pr incipio escr ibir amos clases que sean nuest r os Pr ogr amas Pr incipales, es decir , aquellos
que r esuelven los pr oblemas que nos plant eemos. Por ej emplo:


public class HolaMundo {
static public void main (String[] args) {
Console c = new Console();
c.println (”Hola Mundo¨);
}
}


Est a clase r epr esent a mi pr ogr ama llamado HolaMundo y solo escr ibe en pant alla la f r ase “Hola
Mundo”.


x.j ava x.class
Escr ibe Compila Ej ecut a
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

7
Tipos de Clases
Exist en 2 t ipos básicos de clases: Las clases ej ecut ables y las que no lo son.

La dif er encia ent r e est as 2 clases r adica f ísicament e en que algunas de ellas son invocadas
desde ot r as clases. Por ej emplo, Console es una clase (Console. class) que es invocada o
ut ilizada por la clase HolaMundo ant er ior ment e vist a.

Est a clase puede t ener muchos mét odos o f uncionalidades, que son ut ilizadas dent r o de los
ot r os pr ogr amas.


public class Console {
public void print(String s) { ... }
public void println(String s) { ... }
public int readInt() { ... }
public double readDouble() { ... }
public long readLong() { ... }
...
}


La clase HolaMundo es del t ipo que se puede ej ecut ar , es decir , al t ener el mét odo main
signif ica que lo que est á dent r o de los par ént esis de llave cor r esponde a lo ej ecut able:


public class HolaMundo {
static public void main (String[] args) { // EJECUTABLE
Console c = new Console();
c.println(”Hola Mundo¨);
}
}

I nst r ucci ones
Cada línea en J ava es conocida como una I nst r ucción, y signif ica que es lo que uno manda a
r ealizar al comput ador en un det er minado moment o. Por ej emplo:


c.println(”Hola Mundo¨); // Indica al computador que debe
// imprimir en pantalla la frase
// ”HOLA MUNDO¨


Todas las inst r ucciones llevan un separ ador al f inal: “;” (punt o y coma). Est e separ ador f unciona
como si se le indicar a al comput ador DONDE t er mina una línea, ya que J ava per mit e que en 1
línea f ísica escr ibir más de una inst r ucción:


c.print(”Hola¨); c.println(” Mundo¨);


Est a línea es equivalent e a:
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

8


c.print(”Hola¨);
c.println(” Mundo¨);


ya que el “;” indica el f in de inst r ucción.

También es nor mal que uno pueda escr ibir una inst r ucción en más de una línea f ísica, ya que el
“;” es nuest r o f in de inst r ucción:


c.println(”Hola” +
” Mundo¨);


Est as 2 línea son int er pr et adas por el comput ador como si f uesen una sola:


c.println(”Hola” + ” Mundo¨);


Bloques
En J ava se pueden agr upar las inst r ucciones en Bloques de inst r ucciones. Los bloques son
delimit ados por los par ént esis de llaves (“{“ y “}”).

Los mét odos son bloques de pr ogr amas que se ej ecut an al ser invocados:


static public void main (String[] args) {
Console c = new Console();
c.println(”Hola Mundo¨); BLOQUE
}


Las clases se componen de 2 par t es: un encabezado y un cuer po:


public class HolaMundo { ENCABEZADO
static public void main (String[] args) {
Console c = new Console();
c.println(”Hola Mundo¨); CUERPO
}
}


El cuer po de una clase es consider ado un bloque de pr ogr ama, ya que almacena múlt iples
bloques (mét odos) y ot r as inst r ucciones. Los bloques t ambién pueden almacenar ot r os bloques
como en est e caso.
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

9
Ej ecución de un Pr ogr ama J ava
Def inir emos plan de ej ecución a las líneas que r ealment e son leídas y ej ecut adas cuando uno
invoca la clase que desea cor r er .

La ej ecución de un pr ogr ama en J ava es lineal, y comienza SI EMPRE por el bloque de pr ogr ama
escr it o dent r o del mét odo main. Al moment o de ej ecut ar la clase, el bloque main comienza a
ej ecut ar . Luego se r ealizan las llamadas necesar ias a cualquier bloque o mét odo:


import java.io.*;

class ejemplo{
//este programa calcula el factorial de un numero.
static public int fact(int numero){
int factorial=1;

for(int i=1; i<numero; i++){
factorial=factorial*i;
}

return factorial;
}

static public void main(String args[]){
Console c=new Console();

c.print("Ingrese el numero a calcular: ");
int numero=c.readInt();

int factorial = fact(numero);

c.print("El factorial de:"+ numero+ " es:"+ factorial);
}
}


En est e ej emplo, el plan de ej ecución ser ía el siguient e:

1) . [ I NI CI O DEL PROGRAMA]
2) Console c=new Console();
3) c.pr int ("I ngr ese el numer o a calcular : ");
4) int numer o=c.r eadI nt ();
5) int f act or ial = [ r esult ado del bloque siguient e]
a) int f act or ial=1;
b) f or (int i=1; i <numer o; i++) [ r epit e el siguient e bloque]
i) f act or ial=f act or ial* i;
c) r et ur n f act or ial; [ devuelve el valor del bloque al 4]
6) c.pr int ("El f act or ial de:"+ numer o+ " es:"+ f act or ial);
7) . [ FI N DEL PROGRAMA]

Podemos not ar que la ej ecución es muy dist int a a el ór den en el cual se han escr it o las líneas de
código (inst r ucciones).
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

10
En la Pr áct ica
La idea es que ahor a que conocemos como se escr iben los pr ogr amas, podamos saber t ambién
como llegar a que se ej ecut en t ambién.

Qué necesit as par a pr ogr amar
Es muy necesar i o ut ilizar el J ava Develpment Kit (J DK) adecuado par a las necesidades que
t engas. Par a ef ect os del cur so, nosot r os ut ilizar emos el J DK 1.1.8 o 1.3.0, per o nada super ior a
eso, ya que l as f uncionalidades de la Console pueden ver se af ect adas por ot r as ver siones
2
.

El J DK es un compilador y ej ecut or de pr ogr amas J ava a t r avés de algo que se llama J ava
Vir t ual Machine (J VM) y que es como un comput ador per o que solo ent iende J ava.

Par a que t u comput ador t enga una J VM, es necesar io que descar gues el J DK y lo inst ales en t u
comput ador . En el caso de la escuela se encuent r a inst alado el J DK 1.3.0 y las f uncionalidades
se ven bast ant e bien, per o r ecomendamos que inst ales el J DK 1.1.8 o 1.2.2.

El J DK lo puedes descar gar de la página of icial de J ava de Sun Micr osyst ems
(ht t p:/ / j ava.sun.com) o desde la página de ayuda de la página del cur so.

Luego que lo t engas en t u comput ador , inst ala el sof t war e y “voila”. Con est o ya t ienes lo
necesar io par a comenzar t u avent ur a.

Como escr ibir un pr ogr ama
Par a escr ibir un pr ogr ama lo pr imer o que se necesit a es un edit or de t ext o. El mas simple y que
viene de maner a pr edet er minada con windows es Not epad (Bloc de Not as), per o cada quien es
libr e de usar el que mas le acomode (Ult r aEdit , Text pad, J olie, et c).

El icono de not epad se encuent r a en el menú: MENU I NI CI O è ACCESORI OS è Bloc de
Not as (Not epad)

Y el abr ir lo se ve una vent ana como la siguient e:


2
Si t e at r eves a pr obar en ot r a ver sión del J DK queda est r ict ament e baj o t u r esponsabilidad.
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

11

En est a vent ana se puede escr ibir el código de algún pr ogr ama. Por ej emplo el siguient e código
podemos escr ibir lo dent r o de Not epad, par a que pr obemos:

class ejemplo{
static public void main(String args[]){
Console c=new Console();

c.print("Ingrese el numero a calcular: ");
int numero=c.readInt();

int factorial=1;
for(int i=1; i<numero; I++){
factorial=factorial*i;
}

c.print("El factorial de:"+ numero+ " es:"+ factorial);
}
}

Que en not epad quedar ía como:

Luego, par a guar dar eso se debe ir al menú
Ar chivo/ Guar dar como…

Se guar da, par a ahor r ar conf usión, con el mismo
nombr e de la clase ( class ej emplo{…} ).

Las comillas aquí son necesar ias o de lo
cont r ar io el ar chivo se guar dar a con el nombr e
como: ej emplo. j ava. t xt cosa que est a muy mal
por que no podr emos ut ilizar lo como pr ogr ama
J ava.
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

12

Exist en ot r os edit or es que puedes usar . Algunos conocidos son los llamados I DE. La mayor ía
debes pagar los, per o puedes encont r ar ver siones en la int er net . Est os son:

§ I BM Visual Age f or J ava
§ Bor land J Builder
§ Sun For t e
§ J ade
§ J Cr eat or (La ver sión Limit ed Edit ion es gr at is)
§ J olie (un desar r ollo gr at is del pr of esor Kur t Schwar ze)

Algunos edit or es de t ext o que pueden ayudar mar cando color es y est r uct ur a son:

§ Text pad
§ Ult r aEdit

Como compilar un pr ogr ama
Una vez guar dado el pr ogr ama debemos asegur ar nos que nuest r o CLASSPATH est e apunt ando
cor r ect ament e a las libr er ías de J ava. Par a ello debemos abr ir una vent ana de MS-DOS y
poner :

set CLASSPATH = . ; C: \ j dk1. 1. 8\ lib

el dir ect or io j dk1. 1. 8 es, en est e caso, la ver sión de J ava que inst alamos. Si t u ver sión es la
1.2.2, deber ías cambiar lo en el CLASSPATH.

Después debemos colocar los 4 ar chivos que usan la consola en el mismo dir ect or io que el
pr ogr ama que hemos escr it o llamado ej emplo. j ava:


Console.class
ConsoleCanvas.class
Message.class
Fat alEr r or .class






Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

13
Luego debemos abr ir una vent ana de MS-DOS y colocar nos en el dir ect or io donde se encuent r a
nuest r o ar chivo ej emplo.j ava mediant e el comando “cd”. Ej emplo:

Una vez ubicados en el dir ect or io llamamos al comando compilador del pr ogr ama:


El cual, si t odo est a bien, y gener alment e no lo est a (kar ma comput in), gener ar a el ar chivo
ej emplo.class que cont endr á el pr ogr ama ya compilado, es decir , en un lenguaj e que el
comput ador si puede compr ender .

Si t odo est á bien, volver á a most r ar la línea de comando sin poner nada en pant alla:

C: \ WI NDOWS\ Deskt op\ t emp>

y en el dir ect or io donde est án los pr ogr amas, gener ar el ar chivo ej emplo. class.
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

14

En caso de que no se ej ecut e el comando j avac, es pr obable que sea o por que j ava no est a
inst alado en el comput ador , o por que nuest r o PATH, no apunt a al dir ect or io donde est a el
comando j ava. En est e caso, deber ás poner lo siguient e y volver a compilar :

set PATH = %PATH%;C:\ j dk1.1.8\ bin

Como ej ecut ar un pr ogr ama.
Una vez compilado el pr ogr ama y ahor a que t enemos el ar chivo “ej emplo.class”, podemos
pr oceder a ej ecut ar lo. Aquí suelen ocur r ir cosas inesper adas, per o con paciencia t ambién se
pueden ar r eglar .

Lo cual ej ecut ar á el pr ogr ama ej emplo. Debemos hacer hincapié en que el nuevo comando se
llama j ava, y no j avac (j avac ó j ava compiler ), y que no se ej ecut a: “j ava ej emplo.class”, sino
que solament e “j ava ej emplo”.
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

15
Los Er r or es en J ava
Lo más común cuando escr ibimos pr ogr amas en J ava es que t engamos er r or es. Exist en 2 t ipo
de er r or es: de compi lación y de ej ecución:
Er r or es de Compilación
Los er r or es de compilación son aquellos que salen cuando est amos compilando (usando j avac)
nuest r o ar chivo .j ava. Por ej emplo, veamos el siguient e pr ogr ama con er r or es:

clas EjemploDeError {
static void main (String[] args) {
Console c = new Console();
c.println ("Aquı le falta un punto y coma")
c.println ("Esta lınea está ok");
}
}

Nót ese que hemos deliber adament e puest o clas en vez de class en la def inición de la clase, y
en la línea 4 hemos dej ado sin ; al f inal de ella. También no hemos puest o las clases de la
consola par a que veamos qué ocur r e.

Si lo escr ibimos y lo int ent amos compilar en j ava obt endr emos el siguient e er r or :

C:\WINDOWS\Desktop\temp>javac EjemploDeError.java
EjemploDeError.java:1: 'class' or 'interface' expected
clas EjemploDeError {
^
1 error

C:\WINDOWS\Desktop\temp>_

En gener al, los er r or es de compilación son aquellos que son causados por un pr oblema en la
sint axis o que no dependen de los valor es de var iables, mét odos e ingr esos de dat os que
ocur r an al moment o de ej ecut ar .

Al ver est e caso podemos decier inmediat ament e que “clas” est á mal escr it o. De hecho el
compilador nos lo dice:

Ej emploDeEr r or . j ava: 1 I ndica el ar chivo y el númer o de la línea del er r or .
‘class’ or ‘int er f ace’ expect ed Ést e es el er r or .

El que nos salió en est e moment o nos dice que “esper aba un class o int er f ace”, lo que signif i ca
que esper aba la palabr a “class” que es clar ament e el er r or en que incur r imos. Lo que est á abaj o
de la pr imer a línea de er r or es la línea y est á mar cado el inicio de la palabr a que est á mal
escr it a:

clas EjemploDeError { Esta es la lınea errada.
^ Indica dónde está el error en la lınea.

Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

16
Si lo cor r egimos y lo volvemos a compilar , el er r or cambiar á:

C:\WINDOWS\Desktop\temp>javac EjemploDeError.java
EjemploDeError.java:4: ';' expected
c.println ("Aqui le falta un punto y coma")
^
EjemploDeError.java:3: cannot resolve symbol
symbol : class Console
location: class EjemploDeError
Console c = new Console();
^
EjemploDeError.java:3: cannot resolve symbol
symbol : class Console
location: class EjemploDeError
Console c = new Console();
^
3 errors

C:\WINDOWS\Desktop\temp>_

Ahor a t enemos 3 er r or es (como dice la últ ima línea). 2 de ellos ocur r en por causa de la Console
(2º y 3º) y ot r o ocur r e por f alt a del ;.

EjemploDeError.java:4: ';' expected
c.println ("Aqui le falta un punto y coma")
^

El pr imer er r or nos dice que en la línea 4 esper aba que hubier a un “;” al f inal de la línea. Est e
er a el pr oblema que habíamos dej ado par a pr obar .

EjemploDeError.java:3: cannot resolve symbol
symbol : class Console
location: class EjemploDeError
Console c = new Console();
^
EjemploDeError.java:3: cannot resolve symbol
symbol : class Console
location: class EjemploDeError
Console c = new Console();
^

En los ot r os dos casos apar ece la f r ase “cannot r esolve symbol” y dest acando la palabr a
“Console”. Est o ocur r e por que no encuent r a el ar chivo Console. class en el CLASSPATH, es
decir , o no est á def inido el CLASSPATH como i ndicamos ant er ior ment e o f alt an las clases.

Cor r ij amos t odos los er r or es y veamos como queda:

C:\WINDOWS\Desktop\temp>javac EjemploDeError.java

C:\WINDOWS\Desktop\temp>_

Lo que signif ica que f ue compilado sat isf act or iament e.
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

17
Er r or es de Ej ecución
Los er r or es de ej ecución cr eo que son los más dif íciles de j ust if icar y t ambién los más
complej os de leer en J ava. El int ér pr et e de j ava
3
ej ecut a un pr ogr ama y al moment o de
encont r ar un er r or (que no f ue det ect ado por el compilador ) lo envía a pant alla en f or ma de
Excepción (Except ion).

Las excepciones son algo súmament e delicado, ya que pueden dar nos dolor es de cabeza como
nos pueden salvar la vida en ot r os casos, ya que se pueden manipular , a dif er encia de ot r os
lenguaj es de pr ogr amación. Est o lo ver emos más adelant e en el cur so.

Veamos un pr ogr ama ej emplo que t enga er r or es de ej ecución:

class EjemploDeError {
static void main (String[] args) {
Console c = new Console();
c.println (”Ingresa una letra?¨);
int x = c.readInt();

String s = "Un texto";
c.println(s.charAt(-1));
}
}

En est e caso hay 1 er r or obvio que est á en el char At (- 1), ya que no se puede sacar un valor
menor a 0 de un st r ing, per o veamos el ot r o que puede ocur r ir t ambién. Si ej ecut amos est e
pr ogr ama nos sale en pant alla:

Ingresa una letra?_

Si nosot r os hacemos caso e ingr esamos “a” ocur r e:

Unable to convert to int

Est o nos dice que est á mal lo que int ent amos ingr esar y el pr ogr ama se pega y debemos
pr esionar Cont r ol-Cen la vent ana de MS-DOS que invocamos “j ava Ej emploDeEr r or ”.

Pr obemos ahor a ingr esando un númer o (cor r ect ament e) par a que caiga en la ot r a línea:

C:\WINDOWS\Desktop\temp>java EjemploDeError
Exception in thread "main"
java.lang.StringIndexOutOfBoundsException: String index out of
range: -1
at java.lang.String.charAt(Unknown Source)
at EjemploDeError.main(EjemploDeError.java:7)

y nuevament e debemos pr esionar Cont r ol-C par a t er minar la ej ecución del pr ogr ama. Ahor a
t enemos algo dist int o al er r or de conver sión, per o igualment e una excepción que debemos
int er pr et ar .

3
El I nt ér pr et e de J ava (Linker ) es quien se encar ga de ej ecut ar el .class en la J VM.
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

18

Si not amos bien en la línea (ya que por t ema de espacio, las 3 pr imer a líneas son en r ealidad 1
sola) est a nos indica qué ocur r ió:

j ava. lang. St r ingI ndexOut Of BoundsExcept ion Tipo de excepción que ocur r ió.
St r ing index out of r ange Pequeña descr ipción de la excepción.
- 1 Valor que causó la excepción.

Con est os valor es podemos per cat ar nos que el er r or ocur r ió por que t r at é de acceder con el –1
f uer a del r ango de un St r ing.

Sigamos más abaj o. Lo que sigue es llamado St ack de Ej ecución y nos indica cuánt os mét odos
hemos llamado desde que se ej ecut ó el pr imer main. Su lect ur a es de abaj o hacia ar r iba,
comenzando por el main en la últ ima línea y acabando por el mét odo más int er no en la pr imer a.

También, cada línea nos indica en qué ar chivo y línea ocur r ió el er r or .

En est e caso, el st ack es:

at java.lang.String.charAt(Unknown Source)
at EjemploDeError.main(EjemploDeError.java:7)

Si lo analizamos det enidament e (de ar r iba hacia abaj o) dice:

a) Se cayó en el mét odo char At de la clase j ava. lang. St r ing.
b) No t enemos el código f uent e de esa clase.
c) El que llamó a char At es el main de la clase Ej emploDeEr r or .
d) El ar chivo que posee est a clase es Ej emploDeEr r or . j ava.
e) La línea que est á haciendo est a invocación es la línea 7.

Por lo que si vamos a la línea 7 del ar chivo encont r ar emos:


c.println(s.charAt(-1));


que es exact ament e el pr oblema que quer íamos encont r ar .

Más adelant e en el cur so ut ilizar emos las excepciones como un apoyo a la pr ogr amación en J ava
al moment o de incur r ir en er r or es de ej ecución.
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

19
Pr incipios Avanzados
Uso de PUBLI C/ PROTECTED/ PRI VATE:
Est as sent encias (que pueden est ar en las f ir mas de los mét odos o en las def iniciones de las
clases) nos indican el nivel de "PRI VACI DAD" que t iene la clase.

METODOS:
La pr ivacidad (a nivel de mét odos) indica desde DONDE puedo llamar un mét odo. Es decir :

§ PUBLI C: Lo puedo llamar desde cual quier par t e (clases dent r o del mismo dir ect or io o de
ot r o dir ect or io).
§ PROTECTED: Solo las clases "hij as" pueden llamar lo (concept o de her encia más avanzado
que ver emos luego).
§ PRI VATE: Solo la misma clase que lo def ine puede llamar lo.
§ Sin nada: Par a las clases del mismo dir ect or io es pública, es decir la pueden llamar . Desde
ot r o dir ect or io no exist e.

Est as palabr as no son OBLI GATORI AS, ya que por def inición si no ponemos nada, es accesible.

CLASES:
A nivel de clases, la pr i vacidad se r ef lej a casi de la misma f or ma que los mét odos. Es decir :

§ PUBLI C: Se puede ut ilizar est a clase desde cualquier lugar . OBLI GA a guar dar la clase en
un ar chivo con el MI SMO NOMBRE (oj o con las mayúsculas y minúsculas):


public class Ejemplo {
...
}


se debe guar dar en Ej emplo.j ava y no en ej emplo.j ava.

§ Sin nada: Se puede ut ilizar en el mismo dir ect or io. Aquí el nombr e del ar chivo J AVA no
impor t a, es decir :


class Ejemplo {
...
}


se puede guar dar en Ej emplo.j ava, ej emplo.j ava o mipr ogr ama.j ava
Java: del Grano a su Mesa (Version 1.3)
Capitulo I: Principios Basicos de Java

20
Uso de STATI C:
El uso de STATI C en los mét odos solo nos explica cuando ut ilizamos un "OBJ ETO" o cuando
ut ilizamos una "CLASE" par a invocar el mét odo.

OBJ ETO:
Un obj et o es una var iable de un t ipo Clase que es cr eada con un new:


Console c = new Console();


en est e caso "c" es un obj et o de t ipo "Console". Todos los mét odos de la clase Console est án
declar ados sin la palabr a STATI C, por ej emplo, la f ir ma de "pr int ln" ser ía:


public void println(String s) {
...
}


y es por est a r azón que necesit amos al obj et o "c" par a invocar lo como:


c.println("Esto usa un objeto");


CLASE:
Las llamadas a mét odos que se r ealizan a t r avés del nombr e de la clase REQUI EREN la palabr a
"st at ic" en su def inición. Por ej emplo, en la clase Mat h t enemos el mét odo:


public static double random() {
...
}


y como posee el "st at ic", su invocación ser ía del t ipo:


double x = Math.random();

Java: del Grano a su Mesa (Version 1.3)
Capitulo II: Conceptos Basicos

21
Capít ulo I I : Concept os Básicos
Mot ivaci ón

Escr ibir un pr ogr ama que inst r uya al comput ador par a que est ablezca el siguient e diálogo con
una per sona (usuar io):

Por favor ingresa un Né: 123
Gano yo con el 124

Concept os
Algor it mo
Se def ine como “Algor it mo” a la ser ie de pasos o “Et apas” (que debe
r ealizar el comput ador ) par a r esolver un pr oblema

En el pr oblema plant eado ar r iba, un “algor it mo” par a r esolver lo se descr ibe a cont inuación:

1. Escr ibir (most r ar ) en la pant alla la f r ase “Por f avor ingr esa un N°: ”
2. Leer (obt ener , r ecuper ar ) el n°ingr esado por la per sona usando el t eclado.
3. Escr ibir en la pant alla:
• “Gano yo con el “
• el númer o (ingr esado por la per sona en el paso 2) sumándole uno.
4. Ter minar el pr ogr ama
Comput ador
Usuar io
COMPUTACI ON
• Algor it mos y Est r uct ur as de Dat os
• Lenguaj es de Pr ogr amación
• I ngenier ía de Sof t war e
• Comunicación Humano-Comput ador
• Comput ación Numér ica y Si mbólica
• Bases de Dat os
• I nt eligencia Ar t if icial
• Ar quit ect ur a de Comput ador es
• Sist emas Oper at i vos
Pr oblemas Soluciones
Razonamient os:
• algor ít mico
• lógico
• capacidad par a r esolver
pr oblemas
Java: del Grano a su Mesa (Version 1.3)
Capitulo II: Conceptos Basicos

22
Pr ogr ama
Tr aducción de un “Algor it mo” en un lenguaj e de pr ogr amación que el
comput ador pueda int er pr et ar par a r esolver el pr oblema.

Par a ef ect os de est udio en est e cur so, el lenguaj e de pr ogr amación ut ilizado par a int er pr et ar
nuest r os algor it mos es J ava.

Tr aduzcamos el algor it mo que def inimos par a el pr oblema inicial y veamos como queda en
lenguaj e J ava:

C.print(”Por favor ingresa un N°:¨);

int n;
n = C.readInt();

C.print(”Gano yo con el ”);
C.print(n+1);

Par a compr ender mej or el lenguaj e, ir emos línea a línea analizando qué signif ica y cómo se
ut ilizó par a t r aducir el algor it mo ant er ior .

C. pr int (“ Por f avor ingr esa un N°: ” );
• Escr ibe en la pant alla la f r ase encer r ada ent r e comi llas (“ ” ).
• C es un obj et o que r epr esent a la consola (pant alla y t eclado) del comput ador .
• pr int es un mét odo (f unción) que se aplica al obj et o C y que escr ibe su ar gument o
en la pant alla.
int n;
• Declar a n como una var iable ent er a.
• Var iable
• Repr esent ación si mbólica de un valor (númer o).
• Repr esent a una ubicación (celda) en la memor ia del comput ador .
• Posee un nombr e que la ident if ica (let r a seguida de lat r as, dígit os o _).
• Capacidad: un valor del t ipo indicado.
• int indica que el t ipo de númer o que puede almacenar la var iable es un ent er o
(númer os sin punt o decimal).
n = C. r eadI nt ();
• Lee un númer o ent er o desde el t eclado y lo asigna (guar da) a (en) la var iable n.
• r eadI nt () es un mét odo (f unción sin ar gument os) que:
• Esper a que el usuar io ingr ese un númer o (t ecleando dígit os y ENTER).
• Lee (obt iene, r econoce) el númer o.
• Ent r ega (r et or na) el númer o como r esult ado.
• Par a abr eviar las dos líneas ant er ior es se puede ut ilizar int n = C. r eadI nt ();
C. pr int (“ Gano yo con el “ );
• Escr ibe en la pant alla la f r ase “Gano yo con el”.
C. pr int (n+1);
• Escr ibe en la pant alla el valor de la var iable n más uno.
• n+1 Expr esión ar it mét ica (n: var iable, 1: const ant e, +: oper ador ).
Java: del Grano a su Mesa (Version 1.3)
Capitulo II: Conceptos Basicos

23
• Oper ador es Ar it mét icos válidos:
• Adición: (+)
• Subst r acción: (- )
• Pr oduct o: (* )
• Cuocient e: (/ )
• Par a abr eviar las dos líneas ant er ior es se puede ut ilizar C. pr int (“ Gano yo con el “
+ (n+1));
• (+) : Est e oper ador se convier t e en un concat enador (añade) de car act er es.
• Mej or a: C. pr int ln(“ Gano yo con el “ + (n+1)); escr ibe y después posiciona el
cur sor al comienzo de la siguient e línea en la pant alla

Con est os concept os, se pueden r ealizar muchos más pr ogr amas que est e sencillo ej emplo. La
mayor cant idad de los pr oblemas plant eados a la comput ación se basan en est a básica
int er acción ent r e usuar io-comput ador , par a hacer la sencilla y que el comput ador pueda obt ener
la inf or mación necesar ia par a r esolver el pr oblema.
Solución al Pr oblema
Una solución complet a al pr oblema plant eado, la cual ser ía f ácilment e pr obada en el
labor at or io, se pr esent a a cont inuación.

// Jalisco: programa que nunca pierde
import java.awt.*;
class Jalisco {
static public void main(String[] args) {
Console C = new Console();
C.print(”Por favor ingresa un N°:¨);
int n = C.readInt();
C.println(”Gano yo con el ”+ (n+1));
}
}

De la misma f or ma que en la ant er ior explicación se pr esent ó, se det alla línea a línea la
ej ecución del pr ogr ama con la t r aducción que el comput ador r ealiza.

/ / J alisco: pr ogr ama que nunca pier de
• Coment ar io hast a el f inal de la línea.
• El comput ador no t r aduce est a línea, puest o que es solo una línea inf or mat iva y no
inf luye en la ej ecución del pr ogr ama.

impor t j ava. awt . * ;
• I nser t a declar aciones necesar ias par a que pr ogr ama lea/ escr iba
class J alisco {…}
• Def ine la clase de nombr e J alisco.
• Todo pr ogr ama J ava debe est ar cont enido en una clase.
st at ic public void main(St r ing[ ] ar gs) {…}
• Mét odo que cont iene inst r ucciones del pr ogr ama pr incipal ( main).
• Encabezamient o est ándar (signif icados se explicar án post er ior ment e).
Console C = new Console();
Java: del Grano a su Mesa (Version 1.3)
Capitulo II: Conceptos Basicos

24
• Abr e una vent ana par a leer y escr ibir .
• C: obj et o de clase Console.
• Console: clase de int er acción pr edef inida con mét odos par a leer y ecr ibir .
Pr oblemas
Escr ibir un pr ogr ama que est ablezca el siguient e diálogo.

Calcular perımetro y area de circulo
Diametro ? 3
Perimetro = ...
Area = ...
Solución 1.
Est a solución consider a que el diámet r o es un númer o ent er o y que PI es un númer o r eal:

// Se declara la constante pi
final double pi = 3.1416;

// Se crea una Consola para entrada y salida de datos
Console C = new Console();

// Se obtiene el valor del diámetro del cırculo
C.println(”Calcular perımetro y area de circulo¨);
C.print(”Diametro ? ¨);
int d = C.readInt();

// Se calcula y despliega los resultados de la operación
C.println(”Perımetro = ¨ + (pi * d));
C.println(”Area = ¨ + ( pi * Math.pow(d/2, 2));
Solución 2
Est a solución consider a que el diámet r o es un númer o r eal y que PI es un númer o r eal:

// Se declara la constante pi
final double pi = 3.1416;

// Se crea una Consola para entrada y salida de datos
Console C = new Console();

// Se obtiene el valor del diámetro del cırculo
C.println(”Calcular perımetro y area de circulo¨);
C.print(”Diametro ? ¨);
double d = C.readDouble();

// Se calcula y despliega los resultados de la operación
C.println(”Perımetro = ¨ + (pi * d));
C.println(”Area = ¨ + ( pi * Math.pow(d/2, 2));

Los r esult ados que se obt ienen par a el per ímet r o son iguales, sin embar go par a el ár ea son
complét ament e dist int os:

Caso d ent er o:
Perımetro = 9.4248
Java: del Grano a su Mesa (Version 1.3)
Capitulo II: Conceptos Basicos

25
Area = 3.1416
Caso d r eal:
Perımetro = 9.4248
Area = 7.0686

Est e f enómeno ocur r e nor malment e en J ava, puest o que al oper ar un cuocient e (caso que puede
dar un r esult ado con deci males) con ambos valor es ent er os, el r esult ado SI EMPRE ser á ent er o.

Por ej emplo: 3 / 2 = 1 ent er o
3 / 2.0 = 1.5 r eal
Pr oblemas Pr opuest os
1. Pr ogr ama par a el siguient e diálogo

Calcular perımetro y area de rectángulo
Largo ? 2
Ancho ? 3
Perımetro = ...
Area = ...

2. Diseñar el diálogo y escr ibir un pr ogr ama que calcule la velocidad de un móvil en km/ hor a,
dadas la dist ancia (en met r os) y el t iempo ( en segundos).

3. I nvent ar un pr oblema, diseñar el diálogo y escr ibir .
Java: del Grano a su Mesa (Version 1.3)
Capitulo III: Entrada y Salida
26
Capít ulo I I I : Ent r ada y Salida
Mot ivaci ón
La I / O (Ent r ada/ Salida) est ándar es, por def inición, cómo se comunica nat ivament e J ava con
el usuar io.

Es así como clases hechas como Console evit an que uno conozca r ealment e donde est á el
ingr eso de dat os y el despliegue de ellos en la pant alla o int er f az (gr áf ica de t ext o) que J ava
pr ovee. De hecho, Console es un Applet que ut iliza un Canvas en donde se escr iben las líneas de
t ext o par a la salida est ándar y que per mit e el ingr eso de dat os a t r avés del t eclado, par a luego
pasár selo a los pr ogr amas que la ut ilizan.
Sint axis
Clase Console
4

Est a clase es simplement e un encapsulamient o de la Ent r ada y Salida est ándar de J ava. En
est e document o se ut il iza la mayor par t e de los capít ulos por simplicidad, no obst ant e la
ut ilización de Syst em par a ent r ada y salida est ándar t ambién se det alla en caso de desear
ut ilizar la.

Le def inición de Console per mit e r ealizar las siguient es f uncionalidades:

Mét odo Descr ipción
public Console();
public Console(St r ing);
public Console(int ,int , St r ing);
Const r uct or es de la clase Console por def ect o,
con t ít ulo, y con t amaño y t ít ulo
r espect ivament e.
public int maxcol();
public int maxr ow();
Obt ener el t amaño de columnas y f ilas que puede
cont ener la consola abier t a.
public void clear (); Limpiar la consola.
public void showCur sor ();
public void hideCur sor ();
Most r ar y ocult ar el cur sor .
public void pr int (St r ing);
public void pr int ln(St r i ng);
I mpr imir en la consola.
public boolean r eadBoolean();
public byt e r eadByt e();
public shor t r eadShor t ();
public int r eadI nt ();
public long r eadLong();
public double r eadDouble();
public f loat r eadFloat ();
Leer un valor desde el t eclado ut ilizando la
consola.

4
Ver ht t p:/ / www.holt sof t .com/ j ava/ hsa_package.ht ml# Console par a mayor inf or mación.
Java: del Grano a su Mesa (Version 1.3)
Capitulo III: Entrada y Salida
27
public char r eadChar ();
public St r ing r eadSt r ing();
public St r ing r eadLine();
public void set Font (Font );
public void set Text Backgr oundColor (Color );
public void set Text Color (Color );
Dar t ipogr af ía (Font ) y color al t ext o de la
consola
5
.

Y t ambién exist en f or mas de ut ilizar la como un lienzo gr áf ico par a dibuj ar
6
:

Mét odo Descr ipción
public int maxx();
public int maxy();
Obt ener t amaño del lienzo.
public void set Color (j ava.awt .Color ); Dar color al pincel.
public void clear Rect (int , int , int , int ); Limpiar un t r ozo del lienzo.
public void copyAr ea(int , int , int , int , int , int ); Copiar un t r ozo del lienzo.
public void dr aw3DRect (int , int , int , int , boolean);
public void dr awAr c(int , i nt , int , int , int , int );
public void dr awLine(int , int , int , int );
public void dr awMapleLeaf (int , int , int , int );
public void dr awOval(int , int , int , int );
public void dr awPolygon(int [ ] , int [ ] , int );
public void dr awRect (int , int , int , int );
public void dr awRoundRect (int , int , int , int , int , int );
public void dr awSt ar (int , int , int , int );
public void dr awSt r ing(St r ing, int , int );
public void f ill3DRect (int , int , int , int , boolean);
public void f illAr c(int , int , int , int , int , int );
public void f illMapleLeaf (int , int , int , int );
public void f illOval(int , int , int , int );
public void f illPolygon(int [ ] , int [ ] , int );
public void f illRect (int , int , int , int );
public void f illRoundRect (int , int , int , int , int , int );
public void f illSt ar (int , int , int , int );
Dibuj ar t odo t ipo de f igur as.
Clase Syst em
En algún lado ya se ha ut ilizado la clase Syst em, la cual se basa en una ser ie de f uncionalidades
est át icas (def inidas como st at ic) que per mit en int er act uar nat ivament e ent r e el sist ema y el
usuar io (o los per if ér icos que t enga). Por ej emplo:

Syst em. out es un obj et o que posee una r ef er encia a la pant alla de salida est ándar de J ava.


5
Par a ver cómo f uncionan los color es, r ef er ir se a Canvas en página 151.
6
Par a ver cómo f uncionan algunos de los mét odos gr áf icos, ver sección Canvas en página 151.
Java: del Grano a su Mesa (Version 1.3)
Capitulo III: Entrada y Salida
28
Ahondando en est e ej emplo, Syst em. out posee las f uncionalidades de impr imir en pant alla que
han t r ascendido a obj et os como la Console o Pr int Wr it er :

• Syst em. out . pr int ln(. . . ): I mpr ime en pant alla lo que est á ent r e par ént esis (lit er al o
expr esión) y salt a una línea después de hacer lo.
• Syst em. out . pr int (. . . ): I mpr ime en pant alla lo que est á ent r e par ént esis (lit er al o
expr esión) per o sin salt ar la línea al f inal.

Por ej emplo, lo que con Console imit aba el siguient e diálogo:

Hola mucho gusto.

er a:

Console c = new Console();
c.println(”Hola mucho gusto¨);

con Syst em. out es mucho más sencillo: al ser una var iable est át ica de la clase Syst em, no
necesit a de una r ef er encia a dicha clase:

System.out.println(”Hola mucho gusto¨);

Bast ant e sencillo. Veamos ahor a como se leen dat os con Syst em.

El caso de ent r ada de dat os es más complej o y es lo que lleva a los pr ogr amador es a cr ear
obj et os como Console. Es decir , no es t an senci llo como poner :

System.in.readInt(); // ESTO ESTA MALO

Aunque les gust ar ía mucho. J

Syst em. in es una r ef er encia est ándar a la ent r ada desde el t eclado. Sin embar go su uso es un
poco dist int o, per o similar a lo que pasa con los ar chivos de lect ur a, ya que t ambién son
ent r adas, est o es:

BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));

Est a línea r eemplazar ía a la declar ación de la consola en el caso de ut ilizar Console. Es decir , lo
que ant es imit aba a:

Cómo te llamas? Juan
Hola Juan, mucho gusto

y que con Console quedaba más o menos así:

Console c = new Console();
c.print(”Como te llamas?¨);
Java: del Grano a su Mesa (Version 1.3)
Capitulo III: Entrada y Salida
29
String nombre = c.readLine();
c.println(”Hola ” + nombre + ”, mucho gusto¨);

Ahor a cambiar ía un poquit o como:

BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
System.out.print(”Como te llamas?¨);
String nombre = in.readLine();
System.out.println(”Hola ” + nombre + ”, mucho gusto¨);

Hey, no es t an dist int o. Per o el cambio viene al t r abaj ar con númer os, ya que Buf f er edReader
solo puede leer líneas de t ext o, por lo que mét odos r eadI nt y r eadDouble quedan
complet ament e f uer a de lugar . Solo se puede ut ilizar r eadLine() y leer solo St r ings (hay que
hacer un cast o conver sión explícit a
7
).
Pr oblema Pr opuest o
Tenemos el siguient e pr ogr ama desar r ollado con Console:

Console c = new Console();

while (true) {
c.print(”Pregunta: ”);
String p = c.readLine();
c.print(”Respuesta: ”);
switch (p.charAt(0).toUpperCase()) {
case ”A¨:
c.println(”Si, toda la razón¨);
case ”E¨:
c.println(”No es cierto¨);
case ”I¨:
c.println(”Es muy probable¨);
case ”O¨:
c.println(”Nunca¨);
case ”U¨:
c.println(”Siempre¨);
default:
c.println(”Quizás¨);
}
}

Tr at e de conver t ir est e código par a que ut ilice Syst em. out y Syst em. in como ent r ada y salida
de dat os

7
Conver siones St r ing > int y St r ing > double.
Java: del Grano a su Mesa (Version 1.3)
Capitulo IV: Asignaciones, Expresiones y Tipos de Datos

30
Capít ulo I V: Asignaciones, Expr esiones y Tipos de Dat os
Mot ivaci ón
Nos gust ar ía mucho r ealizar el cálculo de por cent aj es de elección de 2 candidat os inst r uyendo
al comput ados par a que est ablezca el siguient e diálogo con el usuar io:

Calcular porcentajes
Votos candidato 1? _
Votos candidato 2? _
Total de votos = N–
Candidato 1 = xxx %
Candidato 2 = xxx %
Concept o
A cont inuación har emos las def iniciones básicas necesar ias par a comenzar con los concept os de
pr ogr amación y que nos ser án út iles a t r avés del cur so:
Expr esión
Es una combinación de oper ador es, var iables y const ant es del lenguaj e
que, al ser evaluada, per mit e la obt ención de un valor r eut ilizable en
ot r o lugar del pr ogr ama.

Par a ver clar ament e est o, la siguient e línea es una expr esión:

((6 * a) – (5 + b) / c) * x
2


La evaluación de las expr esiones sigue las mismas r eglas del álgebr a. Est as son:

1. Expr esiones Par ent izadas
2. Oper ador es Unar ios
3. Oper ador es Mult iplicat ivos (* , / )
4. Oper ador es Adit ivos (+, -)

Y en el caso de exist ir oper ador es de igual pr ior idad, se evalúan de izquier da a der echa.
Asignación
La asignación es una inst r ucción en la cual el comput ador da un valor
par a ser almacenado dent r o de una var iable o espacio de memor ia f ísica.

La sint axis de una asignación es:

<variable> = <expresión>;

En donde:
Java: del Grano a su Mesa (Version 1.3)
Capitulo IV: Asignaciones, Expresiones y Tipos de Datos

31

<expr esión> se escr ibe en una línea (hacia el lado) y no en var ios niveles. La compr enden
var iables, const ant es, oper ador es binar ios (+, -, * , / ), oper ador es unar ios (+, -), mét odos y
expr esiones ent r e par ént esis. Ant es de ser asignada a una var iable, est a expr esión es
EVALUADA y el valor obt enido r eside en el espacio r eser vado de memor ia par a dicha var iable.

Por ej emplo, podemos r ealizar las siguient es asignaciones

a = v1 + v2;
a = (5 - a) * 3 / v1;
a = 2;
Tipos de Dat os
Son def iniciones de espacios de memor ia en los cuales se almacenan
valor es específ icos.

Est a def inición es bast ant e t écnica, por lo que simplif icar emos un poquit o a la siguient e
def inición de t ipo de dat o:

Es una clase de númer os (o dat os) con los cual es se pueden def inir las
var iables que los almacenar án.

En J ava exist en los t ipos de dat os numér icos:

Tipo Nº Bit s Mayor Valor Menor Valor Pr ecisión (dígit os)
Byt e 8 127 -128 3
Shor t 16 32.767 -32.768 5
I nt 32 2.147.483.647 -2.147.483.648 10
Long 64 2
63
– 1 -2
63
19
Float 32 3,4 x 10
38
-3,4 x 10
38
7
Double 64 1,7 x 10
301
-1,7 x 10
301
15

Par a def inir o declar ar una var iable con cier t o t ipo, se debe ut ilizar la siguient e sint axis:

<tipo de dato> <nombre de la variable>;

en donde

<nombr e de la var iable> es un nombr e cualesquier a que le per mit a ident if icar a ese espacio
de memor ia separ ado par a el t ipo de dat o indicado.

Por ej emplo:

int i;
i = 5;
Java: del Grano a su Mesa (Version 1.3)
Capitulo IV: Asignaciones, Expresiones y Tipos de Datos

32
Conver sión de Dat os
Par a conver t ir t ipos de dat os se usa un CAST explícit o o implícit o que
t r ansf or ma, convier t e y/ o t r unca desde un t ipo de dat o a ot r o.

Los cast implícit os se pueden hacer desde t ipos de más pequeño t amaño (ver t abla) hacia t ipos
más gr andes. Por ej emplo:

int a = 6;
double b = a; // Cast implıcito

Los cast explícit os se deben hacer desde t ipos de más gr ande t amaño (ver t abla) hacia t ipos
más pqueños. Por ej emplo:

double a = 10.0;
double b = (double) a; // Cast explıcito
Solución
Console c = new Console();
c.println(”Calcular porcentajes¨);

c.print(”Votos candidato 1¨);
int v1 = c.readInt();

c.print(”Votos candidato 2¨);
int v2 = c.readInt();

int total;
total = v1 + v2;

c.println(”Total de votos = ” + total);
c.println(”Candidato 1 = ” + 100.0*v1/total);
c.println(”Candidato 2 = ” + 100.0*v2/total)


Java: del Grano a su Mesa (Version 1.3)
Capitulo V: Metodos y Funciones
33
Capít ulo V: Mét odos y Funciones
Mot ivaci ón
Exist en muchas f unciones mat emát icas y no mat emát icas en J ava que se encuent r an pr e-
def inidas. Est as f unciones est án escr it as par a que los pr ogr amador es las ut ilicen en sus
códigos sin volver a escr ibir los subpr ogr amas que r ealizan esas f uncionalidades.
Concept o
Funciones/ Mét odos
Tr ozos de código que pueden ser r eut ilizados a t r avés de una llamada a
su def inición con cier t os par ámet r os. También r eciben el nombr e de
Mét odos.

En J ava por ej emplo exist e una gr an libr er ía mat emát ica que incluye mét odos par a la r aíz
cuadr ada, pot encias, exponenciales, logar it mos, senos, cosenos, t angent es, máximos, mínimos,
r edondeo de valor es y númer os aleat or ios.
I nvocación o Llamada de un Mét odo
La llamada es la f or ma en que el lenguaj e invoca o per mit e la ej ecución
del t r ozo de código escr it o dent r o de un mét odo. En gener al, r equier e
de un nombr e (del mét odo) y sus par ámet r os (si es que t iene).

Par a que veamos como se invocan los mét odos, veamos aquellos que se encuent r an en la libr er ía
mat emát ica:

Función Signif icado Tipo
Ar gument o
Tipo
Result ado
Ej emplo Result ado
sqr t (x) √ x, x ≥ 0 double double sqr t (4.0) 2.0
abs(x) | x| i, l, f , d del ar g abs(-3) 3
pow(x,y) x
y
d d pow(2.0,3) 8.0
exp(x) e
x
d d exp(1) Mat h. E
8

log(x) logex d d log(Mat h.E) 1.0
sin(x) seno de <x
(x en r adianes)
d d sin(Mat h.PI / 2) 1.0
cos(x) coseno de <x d d cos(Mat h.PI ) -1.0
t an(x) t angent e de <x d d t an(Mat h.pi/ 4) 1.0
asin(x) ar co-seno de x d d asin(1.0) Mat h. PI
9
/ 2
acos(x) ar co-coseno de x d d acos(-1.0) Mat h. PI

8
Mat h.E est á def inida en la libr er ía mat emát ica.
9
Mat h.PI est á def inida en la libr er ía mat emát ica.
Java: del Grano a su Mesa (Version 1.3)
Capitulo V: Metodos y Funciones
34
Función Signif icado Tipo
Ar gument o
Tipo
Result ado
Ej emplo Result ado
at an(x) ar co-t angent e de x d d at an(1.0) Mat h. PI / 4
r ound(x) r edondear x d, f l, i r ound(4.5) 5L
f loor (x) n / n ≤ x <n+1 d d f loor (4.9) 4.0
ceil(x) n / n-1 <x ≤n d d ceil(4.1) 5.0
max(x,y) mayor ent r e x e y i,l,f ,d de ar g max(4.1, 6.5) 6.5
min(x,y) menor ent r e x e y i,l,f ,d de ar g min(4.1, 6.5) 4.1
r andom( ) Nº al azar en [ 0,1[ d r andom( ) 0.x...

Veamos unos ej emplos de ut ilización de f unciones de la libr er ía mat emát ica:

// Cálculo de Area y Perımetro
c.print(”Ingrese el radio de la circunferencia?¨);
double r = c.readDouble();

c.print(”El perımetro de la circunferencia es: ¨);
c.println(2 * Math.PI * r);
c.print(”El area de la circunferencia es: ”);
c.println(Math.PI * Math.pow(r, 2));

En est e ej emplo podemos ver como ut ilizamos un mét odo de la clase mat emát ica dent r o de una
expr esión.

// Cálculo de un radio a partir del área
c.print(”Ingrese ahora un Area de circunferencia?¨);
double a = c.readDouble();

c.print(”El radio de la circunferencia es: ”);
c.println(Math.sqrt(a / Math.PI));

En est e ej emplo podemos ver como se puede ut ili zar una expr esión como ar gument o de un
mét odo de la clase mat emát ica.

// Cálculo de la tangente a partir de otras funciones
c.print(”Ingrese un ángulo en radianes? ”);
double ang = c.readDouble();

c.print(”La tangente original es: ”);
c.println(Math.tan(ang));

c.print(”La tangente calculada es: ”);
c.println(Math.sin(ang)/Math.cos(ang));

En est e ej emplo podemos ver que se pueden componer en una misma expr esión dist int o
mét odos mat emát icos sin necesidad de ut ilizar var iables adicionales.

Java: del Grano a su Mesa (Version 1.3)
Capitulo V: Metodos y Funciones
35
Mot ivaci ón
Quisiér amos escr ibir t r ozos de código que per mit an r ealizar las oper aciones básicas de la
ar it mét ica (sumar , r est a, división y mult iplicación), par a ut ilizar los a dist int os niveles.

Es por eso que nos gust ar ía cr ear una est r uct ur a de pr ogr amación que nos per mit a almacenar
subpr ogr amas pr e-hechos par a ser ut ilizados dent r o de nuest r os pr opios pr ogr amas.
Concept o
Declar ación de un Mét odo
La declar ación de un mét odo es la escr it ur a del subpr ogr ama que
r esuelve la f uncionalidad del mismo.

La f or ma gener al de declar ación de un mét odo es la siguient e:

static <tipo> <nombre> (<arg1>, <arg2>, ...) {
<instrucciones>
return <valor de retorno>;
}

En donde:

<t ipo> Tipo de dat o del valor que se r et or na al f inal de la ej ecución del mét odo.
<nombr e> Nombr e con el cuál es ident if icado el mét odo.
<ar gn> Ar gument o n-ésimo del mét odo. Puede t ener ent r e 0 y cualquier númer o
de ar gument os.
<inst r ucciones> Tr ozo de código que se pr ocesa dur ant e la ej ecución del mét odo.
<valor de r et or no> Valor que r et or na el mét odo a su línea llamador a y que es r esult ado del
pr ocesamient o r ealizado en el t r ozo de código o cuer po del mét odo.

La combinación ent r e t ipo, nombr e y ar gument os se le llama Fir ma del Mét odo.

Por ej emplo, def inamos un mét odo que r et or ne el valor de una r aíz quint a:

static double raizQuinta (double x) {
return Math.pow(x, 1/5);
}

y su llamada ser á (en negr it as):

double rq = raizQuinta(26);
Solución
Con est o def inido, podemos escr ibir el código de los mét odos de la segunda mot ivación:

Java: del Grano a su Mesa (Version 1.3)
Capitulo V: Metodos y Funciones
36
static double suma (double a, double b) {
return a + b;
}

static double resta (double a, double b) {
return suma(a, -b);
}

static double multiplica (double a, double b) {
return a * b;
}

static double division (double a, double b) {
return multiplica (a, 1/b);
}

Y par a ut ilizar est a diver t ida ver sión es:

double val1 = 5;
double val2 = 10;

c.println (val1 + ” + ” + val2 + ” = ” + suma (val1, val2));
c.println (val1 + ” - ” + val2 + ” = ” + resta (val1, val2));
c.println (val1 + ” * ” + val2 + ” = ” + multiplica (val1, val2));
c.println (val1 + ” / ” + val2 + ” = ” + division (val1, val2));
Pr oblema
Escr ibir una f unción que calcule el máximo de 3 númer os y ot r a el mínimos de 3 númer os r eales.

static double max3 (double val1, double val2, double val3) {
return Math.max(val1, Math.max(val2, val3));
}

static double min3 (double val1, double val2, double val3) {
return Math.min(val1, Math.min(val2, val3));
}

Desaf íat e: Saca ahor a el de en medio
Pr opuest o
Escr ibir una f unción que calcule el númer o aleat or io ent r e una cot a inf er ior x y ot r a cot a
super ior y. Es decir , que t enga la siguient e f ir ma:

static int aleatorio (int x, int y)

el r esult ado ∈ [ x, y]

Java: del Grano a su Mesa (Version 1.3)
Capitulo VI: Condicionales
37
Capít ulo VI : Condicionales
Mot ivaci ón
Escr ibir subpr ogr amas que r ealicen los oper aciones de adición y cuocient e de númer o r eales,
consider ando que no se puede dividir por 0.
Algor it mo
Veamos pr imer o el algor it mo par a la adición a modo de pr áct ica:

1. Recibir los valor es de los sumandos dent r o del subpr ogr ama (llamada del mét odo).
2. Guar dar t empor alment e el valor de la suma de los valor es obt enidos en la llamada.
3. Ret or nar el r esult ado guar dado en el paso 2.

Par a est e algor it mo no hay pr oblema de escr ibir la solución:

static double suma (double a, double b) {
double r = a + b;
return r;
}

Una ver sión alt er nat iva y avanzada ser ía:

static double suma (double a, double b) {
return a + b;
}

Ok. Veamos el algor it mo par a la división:

1. Recibir los valor es de los oper andos del cuocient e.
2. Ver if icar si el dividendo es igual a 0
a. Ret or nar 0 (indicando que er a 0 par a que no haya er r or )
3. Guar dar t empor alment e el valor de la división de los valor es obt enidos en la llamada.
4. Ret or nar el r esult ado guar dado en el paso 3.

Como podemos ver , necesit amos algo que nos per mit a ej ecut ar (a) solo si el dividendo es 0.
Concept o
Condi cionales
Un condicional es una inst r ucción que per mit e ej ecut ar un t r ozo de
código si y solo si cumple con una condición o valor de ver dad.

Java: del Grano a su Mesa (Version 1.3)
Capitulo VI: Condicionales
38
El concept o de condicional es bast ant e básico. Las condiciones son expr esiones que r et or nan
valor es de ver dad (ver dader o o f also) y que condicionan la ej ecución de inst r ucciones indicadas
en el condicional.

Algo como:

Si la condición es cierta
Ejecuta las instrucciones cuando es cierta
Si no es cierta
Ejecuta estas otras instrucciones.
Sint axi s
Los condicionales ut ilizan un comando especial llamado if . . . else. Su f or ma gener al es como
sigue:

if (<condición>) {
<instrucciones si es verdadero>
}
else {
<instrucciones si es falso>
}

La pr imer a par t e del condicional cor r esponde a la condición, la segunda par t e (o else)
cor r esponde a decir “si la condición NO se cumple” o el f amoso “si no” o “de lo cont r ar io”. Est a
segunda par t e es opcional.

Ant es de cont inuar , debemos inser t ar dos nuevos concept o:
Valor de Ver dad
Todos saben cuál es la def inición e est e concept o. Así que abor dar emos un nuevo t ipo de dat o
que sopor t a almacenar est o: bolean.

El bolean es un t ipo de dat o especial que solo puede almacenar VERDADERO o FALSO. Por
ej emplo:

boolean var1 = true;
boolean var2 = false;

Es sumament e sencillo. La gr acia es que se puede usar como condición sola en un if . Por
ej emplo:

if (var1)
...
else
...
Java: del Grano a su Mesa (Version 1.3)
Capitulo VI: Condicionales
39
Oper ador es Lógicos
Un oper ador lógico es un compar ador que per mit e oper ar valor es,
var iable o expr esiones y r et or nar un valor de ver dad (ver dader o o
f also).

Exist e muchos oper ador es lógicos que descr ibir emos a cont inuación:

Compar ador de Valor es Numér icos: Per mit e compar ar valor es numér icos indicando si es
mayor , menor , mayor o igual, menor o igual, dist int o o simplement e igual.

A > 5 OPERADOR MAYOR QUE
A < 3 OPERADOR MENOR QUE
A >= 1 OPERADOR MAYOR O IGUAL QUE
A <= 0 OPERADOR MENOR O IGUAL QUE
A == 4 OPERADOR IGUAL QUE
A != 4 OPERADOR DISTINTO QUE

Oper ador de Negación: Est e oper ador per mit e NEGAR un valor de ver dad, es decir cambiar
el valor de VERDADERO a FALSO o de FALSO a VERDADERO.

! (A == 5) SE TRADUCE POR A != 5

Conj unciones: Son oper ador es especiales que per mit en unir dist int os valor es de ver dad.
Hablando un poco en español ser ía como el Y y el O (bueno, son eso).

A > 5 && A < 10 A mayor que 5 y menor que 10
A < 9 || A > 10 A menor que 9 o mayor que 10

Un ej emplo que ut iliza t odo lo ant er ior ser ía condicionar si es par o impar un númer o:

c.print(”Número?¨);
int n = readInt();
if ( n % 2 == 0 ) {
c.println(n + ”Es par¨);
}
else {
c.println(n + ”Es impar¨);
}

Est o es muy f ácil de visualizar . Veamos un ej emplo más complej o consider ando 3 casos
dist int os:

c.print(”Número?¨);
int n = readInt();
if ( n > 0 ) {
c.println(n + ” es mayor que 0¨);
}
else if ( n < 0 ) {
c.println(n + ” es menor que 0¨);
}
else {
c.println(n + ” es igual que 0¨);
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo VI: Condicionales
40


En est e ej emplo podemos ver 3 casos y como se pueden mezclar los dist int os if ... else.

Por últ imo un ej emplo sencillo de que hacer solo si se cumple la condición:

c.print(”Número?¨);
int n = readInt();
if ( n == 123 ) {
c.println( ”BINGO¨);
}

En est e últ imo ej emplo podemos ver que el ELSE er a complet ament e opcional.
Solución
La solución con est e concept o se pone muuuuy sencilla y queda como:

static double division (double a, double b) {
if (b == 0) {
return 0;
}
double r = a / b;
return r;
}

También, podemos ut ilizar una solución alt er nat iva como:

static double division (double a, double b) {
double r;
if (b == 0) {
r = 0;
}
else {
r = a / b;
}
return r;
}

O una muy similar , per o algo mas int eligent e:

static double division (double a, double b) {
double r = 0;
if (b != 0) {
r = a / b;
}
return r;
}
Caso Especial
Hay un pr oblema muy clar o, cuando se ut ilizan muchos I F par a dist inguir dist int os t r ozos con
compar ador es de igualdad. Por ej emplo:

Java: del Grano a su Mesa (Version 1.3)
Capitulo VI: Condicionales
41
c.print(”Opcion?¨);
int op = c.readInt();

if (op == 1)
<instrucciones 1>
else if (op == 2)
<instrucciones 2>
else if (op == 3)
<instrucciones 3>
else if (op == 4)
<instrucciones 4>
else if (op == 5)
<instrucciones 5>
else if (op == 6)
<instrucciones 6>
else
<instrucciones 7>

Al obser var con det ención est o, se puede t or nar engor r oso, pues si indent ár amos quedar ía
r ealment e asquer oso. Exist e una inst r ucción que nos puede salvar : swit ch.

c.print(”Opcion?¨);
int op = c.readInt();

switch op {
case 1:
<instrucciones 1>
break;
case 2:
<instrucciones 2>
break;
case 3:
<instrucciones 3>
break;
case 4:
<instrucciones 4>
break;
case 5:
<instrucciones 5>
break;
case 6:
<instrucciones 6>
break;
case:
<instrucciones 7>
break;
}

en donde los case deben t ener valor es const ant es (es decir , que no sean var iables).
Pr oblemas
(a) Se desea escr ibir un mét odo que calcula la r aíz n-ésima de un númer o consider ando que
solo se pueden calcular r aíces par a númer os >0 (caso de r aíces par es). La f ir ma del mét odo
es:

public st at ic double r aizN (double base, int r aiz)

Java: del Grano a su Mesa (Version 1.3)
Capitulo VI: Condicionales
42

public static double raizN (double base, int raiz) {
if (raiz % 2 = 0 && base < 0)
return 0; // Indica que no se puede calcular

return Math.pow(base, 1/raiz);
}


(b) Escr iba un pr ogr ama que imit e el siguient e diálogo:

Escriba el número que desea obtener raız? _
Indique la raız? _

La raız <n-esima> del número es = XXXX.XXX

Consider e que el t ér mino “<n-ésima>” debe indicar :

§ “cuadr ada” si la r aíz es 2
§ “cuar t a” si la r aíz es 4
§ “quint a” si la r aíz es 5
§ “n-ésima” en cualquier ot r o caso, r eemplazando “n” por el valor de la r aíz


import java.io.*;

public class Raices {

// Aquı se inserta el método raizN
public static double raizN (double base, int raiz) {
if (raiz % 2 = 0 && base < 0)
return 0; // Indica que no se puede calcular

return Math.pow(base, 1/raiz);
}

// Programa principal (solución parte b)
public static void main (String[] args) {
Console c = new Console(”Raices¨);

// Se imprime en pantalla el diálogo
c.print(”Ingrese el número que desea obtener raiz?¨);
double x = c.readDouble();

c.print(”Ingrese la raiz?¨);
int n = c.readInt();

// Se calcula la raiz
double raiz = raizN(x, n);

// Se escribe el resultado
switch r {
case 2:
c.print(”La raız cuadrada ¨);
case 4:
c.print(”La raız cuarta ¨);
case 5:
c.print(”La raız quinta ¨);
case:
Java: del Grano a su Mesa (Version 1.3)
Capitulo VI: Condicionales
43
c.print(”La raız ” + n + ”-ésima ¨);
}
c.println(” del número es = ” + raiz);
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo VII: Ciclos de Programa
44
Capít ulo VI I : Ciclos de Pr ogr ama
Mot ivaci ón
Escr iba un pr ogr ama que per mit a calcular el valor de la hipot enusa de t r iángulos con los valor es
de los cat et os dados por el usuar io, según la f ór mula de pit ágor as.

a
2
+ b
2
= c
2


Par a ello, t r at e de r ealizar el siguient e diálogo:

Cálculo de la Hipotenusa de un Triángulo

Triángulo 1
a?_
b?_
Hipotenusa = ...

Desea Continuar (1=Si/2=No)? _ Suponemos que pone 1

Triángulo 2
a?_
b?_
Hipotenusa = ...

Desea Continuar (1=Si/2=No)? _ Suponemos que pone 2

Se han calculado 2 triángulos
Gracias por usar el programa
Algor i t mo:
1. Escr ibir t ext o de bienvenida en pant alla
2. I niciar cont ador del nº de t r iángulos calculados en 1
3. I niciar ciclo de pr ogr ama
4. Escr ibir t ext o “Tr iángulo” con el valor del t r iángulo (1)
5. Pedir y almacenar cat et o “a”
6. Pedir y almacenar cat et o “b”
7. Calcular e escr ibir en pant alla el valor de la hipot enusa del t r iángulo (1)
8. I ncr ement ar el cont ador
9. Escr ibir en pant alla la pr egunt a “Desea Cont inuar (1=Si/ 2=No)?”
10. Pedir y almacenar el r esult ado a la pr egunt a del punt o 9
11. Si el usuar io ingr esa 1, volver al punt o 4 par a el t r iángulo (cont ador +1)
12. Escr ibir en pant alla la cant idad de t r iángulos calculados
13. Escr ibir en pant alla “Gr acias por usar el pr ogr ama”

Est e algor it mo se ve un poco más lar go de lo común, per o lo más impor t ant e son l os it ems 3 y 11
dest acados, por que est o def inen un ciclo.
Java: del Grano a su Mesa (Version 1.3)
Capitulo VII: Ciclos de Programa
45
Concept os
Ciclo
Un Cicl o es un t r ozo de pr ogr ama que se r epit e según una Condición que
evaluada puede ent r egar ver dader a o f alsa.

En J ava exist e una inst r ucción par a r ealizar est e t ipo de código, y se llama While.
Sint axi s
while (<condición>) {
<trozo de código que se repite>
}

en donde:
<condición> Valor de ver dad que debe ser ver dader o par a que se ej ecut e el t r ozo
de código escr it o dent r o del while.

Por ej emplo, el siguient e código se r epit e mient r as (while) a sea mayor o igual a 0:

Console C = new Console();
int a = 10;
while (a >= 0) {
C.println(”Se repite este texto en pantalla¨);
a--; // esto es lo mismo que escribir a=a-1;
}

Ot r a f or ma de r epr esent ar un ciclo es con un f or (por o par a) que es más complet o que el
ant er ior :

for (<inicio>; <condición>; < incremento>) {
<trozo de código que se repite>
}

en donde:
<inicio> Es una inst r ucción que se ej ecut a solo al comenzar el f or .
<condición de salida> Es la condición que debe ser TRUE par a que el f or no t er mine.
<incr ement o> Es una inst r ucción que se ej ecut a cada vez que el ciclo es
r ealizado (en cada it er ación).

Por ej emplo, el siguient e código se r epit e por (f or ) 10 veces:

Console C = new Console();
for (int a=10; a>0; a--) {
C.println(”Se repite este texto en pantalla¨);
}

Obser va la equivalencia dir ect a ent r e el f or y el while de ej emplo, ya que ambos hacen
exact ament e lo mismo.
Java: del Grano a su Mesa (Version 1.3)
Capitulo VII: Ciclos de Programa
46
Solución
import java.awt.*;

public class Triangulos {
public static void main (String[] args) {
Console C = new Console();

C.println(”Cálculo de la Hipotenusa de un
Triángulo¨);

int respuesta = 1;

int contador = 1;
while (respuesta == 1) {
C.println(”Triángulo ” + contador);

C.print(”a?¨);
double a = C.readDouble();
C.print(”b?¨);
double b = C.readDouble();

C.println(”Hipotenusa = ” +
Math.sqrt(Math.pow(a, 2) +
Math.pow(b, 2))
);

contador++;

C.print(”Desea continuar (1=Si/2=No)?¨);
respuesta = C.readInt();
}

C.println(”Se han calculado ” + (contador - 1) +
Triángulos¨);
C.println(”Gracias por usar el programa¨);
}
}
Pr oblemas
(a) Escr ibir un pr ogr ama que pida al usuar io 2 númer o ent er os y que luego los mult iplique
ut ilizando SOLO sumas.

Not a: Recuer da que X por Y es lo mismo que sumar Y veces el valor de X. Se r ecomienda
que ut ilices un ciclo f or par a r esolver est e pr oblema

import java.awt.*;

public class Producto {
public static void main (String[] args) {
// Se crea la consola
Console c = new Console();

// Se piden los valores de los operandos
c.print(”Ingrese el operando X?¨);
int X = c.readInt();
c.print(”Ingrese el operando Y?¨);
int Y = c.readInt();

Java: del Grano a su Mesa (Version 1.3)
Capitulo VII: Ciclos de Programa
47
// Se calcula el producto entre X e Y como sumas
int producto = 0;
for (int i=1; i<=Y; i++) {
producto = producto + X;
}

// Se despliega el resultado
c.println(”X por Y = ” + producto);
}
}

(b) Pr opuest o. Haz lo mismo que en el pr oblema ant er ior (X por Y) per o ahor a consider ando las
pot enci as (X
y
) y ut ilizando solo PRODUCTOS. Recuer da que est a oper ación es lo mismo que
mult iplicar Y veces el valor de X.

(c) Desaf ío. ¿Puedes hacer lo mismo a b per o solo con sumas? Tr at a de hacer lo con t us
palabr as, y luego compár alo con la siguient e solución:

import java.awt.*;

public class Potencias {
public static int productoXY (int X, int Y) {
int producto = 0;
for (int i=1; i<=Y; i++) {
producto = producto + X;
}
return producto;
}

public static int potenciaXY (int X, int Y) {
int potencia = 0;
for (int i=1; i<=Y; i++) {
potencia = productoXY(X, X);
}
return potencia;
}

public static void main (String[] args) {
Console c = new Console();

c.print(”Ingrese la base X?¨);
int X = c.readInt();
c.print(”Ingrese el exponente Y?¨);
int Y = c.readInt();

c.println(”X elevado a Y = ” + potenciaXY(X, Y));
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo VIII: Cadenas de Texto y Literales
48
Capít ulo VI I I : Cadenas de Text o y Lit er ales
Mot ivaci ón
Hast a ahor a conocemos los númer os y t odo. Per o, ¿cómo ut ilizar las cadenas de car act er es?

Quer emos r ealizar el j uego del “r epondón” simulando el siguient e diálogo:

Hazme preguntas y YO respondo.
P? Esto es un entero
R: NO
P? Eres un computador
R: SI
P? Yo soy un usuario
R: NO
P? Sabes computación
R: SI
Concept o
Cadena de Text o
Las Cadenas de Text o son un gr upo de car act er es uno t r as ot r o y que
r epr esent an palabr as, f r ases u or aciones (gr amat icales) con y sin
sent ido.

Según est a def inición:
• “ Ana” es una Cadena de Text o.
• “ Yo soy genial” es una Cadena de Text o.
• “ 23499 ldslñññsdf ñ” t ambién es una Cadena de Text o.
Sint axi s
En J ava, las cadenas de t ext o t iene un nombr e especial y se llaman St r ing.

Exist en 2 t ipos de St r ings, los Lit er ales y los t ipos de dat o St r ing.

Lit er ales: Son aquellos St r ings, r epr esent ados por cadenas dent r o de comill as dobles (“ “), y
que r epr esent an f ielment e su cont enido. Por ej emplo:

c.print(”Este es un LITERALó);

Clar ament e el par ámet r o del mét odo pr int es un lit er al.

St r ing: Es un t ipo de dat o especial que per mit e almacenar lit er ales en var iables. Por ej emplo:

String a = ”Esta es una variable STRING¨;
c.print(a);
Java: del Grano a su Mesa (Version 1.3)
Capitulo VIII: Cadenas de Texto y Literales
49

Al igual que en el ant er ior ej emplo, pr int r ecibe en est e caso una var iable St r ing en vez de un
lit er al. Mucha at ención, que al inicializar una var iable St r ing, es necesar io hacer lo con un
LI TERAL.

Algunas f uncionalidades út iles de los St r ings son:
Concat enación de St r ings
Par a concat enar o j unt ar dos o más St r ings se ut i liza el oper ador ar it mét ico de adición (+). Por
ej emplo:

String a = Ӭ; // VACIO
a = a + ” primero¨
a = a + ” segundo¨
a = a + ” otro¨ + a + ”otro¨;

Est o concat enar ía al f inal en a la f r ase: “pr imer o segundo ot r o pr imer o segundo ot r o”.
Lect ur a de un St r ing desde el Teclado
Par a comenzar , debemos saber como leer un St r ing desde la ent r ada de dat os. Par a ello
ut ilizar emos el mét odo de la CONSOLA llamado r eadLine():

String a;
a = c.readLine();

Est e ej emplo guar dar ía lo ingr esado por el usuar io en la var iable a, sin impor t ar si son númer o o
let r as.

Al igual que los r eadI nt () y r eadDouble(), r eadLine() no posee par ámet r os y su f or ma gener al
ser ía la siguient e:
<var iable St r ing> = c. r eadLine();
Lar go de un St r ing
Es muy ut il conocer cuánt os car act er es posee un St r ing (var iable o lit er al). Par a ello exist en un
mét odo dent r o de la clase St r ing que se ut iliza, llamado lengt h:

String a = ”Hola mundo¨;
c.print (a + ” posee ” + a.length() + ” caracteres¨);

Est e ej emplo most r ar ía en la consola “Hola mundo posee 10 car act er es”

Como podemos ver en el ej emplo, l engt h se ut iliza con la var iable punt o el mét odo lengt h (sin
par ámet r os). Es decir :
<var iable St r ing>. lengt h();
Java: del Grano a su Mesa (Version 1.3)
Capitulo VIII: Cadenas de Texto y Literales
50
Obt ención de un Car áct er
Al igual que par a el lar go, exist e la f or ma de sacar 1 sola let r a del St r ing. Est o se r ealizar con
el mét odo de la clase St r ing char At (i) en donde i es el i -ésimo menos 1 car áct er de la cadena.
Por ej emplo:

String alfabeto = ”abcdefghijklmnopqrstuvwxyz¨;
c.println(”La letra 3 es ” + alfabeto.charAt(3));

Como podemos ver , est e ej emplo muest r a en la consola la f r ase: “La let r a 3 es d”. Ooooops.
¿Qué est á mal? No hay nada malo. Lo que pasa es que las posiciones comienzan desde 0, es
decir , si quier o la 5 let r a, est a ser ía alf abet o. char At (4) y no alf abet o. char At (5) como ser ía lo
común.

Su f or ma gener al queda como:
<var iable St r ing>. char At (<posición i>);
Búsqueda de un Car áct er o Text o
Par a buscar un t r ozo de t ext o o car áct er dent r o de ot r o se ut iliza el mét odo indexOf (“ t ext o”)
el cual r et or na la posición i -ésima menos uno (es decir r et or na el índice del car áct er cor r ect o
dent r o del St r ing). Por ej emplo:

String s = ”Texto contiene un ; dentro del cuerpo¨;
c.println(”En ” + s.indexOf(”;ó) + ” hay un punto y coma¨);

Est e ej emplo r et or na “En 18 hay un punt o y coma”. Per o si cont amos el númer o desde 1, es el
19avo car áct er .

Su f or ma gener al que busca la pr imer a ocur r encia de un t ext o, es:
<var iable St r ing>. indexOf (<t ext o buscado>);

Not a: Si el St r ing buscado no est á dent r o del St r ing s, la posición r et or nada es –1.

Exist en algunas var iant es de est é mét odo. Par a buscar una ocur r encia de un t ext o a par t ir de
una posición específ ica, se ut iliza:

<var iable St r ing>. indexOf (<t ext o buscado>, <posición a buscar >);

Con est o ent onces podemos buscar desde una posición específ ica. Por ej emplo:

String s = ”esta es una casa¨;
int n = s.indexOf(”es¨); // es lo mismo decir: s.indexOf(”es¨, 0)

Est o r et or na la posición 0, per o si buscamos desde ot r a posición

int n = s.indexOf(”es¨, 2);

Java: del Grano a su Mesa (Version 1.3)
Capitulo VIII: Cadenas de Texto y Literales
51
Ret or nar á la posición 5, por que a par t ir de la posición 2, la pr imer ocur r encia de “es” est á en la
posición 5.

Not a: Si ant eponemos la palabr a “last ” a ambas f or mas del mét odo, es decir , “ last I ndexOf ”,
podemos obt ener no la pr imer a ocur r encia, si no que la últ ima ocur r encia del t ext o buscado.
Obt ención de Tr ozos de un St r ing
Por últ imo par a la clase, ver emos como sacamos un t r ozo de un St r ing, es decir , algo como
sacar un pedacit o que nos sir va. El siguient e ej emplo sacar lo que va ent r e sext a y la undécima
posición es:

String s = ”Este string está completito¨;
String a = s.substring(5, 11);
c.println(a);

Est e ej emplo pone en pant alla la palabr a st r ing. Su f or ma gener al queda:

<var iable St r ing>. subst r ing(<pos inicial>, <pos f inal>);

Nót ese que NO I NCLUYE la posición f inal, es decir , saca hast a el últ imo car act er ant es de
<pos f inal>.

También exist e una f or ma adicional de usar lo y es sin indicar el lar go, es decir :

<var iable St r ing>. subst r ing(<pos inicial>);

De est a f or ma est ar íamos pidiendo desde la posición inicial hast a el f inal del St r ing.
Compar ación de St r ings
Los st r ings no pueden ser compar ados como los númer os con oper ador es lógicos t r adicionales.
Par a ello posee sus pr opios compar ador es, mét odos de la clase St r ing:

Exist en 2 mét odos que nos ayudan a compar ar st r ings:

<var iable St r ing 1>. equals(<var iable St r ing 2>);

Est e mét odo r et or na TRUE si los st r ings son EXACTAMENTE iguales (incluyendo mayúsculas y
minúsculas
10
). Si los st r ings dif ier en en algo (lar go o car act er es) el r esult ado es FALSE.

La ot r a f or ma compar a los st r ings según la t abla ASCI I :

<var iable St r ing 1>. compar eTo(<var iable St r ing 2>);

Est e mét odo r et or na

10
A est o se le llama Case
Java: del Grano a su Mesa (Version 1.3)
Capitulo VIII: Cadenas de Texto y Literales
52

- númer o >0 si el st r ing 1 es MAYOR que el st r ing 2
- 0 si el st r ing 1 es I GUAL que el st r ing 2
- númer o <0 si el st r ing 1 es MENOR que el st r ing 2

¿Cuándo un st r ing es mayor o menor que ot r o?

Un st r ing es mayor que ot r o cuando en el pr imer car act er que dif ier en, el car act er del st r ing 1
es mayor según ASCI I que el st r ing 2. Según la t abla ASCI I de valor es int er nacionales, que
r epr esent a cada car act er con un númer o ent er o ent r e 0 y 255, nos dice que:

- Los númer os (0 .. 9) se r epr esent an por códigos ent r e el 48 y 57 (r espect ivament e)
- Las mayúsculas (A .. Z) se r epr esent an por códigos ent r e el 65 y 90
- Las minúsculas (a .. z) se r epr esent an por código ent r e el 97 y 122
- Todos los demás car act er es poseen dist int os códigos

Ent onces, un car act er es mayor que ot r o cuando su código ASCI I es mayor .
Solución
Recor dando un poquit o t enemos que imit ar el diálogo siguient e:

Hazme preguntas y YO respondo.
P? Esto es un entero
R: NO
P? Eres un computador
R: SI
P? Yo soy un usuario
R: NO
P? Sabes computación
R: SI

Per o además, nos f alt a saber como r esponde el comput ador :

• Si la pr egunt a t er mina con vocal, el comput ador r esponde NO.
• En cualquier ot r o caso r esponde SI .

Ahor a veamos la solución:

Console c = new Console();
c.println(”Hazme preguntas y YO respondo:¨);
while (true) {
c.print(”P? ”);
String pregunta = c.readLine();
if (”aeiouó.indexOf(pregunta.charAt(pregunta.length()-1))>= 0)
c.println(”R: NO¨);
else
c.println(”R: SI¨);
}

Oooops. Cr eo que es demasiado complicado ver la línea del if por ent er o. Analicemos lo que
vamos haciendo paso a paso y separ ado por líneas dist int as (equivalent e al I F de ar r iba):
Java: del Grano a su Mesa (Version 1.3)
Capitulo VIII: Cadenas de Texto y Literales
53

// Obtenemos el largo del STRING
int L = pregunta.length();

// Calculamos el ultimo caracter del string
L = L - 1;

// Sacamos el último carácter
String ultimo = pregunta.charAt(L);

// Vemos si es vocal
int vocal = ”aeiou¨.indexOf(ultimo);
if (vocal >= 0) // Solo si ultimo es vocal
c.println(”R: NO¨);
else
c.println(”R: SI¨);
Pr oblemas
(a) Se desea escr ibir un pr ogr ama que solicit e una línea de t ext o al usuar io y que simplement e
la despliegue en f or ma inver sa, es decir , la de vuelt a.

// Primero, pediremos el texto al usuario
c.println(”Escribe un texto para invertir?¨);
String texto = c.readLine();

// Ahora tomamos el texto y lo invertimos
// guardándolo en una nueva variable
String invertido = ”¨; // Se inicia vacıo
for (int i=0; i<texto.length(); i++) { // Ciclo de recorrido texto
// Se va guardando al revés, caracter a caracter
invertido = texto.charAt(i) + invertido;
}

// Se muestra en pantalla
c.println(”El texto invertido es: ” + invertido);

Es muy impor t ant e not ar que est a no es la única solución posible, por que si somos ast ut os,
podemos ir most r ando en pant alla car act er a car act er en vez de ut ilizar una nueva var iable:

// Primero, pediremos el texto al usuario
c.println(”Escribe un texto para invertir?¨);
String texto = c.readLine();

// Ahora lo invertimos
for (int i=texto.length()-1; i>=0; i--) {
c.print(texto.charAt(i));
}

(b) Pr opuest o. Escr ibir un pr ogr ama que cuent e cuánt as palabr as son ver bos (en inf init ivo) en
un t ext o ingr esado por el usuar io. Recuer de que los inf init ivos t er minan TODOS en una
vocal + “r ”.

(c) Pr opuest o. ¿Podr ía escr ibir un mét odo que ent r egue aleat or iament e un St r ing de n
car act er es?. La f ir ma del mét odo es:

Java: del Grano a su Mesa (Version 1.3)
Capitulo VIII: Cadenas de Texto y Literales
54
public st at ic St r i ng t ext oAzar (int n);

Not a: Ut iliza un st r ing que t enga TODAS las let r as del abecedar io.

(d) Pr opuest o. Escr ibe un pr ogr ama que, ut ilizando e indicando los pat r ones de pr ogr amación
usados, pueda simular el siguient e diálogo:

Contador de letras en una frase
Escriba la frase que desea contar? Esta es la frase
a = 3 veces
e = 3 veces
f = 1 veces
l = 1 veces
r = 1 veces
s = 2 veces
t = 1 veces
7 letras usadas
Escriba la frase que desea contar? _

Not e que lo que hace el pr ogr ama es cont ar cuánt as veces se r epit e una let r a del
abecedar io en la f r ase que ingr esa el usuar io, y cuent a cuánt as let r as dist int as t iene la
f r ase.

Console c = new Console();
c.println("CONTADOR DE LETRAS");
// Ciclo de programa,
// nada que ver con Patrones
while (true) {
c.print("Escriba la frase?");

// PATRON DE LECTURA DE DATOS
String frase = c.readLine();

// Trasnformamos toda la frase a minúsculas
frase = frase.toLowerCase();
int cont_letras = 0;

for (int i=0; i<abcdario.length(); i++;) {

// Sacamos la letra i-ésima del abcdario
String letra = abcdario.charAt(i);

int cont_veces = 0;

for (int j=0; j<frase.length(); j++) {
// Verificamos que sea la letra escogida
if (frase.charAt(j).equals(letra)) {
cont_veces++;
}
}

// Una vez que cuenta cuántas veces se repite la letra
// la mostramos en la Console si es que es != 0.
if (cont_veces>0) {
c.println(letra + " = " + cont_veces +
" veces");
cont_letras++;
}
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo VIII: Cadenas de Texto y Literales
55

// Ahora decimos cuántas letras encontramos en la frase
c.println("Hay " + cont_letras + " letras en la frase");
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo IX: Patrones de Programacion
56
Capít ulo I X: Pat r ones de Pr ogr amación
Mot ivaci ón
Los pr ogr amas no se par t en a desar r ollar desde cer o. Exist en “element os” que per mit en
t r aducir los algor it mos ment ales en códigos de pr ogr amación y que son comunes ent r e una
solución y ot r a. A ellos se les llama Pat r ones de Pr ogr amación.
Concept o
Un Pat r ón de Pr ogr amación es un element o de pr ogr ama ya conocido que
se puede ut ilizar como par t e de la solución de muchos pr oblemas.

Como es nor mal en lo que son los pat r ones, ser ían element os que se r epit en en dist int as
soluciones. A cont inuación ver emos algunos pat r ones básicos más ut ilizados.
Pat r ón de Acumulación
Se ut iliza par a r ealizar cálculos como la suma de var ios valor es acumulados en dist int as
it er aciones de un ciclo:

suma = val1 + val2 + val3 + ... + valn
producto = fac1 * fac2 * fac3 * ... * facm

La f or ma gener al de est e pat r ón es:

<tipo> <variable> = <valorinicial>;
...
while (<condicion>) {
...
<variable> = <variable> <operador> <expresion>;
...
}

Un ej emplo concr et o ser ía r ealizar el siguient e diálogo:

Valores
? 4.0
? 5.0
? 6.0
? 0.0
Contador = 3

La solución del pr ogr ama ant er ior , mar cando en negr it as aquellas que cor r esponden al pat r ón
de acumulación, ser ía:

c.println(”Valores¨);
int cont = 0;
c.print(”? ”);
double nota = c.readDouble();
while (nota != 0.0) {
Java: del Grano a su Mesa (Version 1.3)
Capitulo IX: Patrones de Programacion
57
cont = cont + 1;
c.print(”? ¨);
nota = c.readDouble();
}
c.println (”Contador = ” + cont);
Pat r ón de Lect ur a de Dat os
Est e pat r ón involucr a las acciones de lect ur a de valor es o dat os. Es bast ant e sencillo y su
f or ma gener al es:

<tipo> <variable>;
...
<variable> = c.readTipo();
...

Es muy út il por que es necesar io par a la int er acción con el usuar io. Ej emplo:

c.print(”Ingrese su nombre? ”);
String nombre = c.readString();
c.println(”Hola ” + nombre);
Pat r ón de Recor r ido de I nt er valo
El pat r ón de r ecor r ido de int er valo es aquél que per mit e r ealizar un ciclo de r epet ición ent r e
un int er valo de valor es ent er os. Su f or ma gener al es:

int i = <valor inicial>;
while (i <= <valor final>) {
. . .
i++;
}

y en f or ma de f or ser ía:

for (int i = <valor inicial>; i <= <valor final>; i++) {
. . .
}

Un ej emplo sencillo es la r esolución de una sumat or ia de la f or ma:






La solución a est e pr oblema es bast ant e sencilla con la f or ma f or :

int suma = 0;
for (int i = 0; i <= n; i++) {
suma += i;
}
Σ i
i = 0
n
Java: del Grano a su Mesa (Version 1.3)
Capitulo IX: Patrones de Programacion
58
Pr oblema
(a) En el siguient e pr oblema asocie con númer os las líneas de código que per t enecen a un pat r ón
de pr ogr amación. Use la siguient e simbología:

1. Pat r ón de Acumulación
2. Pat r ón de Lect ur a de Dat os
3. Pat r ón de Recor r ido de I nt er valo

Console c = new Console();
c.println(”Ingrese las notas de los 100 alumnos.¨);
double suma = 0;
for (int i = 0; i < 100; i++) {
c.print(”Alumno ” + i + ¨?¨);
double nota = c.readDouble();
suma += nota;
}
c.println(”El promedio del curso es: ” + suma/100);
Sol ución




(1)

(3)



(2)

(1)




Console c = new Console();

c.println(”Ingrese las notas de los 100 alumnos.¨);

double suma = 0;

for (int i = 0; i < 100; i++) {

c.print(”Alumno ” + i + ¨?¨);

double nota = c.readDouble();

suma += nota;

}

c.println(”El promedio del curso es: ” + suma/100);
Complement o a la Clase
Es muy impor t ant e r ecalcar que est os pat r ones son los básicos que exist en. También los hay en
muchas ocasiones y t ipos dist int os dependiendo de la solución.

Pr obablement e, a t r avés del cur so encuent r es ot r os pat r ones de pr ogr amación. Por ello,
búscalos y encuént r alos, pues t e ser vir án par a t odos t us pr ogr amas (incluso las t ar eas).
Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
59
Capít ulo X: Ar r eglos y Mat r ices
Mot ivaci ón
Hast a ahor a hemos hecho pr ogr amas que pueden f uncionar hast a con 3 valor es dist int os, y no
hemos podido guar dar más inf or mación, a veces var iables, ni nada.

I maginemos el siguient e diálogo:

Votaciones Mundiales por la Paz
Candidatos = 10

Emisión de votos:
Voto? 1
Voto? 3

... (El diálogo continúa mientras no se ponga 0)

Voto? 0

Resultados de las elecciones:
Candidato 7 = 58 votos
Candidato 3 = 55 votos
Candidato 1 = 33 votos

Fin del programa.

Una f or ma sencilla ser ía declar ar 10 var iables que guar den los vot os de cada candidat o per o
¿qué sent ido t iene cuando el númer o de candidat os es 100 o 1.000?. Hoy, encont r ar emos ot r a
solución.
Concept os
Ar r eglos:
List a de element os (espacios en memor ia) de un mismo t ipo que son
r ef er enciados por una misma var iable subindicada a par t ir de 0 (pr imer a
posición) hast a el númer o de element os menos 1 (n-1 es la últ ima
posición).

En ef ect o. Un Ar r eglo puede ser muy út il cuando se ut ilizan est e t ipo de pr oblemas ya que
per mit en un t r abaj o mucho más dinámico que ut ilizando var iables est át icas. También, es un
ahor r o de espacios de memor ia cuando se almacenan.






. . . . . . . .
0
n element os
n-1
Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
60
Es muy impor t ant e ver que los ar r eglos par t en desde 0 y t er mi nan en n- 1 (si el lar go es de n
por supuest o). Por ej emplo, un ar r eglo de lar go 10 posee las “casillas” 0, 1, 2, 3, 4, 5, 6, 7, 8 y 9.
Dimensiones de los Ar r eglos
Los ar r eglos pueden ser uni -dimensionales o mult i -dimensionales. Par a nosot r os solo nos ser án
aplicables los ar r eglos uni -dimensionales (a los que llamar emos solo ar r eglos) y bi-dimensionales
(a las que llamar emos mat r ices).
Sint axis
Los ar r eglos no poseen un t ipo especial par a ser declar ados. Lo único que hay que hacer es
agr egar un modif icador especial a cada uno de los t ipos ya def inidos.

Por ej emplo:

int a[];
a = new int[100]; // Arreglo de 100 enteros

double[] b;
b = new double[10]; // Arreglo de 10 reales

String s[][];
s = new String[23][50]; // Matriz de 23 filas x 50 columnas Strings.

MiTipo[] c;
c = new MiTipo[3]; // Arreglo de 3 objetos de MiTipo

Como podemos ver hay f or mas dist int as (per o equivalent es) par a cr ear ar r eglos. La f or ma (o
f or mas) gener al es:

<tipo>[] <var>;
<var> = new <tipo>[<largo>];

o

<tipo> <var>[];
<var> = new <tipo>[<largo>];

o

<tipo>[][] <var>;
<var> = new <tipo>[<filas>][<cols>];

o

<tipo> <var>[];
<var> = new <tipo>[<filas>][<cols>];

Cualquier a de las dos f or mas es cor r ect a y hacen exact ament e lo mismo. La dif er encia est á en
las combinaciones que se pueden r ealizar cuando se pr ogr ama. Por ej emplo:

int[] a, b;

Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
61
En est e caso se declar an 2 ar r eglos de ent er os.

int a[], b;

En est e ot r o caso se declar a 1 ar r eglo de ent er os (a) y un ent er o (b).

Per o cuando quer emos leer un element o, o almacenar algo en una posición del ar r eglo, se
ut ilizan subíndices ent er os par a indicar que quer emos sacar :

String s[] = new String[50] ;
s[3] = ”Esta es la posición 4¨;
s[10] = ”Esta es la posición 11¨;
c.println(”Se imprime la 15ava posición del String: ” + s[14]);

Un ej emplo de ut ilización de ar r eglos puede ser r ealizar una lect ur a de t ext o por líneas, es
decir :

Escriba el texto de maximo 100 lıneas que desea almacenar en el
archivo. Para finalizar ponga un punto aislado (.)

> Este es un texto
> que es ingresado por el usuario
> a través del teclado.
> ...
(Llegar a 100)
> última lınea.

Listo. Fue guardado en archivo.txt

Ok. Una f or ma sencilla ser ía hacer lo que cada vez que escr ibier a una línea la enviár amos al
ar chivo, per o si lo hiciér amos con ar r eglos solo abr ir íamos el ar chivo al f inal:

Console c = new Console();
c.println(”Escriba el texto de maximo 100 lıneas que desea almacenar
en el archivo. Para finalizar ponga un punto aislado(.) ¨);
String texto[] = new String[100];
int i = 0;
while(i < 100) {
c.print(”> ”);
texto[i] = c.readLine();
if (texto[i].equals(”.ó)) break;
i++;
}

// Ahora se graba en el archivo
PrintWriter pw = new PrintWriter(new FileWriter(”archivo.txt¨));
for(int j = 0; j < i; i++) {
pw.println() = texto[j];
}
pw.close();
c.println(”Listo. Fue guardado en archivo.txt¨);

Ot r o ej emplo, per o ahor a con mat r ices:

Ingrese las notas de los 130 alumnos del curso:
Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
62

Alumno 1:
P1? _
P2? _
P3? _

...

Alumno 131:
P1? _
P2? _
P3? _

El mejor promedio fue el alumno 57 con un promedio de control X.X.

A dif er encia del pr oblema ant er ior , aquí se r ealiza una búsqueda después de ingr esado los
dat os a la mat r iz. El código ser ía:

Console c = new Console();
c.println(”Ingrese las notas de los 110 alumnos del curso:¨);
double notas[][] = new double[110][3];
for(int i = 0; i < 110; i++) {
c.println(”Alumno ”+ i);
for(int j = 0; i < 3; i++) {
c.print(”P” + j + ”? ¨);
notas[i][j] = c.readDouble();
}
}

// Ahora se busca el mejor promedio
double maxProm = 0; // Nadie tiene peor promedio
double mejorAlumno = -1; // Nadie
for (int i=0; i<110; i++) {
double promedio = (notas[i][0] + notas[i][1] + notas[i][2])/3;
if (maxProm < promedio) {
maxProm = promedio;
mejorAlumno = i;
}
}

c.println(”El mejor promedio fue el alumno ” + mejorAlumno +
¨ con un promedio de control ¨ + maxProm);

Como podemos ver , la ut ilización es complet ament e similar en ambos casos.

¿Qué pasa si necesit o un ar r eglo en un mét odo? Bueno est e pr oblema es bast ant e sencillo, ya
que el “t ipo del ar r eglo” est á def inido t ant o por el t ipo de dat o que almacena + los cor chet es
que indican que es un ar r eglo. Siguiendo con est a r egla:

1. Par a pasar por par ámet r o un ar r eglo o mat r iz:

public void producto (double[] arreglo, double[][] matriz)

2. Par a r et or nar un ar r eglo o mat r iz:

public double[] sumaArreglo (...)

Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
63
public double[][] sumaMatriz (...)

No hay mucha dif er encia.

Par a aclar ar más los concept os hast a aquí vist os, podemos t r at ar de hacer un mét odo que
per mit a t r asponer una mat r iz, ent r egándole por par ámet r o la mat r iz or iginal y las dimensiones
de ella:

public double[][] trasponer (double[][] M, int filas, int cols) {
double valTemp = 0;
for (int i = 0; i < filas; i++) {
for (int j = 0; j < i; j++) { // Es óptimo
valTemp = M[i][j];
M[i][j] = M[j][i];
M[j][i] = valTemp;
}
}
return M;
}

Hecho. J

Ot r a not a int er esant e es saber el lar go de un ar r eglo sin t ener la necesidad de conocer lo
pr eviament e. Por ej emplo:

public double promedioNotas (double[] notas) {
double suma = 0;
for (int i = 0; i < notas.length; i++)
suma += notas[i];
return (suma / notas.length);
}

En est e caso not as t r ae una list a con valor es numér icos, per o no sabemos cuánt o. Par a ello
ut ilizamos . lengt h sin par ént esis (a dif er encia de lengt h() de St r ing obviament e).
Solución al Pr oblema
Recor demos el diálogo del pr oblema:

Votaciones Mundiales por la Paz
Candidatos = 10

Emisión de votos:
Voto? 1
Voto? 3

... (El diálogo continúa mientras no se ponga 0)

Voto? 0

Resultados de las elecciones:
Candidato 7 = 58 votos
Candidato 3 = 55 votos
Candidato 1 = 33 votos

Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
64
Fin del programa.

La solución a est e pr oblema es muy similar al pr oblema de l as not as:

Console c = new Console();
c.println(”Votaciones Mundiales por la Paz¨);

c.println(”Candidatos = 10¨);
int votos[] = new int[10];

// Se inicializan los votos en 0
for (int i=0; i<votos.length; i++)
votos[i] = 0;

// Se ejecuta la votación
c.println(”Emisión de Votos:¨);
while (true) {
c.print(”Voto?¨);
int candidato = c.readInt();
if (candidato = 0)
break;
votos[candidato]++;
}

// Se inicializan al mayor como el primero
int[] maximas = new int[3];
for (int i=0; i<maximas.length; i++)
maximas[i] = 0;

// Ahora se buscan los mejores candidatos
for (int i=0; i<votos.length; i++) {
// Buscamos si es mayor que el primer lugar
if (votos[i] >= votos[maximas[0]]) {
maximas[2] = maximas[1];
maximas[1] = maximas[0];
maximas[0] = i;
}
// Buscamos si es el segundo
else if (votos[i] >= votos[maximas[1]]) {
maximas[2] = maximas[1];
maximas[1] = i;
}
// Buscamos si es el tercero
else if (votos[i] >= votos[maximas[2]]) {
maximas[2] = i;
}
}

// Se imprimen los lugares
c.println(”Resultados de las elecciones:¨);
c.println(”Candidato ”+maxima[0]+”=”+votos[maxima[0]]+” votos¨);
c.println(”Candidato ”+maxima[1]+”=”+votos[maxima[1]]+” votos¨);
c.println(”Candidato ”+maxima[2]+”=”+votos[maxima[2]]+” votos¨);

c.println(”Fin del programa¨);

Ot r a opción hubiese sido haber declar ado 3 var iables par a las máximas vot aciones,
modif icando solo el t r ozo de código por el siguient e:

...
Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
65
// Se inicializan al mayor como el primero
int lugar1 = 0;
int lugar2 = 0;
int lugar3 = 0;

// Ahora se buscan los mejores candidatos
for (int i=0; i<votos.length; i++) {
// Buscamos si es mayor que el primer lugar
if (votos[i] >= votos[lugar1]]) {
lugar3 = lugar2;
lugar2 = lugar1;
lugar1 = i;
}
// Buscamos si es el segundo
else if (votos[i] >= votos[lugar2]) {
lugar3 = lugar2;
lugar2 = i;
}
// Buscamos si es el tercero
else if (votos[i] >= votos[lugar3]) {
lugar3 = i;
}
}

// Se imprimen los lugares
c.println(”Resultados de las elecciones:¨);
c.println(”Candidato ”+lugar1+”=”+votos[lugar1]+” votos¨);
c.println(”Candidato ”+lugar2+”=”+votos[lugar2]+” votos¨);
c.println(”Candidato ”+lugar3+”=”+votos[lugar3]+” votos¨);
...

Per o la elegancia va por dent r o. J
Pr oblemas
Una mult it ienda de Bur undí, El Negr o J udío, se ha dado cuent a de que las ut ilidades que r ecibe
mensualment e no son t an buenas como lo er an ant es.

Un est udio con los especialist as económicos de la t r ibu ha ar r oj ado que la clave de las
ut ilidades est á en la at ención que los vendedor es daban a los client es. En una encuest a anónima
se dier on cuent a de que los 25 vendedor es de la t ienda no t enían incent ivos par a at ender
mej or a los client es por que poseían un sueldo f ij o.

Ent onces, al genial Yoghu-Rt uh Mghe, se le ocur r ió dar incent ivos dependiendo de lo que venda
cada vendedor . Par a ello le piden a ust ed algunos f avor cit os:

(a) Desar r olle un pr ogr ama que simule el siguient e diálogo:

Tienda de 25 vendedores
Porcentaje de comisión? _ (Para todos los vendedores es igual)

Inicio de Ventas:

Vendedor? _
Monto vendido? _

...
Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
66

Vendedor? 0
Fin de Ventas

Resumen de comisiones
Vendedor 1 = $ XXXXX
...
Vendedor 25 = $ XXXXX
Sol ución

Console c = new Console();

c.println(”Tienda de 25 vendedores¨);
int nVendedores = 25;

// Se declara el arreglo con lo vendido por el vendedor
int[] ventas = new int[nVendedores];
for (int i=0; i<ventas.length; i++)
ventas[i] = 0;

// Se pide el % de comisión
c.print (”Porcentaje de comisión? ¨);
double comision = c.readDouble();

// Ciclo de venta de la tienda
c.println(”Inicio de Ventas:¨);
while (true) {
c.print(”Vendedor?¨);
int v = c.readInt();
if (v == 0)
break;
c.print(”Monto vendido?¨);
ventas[v - 1] += c.readInt();
}
c.println(”Fin de Ventas¨);

// Calculo de comisiones por vendedor
c.println(”Resumen de comisiones¨);
for (int i = 0; i < ventas.length; i++) {
c.print (”Vendedor ” + (i + 1) + ” = $ ”);
c.println ((ventas[i] * comision / 100));
}

(b) Hágalo ahor a con un númer o de vendedor es var iable, es decir , que el usuar io ingr ese el
númer o de vendedor es, ya que a t r avés del t iempo no es segur o que siempr e t engan 25
vendedor es.
Sol ución
Bueno, de la f or ma en que se hizo en la par t e (a) la solución es bast ant e sencilla. Ver emos solo
un t r ozo de lo que necesit amos par a ver la dif er encia:

Console c = new Console();

c.print(”Numero de Vendedores?ó);
int nVendedores = c.readInt();

// Se declara el arreglo con lo vendido por el vendedor
Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
67
int[] ventas = new int[nVendedores];
for (int i=0; i<ventas.length; i++)
ventas[i] = 0;

...
Pr oblemas Pr opuest os
Escr iba un pr oblema de cont r ol de invent ar io:

1. Tiene un ar chivo de ent r ada (invent ar io.in) en donde guar da una list a con los códigos de
los pr oduct os (5 car act er es) y sus st ocks iniciales (r est o de la línea). Por ej emplo:

39578 27
84990 32
12948 40
38380 0
92329 109
.
.
.

Not e el espacio que hay ent r e el 5t o car áct er y el st ock del pr oduct o

2. Al f inal del pr ocesamient o del pr ogr ama t iene que guar dar los nuevos st ocks en un
ar chivo (invent ar io.out ) con la misma est r uct ur a ant er ior .

3. Pr oceso de la siguient e f or ma:

Control de Inventario

Inventario Inicial:
Producto XXXX = 5
Producto XXXX = ...

Movimientos:
Tipo (1 = entrada, 2 = salida, 0 = terminar)? _
Código del producto? _
...
Tipo (1 = entrada, 2 = salida, 0 = terminar)? 0
Fin del dıa.

Inventario Final:
Producto XXXX = 5
Producto XXXX = ...

El inventario fue guardado en inventario.out
I mpor t ant e
Cuando t u cr eas un ar r eglo con una clase pr e-def inida, no puedes llegar y cr ear el ar r eglo sin
cr ear cada uno de los obj et os (casillas) del ar r eglo. Por ej emplo con la clase Complej o:

Complejo[] c = new Complejo [20]; ß Casillas del Arreglo
for (int i = 0; i < c.length; i++) {
c[i] = new Complejo(); ß Constructor de la Clase
Java: del Grano a su Mesa (Version 1.3)
Capitulo X: Arreglos y Matrices
68
}


Java: del Grano a su Mesa (Version 1.3)
Capitulo XI: Recursividad
69
Capít ulo XI : Recur sividad
Mot ivaci ón
Sabemos per f ect ament e calcular el f act or ial de un númer o en f or ma secuencial. Además,
podemos ver lo en f or ma de mét odo est át ico (dent r o de la clase pr incipal del pr ogr ama):

static int factorial (int n) {
int resultado = 1;
for (int i = 1; i <= n; i++)
resultado = resultado * i;
return resultado;
}

¿Se podr ía solucionar est e mismo pr oblema per o sin ut ilizar un ciclo explícit o como f or o while?
Concept os
Recur sivi dad
La Recur sividad es un pat r ón de pr ogr amación que per mit e llamar
sucesivament e la misma f uncionalidad o mét odo, con una condición de
salida y var iando su par ámet r o de ent r ada, par a llegar al r esult ado f inal.

El concept o de Recur sividad es un poco complej o de ent ender de buenas a pr imer as, ya que es
un pat r ón bast ant e abst r act o cuando se t r at a de visualizar lo f ísicament e.

Veamos un ej emplo.

Gener ar una secuencia (St r ing) de númer os ent er os a par t ir de 1 y hast a llegar a n (dado por el
usuar io (como par ámet r o) en f or ma r ecur siva e inver sa, es decir como { n, n-1, n-2, ..., 2, 1 }.

El encabezado del mét odo quedar ía como:

static String concatenaRecursivo (int n) {
// Recibe como parámetro el n del máximo en el conjunto.

Par a r ealizar est e pr oblema, se debe pensar en el caso inicial, es decir cuando n = 1 (menor
valor posible par a n):

// Caso base retornamos solo el uno.
if (n == 1)
return ”1¨;

Ok…ahor a que el caso base est á r ealizado, suponemos el paso k-1 cier t o, es decir que la
llamada de concat enaRecur sivo(k- 1) nos r et or na el conj unt o de valor es ent r e k-1 y 1
concat enados. Est o quier e deci r que debemos concat enar le k.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XI: Recursividad
70

Ahor a bien, como no podemos sacar un k, sabemos por hipót esis induct iva que:

concat enaRecur sivo(n) ⇔ n + concat enaRecur sivo(n- 1)

Est o se ve si hubiésemos usado n en vez de k en la hipót esis.

En J ava se ut iliza la hipót esis par a n- 1 cier t a de la misma f or ma, quedando:

// Caso general con hipótesis inductiva
return n + concatenaRecursivo(n-1);
} // Fin del método

y, ent onces, en una visión gener al nuest r o mét odo quedar ía como:

// Encabezado del método
static String concatenaRecursivo (int n) {

// Caso base retornamos solo el uno.
if (n == 1)
return ”1¨;

// Caso general con hipótesis inductiva
return n + concatenaRecursivo(n-1);

}

¡¡¡Es r ecur sivo!!!

Y la llamada ser ía:

String serie = concatenaRecursivo(45);

(Guar da en ser ie el r esult ado “45 44 43 42 41 40 ... 3 2 1”)

Ent onces, r esumiendo lo apr endido, par a hacer un mét odo r ecur sivo se necesit a de 2 pasos muy
impor t ant es:

1. Conocer el caso (o casos) base, es decir , la condición de salida de la r ecur sividad.
2. El paso gener al que se ej ecut a pr ocesando y llamando a la siguient e it er ación.

Est o es muy similar a los ciclos.
Solución al Pr oblema
Par a solucionar el pr oblema, def inamos el caso base y el caso gener al.

Caso Base:
La condición base par a el pr oblema del f act or ial, bast ar ía decomponer la f ór mula:

Java: del Grano a su Mesa (Version 1.3)
Capitulo XI: Recursividad
71
N! = N * (N- 1) * (N- 2) * . . . * 1! * 0!

Es clar o ver que la condición de salida ser ía 0! = 1 ya que sin est a def inición no t er mina la
ser ie.

Caso Gener al:
Si r ealizamos una equivalencia mat emát ica de la f ór mula obt endr emos el caso gener al:

N! = N * (N- 1)!

Bueno, est a equivalencia es muy común en soluciones mat emát icas de pr oblemas de est e t ipo,
ya que ut ilizamos la inducción par a suponer que conocemos (N- 1)! y solo lo mult iplicamos con
nuest r o f act or incógnit a N.

Ent onces, con est os dos pasos clar ament e def inidos, podemos dar la solución al pr oblema:

static int factorialRecursivo (int n) {

// Caso base
if ( n == 0 )
return 1;

// Caso general
return n * factorialRecursivo(n-1);

}

Un concept o muy impor t ant e par a pr oblemas mat emát icos.,
Pr oblema Pr opuest o
(a) Escr iba un mét odo r ecur sivo par a r esolver la siguient e sumat or ia:




En donde n es el valor ent r egado por el usuar io (como par ámet r o). Recuer de que la exponencial
est á en la clase mat emát ica y f unciona como Mat h. exp(i).

(b) Escr iba el pr ogr ama que ut ilice lo ant er ior y simule el siguient e diálogo:

Ingrese el número de iteraciones para la suma
n? 35
La sumatoria vale = ...

Σ i * e
i

i = 0
n
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
72
Capít ulo XI I : Clases y Obj et os
Mot ivaci ón
En J ava solo exist en númer os ent er os y r eales. Realment e es algo int er esant e modelar como se
podr ían r ealizar oper aciones con númer os complej os.

Par a est e pr oblema es necesar io pr imer o def inir concept os gener ales par a la ut ilización de
t ipos especiales de dat os.
Concept os
Clase
Se def ine como Clase a una est r uct ur a de pr ogr amación que per mit e
def inir car act er íst icas y f uncionalidades especiales a un gr upo de
obj et os que poseen el mismo compor t amient o (en la vida r eal).

Es así como 2+i, 3. 5+9i, (1, 4. 5)i que son not aciones par a los númer os complej os per t enecen a
la CLASE COMPLEJ O.

Car act er íst icas: Poseen una par t e r eal y una par t e imaginar ia, ambas par t es son númer os
r eales.

Funcionalidades: Pueden ser escr it os en f or ma binomial o en f or ma de vect or , se suman, se
r est an, se dividen, se mult iplican, et c.
Obj et o
Se def ine como Obj et o a una r ef er encia específ ica de un element o que
de cier t a clase, es decir , es un element o que cumple con las
car act er íst icas de una clase.

Como podemos obser var , si COMPLEJ O es una clase, cada uno de sus númer os complej os ser ían
obj et os de esa clase, es decir , 2+i es un obj et o.

Un ej emplo mucho más concr et o que per mit e ver la dif er encia ent r e CLASE y OBJ ETO es el
clásico ej emplo de PERSONA.

Per sona es una clase, pues agr upa a una ser ie de individuos que cumplen con un conj unt o de
car act er íst icas comunes (t ienen sent idos, son bípedos, de dos sexos, et c) y pueden r ealizar una
cant idad de acciones (f uncionalidades) comunes (caminar , hablar , saludar , comer , et c).

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
73
Ahor a bien, ¿qué dif er encia una per sona de ot r a?. Enumer emos algunas de las car act er íst icas
que hacen a cada individuo dist int o de ot r o: Color de Pelo, Color de Oj os, Color de Piel, Talla,
Peso, I dioma, Nombr e, ent r e ot r as.

Con est as def iniciones, ver emos un Obj et o de la clase Per sona:

Color de Pelo: Castaño
Color de Ojos: Verde
Color de Piel: Blanca
Talla: 1.76 mts.
Peso: 73 Kgs.
Idioma: Español
Nombre: Alberto Dıaz

Como podr emos ver , Alber t o Díaz posee las car act er íst icas de cualquier per sona, es decir ,
posee color de pelo, de oj os, de piel, t alla, peso, idioma y nombr e, per o es un Obj et o de la clase
Per sona por que podemos dist inguir lo del gr upo de per sonas.














En la f igur a ant er ior ment e desplazada, podemos obser var def inidos 2 obj et os adicionales al
que ant er ior ment e llamamos Alber t o: Mar ía y Luis. Los t r es obj et os son de t ipo per sona
por que poseen car act er íst icas comunes como ser bípedos y ser es humanos (par a ser de t ipo
Per sona), per o cada uno se dist ingue de ot r o por t ener dist int os nombr es, t allas, pesos, color
de piel, et c.
Cr eación y Ref er encia de Obj et os en J ava
Par a cr ear un obj et o (de t ipo Per sona par a ej emplos), se ut iliza la sent encia NEW.

Persona alberto = new Persona();

En est a simple línea le indicamos al or denador que nos cr ee un Obj et o de t ipo Per sona y l e
llamar emos (a la var iable) alber t o.

Ahor a bien, si exist ier a que t odas las per sonas pueden caminar (f uncionalidad), est o lo
r epr esent ar íamos como:

CLASE:
Per sona
OBJ ETO:
Alber t o
OBJ ETO:
Mar ía
OBJ ETO:
Luis
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
74
alberto.caminar();

Como podemos ver , par a llamar una f uncionalidad de la clase del t ipo de la var iable, se ut iliza el
separ ador “.” (punt o).

Es muy impor t ant e decir que las f uncionalidades de una cl ase son def inidos como mét odos, es
decir , pueden r ecibir par ámet r os y pueden r et or nar valor es. Por ej emplo:

String frase = alberto.hablar(”hola maria¨);
maria.escuchar(frase);

En est e últ imo ej emplo, se est á simulando una conver sación ent r e Alber t o y Mar ía. Ot r o
ej emplo de est o se puede ver más clar ament e con los númer os complej os:

// Declaramos el complejo 3+5i
Complejo a = new Complejo(3, 5);

// Declaramos el complejo -1+9i
Complejo b = new Complejo(-1, 9);

// Declaramos el complejo c como la suma de los complejos
// a y b
Complejo c = a.sumar(b);

// Imprime en pantalla la forma binomial del complejo c
c.println(c.binomial());

Es así como nace un nuevo concept o:
Ref er encia:
Una Ref er encia a un obj et o es la var iable que indica el obj et o deseado.

En el ej emplo de los complej os, a, b y c son r ef er encias a obj et os de t ipo complej o. En el
ej emplo de las per sonas, alber t o y mar ia son los nombr es de las var iables que son las
r ef er encias.
Declar ación de una Clase
La declar ación de una clase no es muy dist int a a lo que ya hemos hecho par a poder compilar y
ej ecut ar nuest r os pr ogr amas y ej emplos.

La f or ma gener al de declar ación de una clase es la siguient e:

[public] class <nombre de la clase> {
// Variables de instancia
[declaracion de variables de instancia]

// Constructor de la clase
public <nombre de la clase> ( [parametros] ) {
<instrucciones>
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
75
// Inicio de las funcionalidades
[public] <tipo de dato del retorno> <nombre del metodo>
( [parametros] ) {
<instrucciones>
}
}

Como podemos ver se par ece mucho al pr ogr ama pr incipal. La dif er encia se encuent r a en los
modif icador es de los mét odos que ut ilizamos. Not emos la ausencia del modif icador st at ic
f r ent e a la def inición de los mét odos.

Por ej emplo, usemos la clase Per sona:

public class Persona {
// Variables de Instancia
public String nombre;

// Constructor
public Persona(String nombre) {
this.nombre = nombre;
}

// Funcionalidades
public String decirNombre() {
return this.nombre;
}

public int sumarEnteros (int n1, int n2) {
return n1 + n2;
}
}

y par a est e ej emplo, podr emos ut ilizar el siguient e código par a r ef er enciar lo:

// Al hacer NEW se llama al constructor de la clase
Persona alberto = new Persona (”Alberto Dıaz¨);

// Le pedimos que nos de su nombre
c.println(”Yo me llamo ” + alberto.decirNombre());

// Le pedimos que sume dos números
int suma = alberto.sumaEnteros(1, 5); // suma es 6

Var iables de I nst ancia: Son var iables que r epr esent an las car act er íst icas que dif er encian l os
dist int os t ipos de obj et os de la clase.

Const r uct or : Son mét odos especiales que per mit en el “set eo” inicial del obj et o. En par t icular la
mayor par t e de las veces se ut ilizan par a set ear var iables de inst ancia o dar le algunos valor es
iniciales al obj et o.

Funcionalidades (Mét odos): Son las acciones que el obj et o puede r ealizar . Est as acciones
pueden o no devolver dat os. A veces se ut ilizan solo par a dar le valor es a var iables de inst ancia
o simplement e par a impr imir en pant alla (pasándole como par ámet r o l a consola).

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
76
Es impor t ant e dest acar que la inst r ucción THI S se ut iliza dent r o de la declar ación de una
clase como una r ef er encia por def ect o a ella misma, par a llamar a las var iables de inst ancia.
También, y en f or ma pr áct ica, la clase declar ada se guar da en un ar chivo con el mismo nombr e
que el nombr e de la clase, es decir par a el ej emplo, Per sona. j ava (oj o con la mayúscula del
pr incipio que es igualit a a la del nombr e de la clase).
Solución al Pr oblema
Revisemos la solución del pr oblema plant eado a la mot ivación par a mayor clar idad a est os
concept os.

public class Complejo {
// Variables de instancia
public double parteReal;
public double parteImag;

// Constructor
public Complejo (double real, double imaginario) {
this.parteReal = real;
this.parteImag = imaginario;
}

// Funcionalidades (algunas)
public String formaBinomial () {
return this.parteReal + ”+¨ + this.parteImag + ”i¨;
}

public String formaVectorial () {
return ”(” + this.parteReal + ”, ¨ +
this.parteImag + ”)i¨;
}

public Complejo suma (Complejo sumando) {
Complejo resultado = new Complejo
(this.parteReal + sumando.parteReal,
this.parteImag + sumando.parteImag);
return resultado;
}
}

Y par a mayor clar idad, como se ut iliza en un pr ogr ama pr incipal ser ía algo como lo siguient e:

<...>
Complejo a = new Complejo (2, -9);
Complejo b = new Complejo (0, -1);

Complejo suma = a.suma (b);

c.println(”La suma de ¨ + a.formaBinomial() + ” y ” +
b.formaBinomial() + ” es: ”);
c.println(c.formaVectorial());
<...>
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
77
Pr oblemas
(a) Def inir la clase Tr iángulo que guar de los valor es de los cat et os a y b (var iables de
inst ancia) y que per mit a r ealizar las siguient es oper aciones sobr e un t r iángulo r ect ángulo:

• Calcular el per ímet r o del t r iángulo
• Calcular el ár ea del t r iángulo

public class Triangulo {
// Variables de instancia que almacenan los catetos
public double a;
public double b;

// Constructor que recibe los catetos de un triángulo
public Triangulo(double a, double b) {
this.a = a;
this.b = b;
}

// Cálculo del perımetro
public double perimetro() {
// Calculamos primero la hipotenusa
double c = Math.sqrt(Math.pow(this.a, 2) +
Math.pow(this.b, 2));

// Retornamos el perımetro
return this.a + this.b + c;
}

// Cálculo del área
public double area() {
// Retornamos el área
return (this.a * this.b) / 2;
}
}

(b) Escr ibir el pr ogr ama pr incipal que use lo ant er ior y que simule el siguient e diálogo:

Ingrese un Triángulo:
a? _
b? _
El perımetro es = []
El área es = []

(me par ece conocido de unas clases at r ás)

<...>
// Pedimos los datos
Console c = new Console();
c.println(”Ingrese un Triángulo:¨);
c.print(”a?¨);
double a = c.readDouble();
c.print(”b?¨);
double b = c.readDouble();

// Creamos el triángulo con estos catetos
Triangulo tr = new Triangulo(a, b);
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
78

// Retornamos los valores pedidos
c.println(”El perımetro del triángulo es = ” + tr.perimetro());
c.println(”El área del triángulo es = ” + tr.area());
<...>

(c) (Pr opuest o) Def inir una clase llamada Pant alla que per mit a almacenar una Console (consola)
y que esconda a la consola que hemos ut ilizado hast a ahor a.

Par a ello def ina los mét odos:

public Pant alla(Console c)
que es el const r uct or de la pant alla y que per mit e r ef er enciar la consola ext er na.

public void escr ibir (St r ing s)
que per mit e escr ibir en la consola (de inst ancia) el st r ing s con un r et or no de línea
al f inal (pr int ln).

public St r ing leeSt r ing()
que per mit e leer desde el t eclado un St r ing cualquier a.

(d) (Pr opuest o) Use la clase Pant alla par a escr ibi r el siguient e pr ogr ama:

Hola. Yo soy el computador.
¿Cómo te llamas? ALBERTO
Hola ALBERTO mucho gusto en conocerte.

Her encia
Exist e la clase Dado ya def ini da como:

int nCar as; Var iable de inst ancias que posee el númer o de car as del dado.
Dado(int n) Const r uct or que per mit e cr ear un dado con n car as.
int t ir ar Dado(int veces) Simula que se t ir a veces veces el dado de nCar as car as y suma los
r esult ados.
int t ir ar Dado() Llama a t ir ar Dado(1).

Se pide r ealizar una clase Dado6 que simule un dado de 6 car as a par t ir de la clase Dado.
Concept os
Her enci a
Una clase Her eda de ot r a cuando posee las mismas car act er íst icas y
f uncionalidades que su padr e, y que se le pueden agr egar ot r as
car act er íst icas y f uncionalidades par t icular es par a ella.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
79
El concept o de her encia es ot r o par adigma de la pr ogr amación or ient ada al obj et o que la hacen
una her r amient a poder osa par a el desar r ollo.

La idea es no r e-const r uir car act er íst icas ni f uncionalidades comunes par a muchas clases de
obj et os, por el cont r ar io, es r eut ilizar lo que se va escr ibiendo par a poder r ealizar mej or es y
más est r uct ur ados pr ogr amas.

Por ej emplo, volviendo al ej emplo de Per sona.















En el diagr ama (un poco modif icado del or iginal vist o 2 clases at r ás) podemos ver que t enemos
los mismos obj et os: Mar ía, Alber t o y Luis. Est os 3 obj et os son Per sonas por que per t enecen a
esa clase, per o hemos inser t ado un element o adicional que es la clase Alumno:

¿Cuál es la idea de est a clase?

Alumno es una especialización de Per sona por que “t odos los alumnos deben ser per sonas”. Est o
quier e decir que un Animal no puede ser un alumno (se par ece a la vida r eal),

Ent onces, podemos decir que Mar ia y Alber t o son Per sonas y Alumnos por que t odas las
f uncionalidades y car act er íst icas de Per sona son her edadas por la clase Alumno.

Veamos un ej emplo concr et o.

Def inamos la clase Calculador a que per mit e r ealizar las oper aciones mat emát icas básicas
(suma, r est a, mult iplicación y división):

public class Calculadora {
// Esta clase no tiene variables de instancia

// Constructor vacıo y no hace nada
public Calculadora() {
}

// Métodos que permiten operar números reales
CLASE
Per sona
OBJ ETO
Alber t o
OBJ ETO
Mar ía
OBJ ETO
Luis
SUBCLASE
Alumno
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
80
public double sumar(double a, double b) {
return (a + b);
}

public double restar(double a, double b) {
return (a - b);
}

public double multiplicar(double a, double b) {
return (a * b);
}

public double dividir(double a, double b) {
if (b == 0) return 0;
return (a / b);
}
}

Est e ej emplo (y a modo de r epaso) se ut ilizar ía de la siguient e f or ma:

//...
Console c = new Console();
Calculadora cal = new Calculadora();

// Pedimos datos
c.print(”a?¨);
double a = c.readDouble();
c.print(”+,-,*,/?¨);
String op = c.readLine();
c.print(”b?¨);
double b = c.readDouble();

// Hagamos un IF múltiple de otra forma
double resultado = 0;
switch op {
case ”+¨:
resultado = cal.sumar(a, b);
case ”-¨:
resultado = cal.restar(a, b);
case ”*¨:
resultado = cal.multiplicar(a, b);
case ”/¨:
resultado = cal.dividir(a, b);
}

// Mostramos el resultado
c.println(a + ” ” + op + ” ” + b + ” = ” + resultado);

Y si most r amos la pant alla, saldr ía algo como:

a? 5
+, -, *, /? *
b? ᑺ3
5 * -3 = -15

Ahor a bien. Necesit amos una clase Calculador aCient if ica que calcule además el SEN y COS.
Par a ello no t enemos que pr ogr amar sumar . Rest ar , mult iplicar y dividir de nuevo, solo debemos
her edar los de calculador a:

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
81
public class CalculadoraCientifica extends Calculadora {
// Se heredan los métodos de Calculadora y las variables
// de instancia.

// Constructor de CalculadoraCientifica
public CalculadoraCientifica() {
// Invoca el constructor de Calculadora
super();
}

// Solo los métodos que nos faltaban
public double seno(double x) {
return Math.sin(x);
}

public double coseno(double x) {
return Math.cos(x);
}
}

Y el mismo pr ogr ama ant er ior podemos cambiar y agr egar a Calculador aCient if ica:

//...
Console c = new Console();
CalculadoraCientifica cal = new CalculadoraCientifica();

// Pedimos datos
c.print(”a?¨);
double a = c.readDouble();
c.print(”+, -, *, /, seno, coseno?¨);
String op = c.readLine();
if (op != ”seno¨ && op != ”coseno¨) {
c.print(”b?¨);
double b = c.readDouble();
}

// Todos los casos
double resultado = 0;
switch op {
case ”+¨:
resultado = cal.sumar(a, b);
case ”-¨:
resultado = cal.restar(a, b);
case ”*¨:
resultado = cal.multiplicar(a, b);
case ”/¨:
resultado = cal.dividir(a, b);
case ”seno¨:
resultado = cal.seno(a);
case ”coseno¨:
resultado = cal.coseno(a);
}

// Mostramos el resultado
if (op != ”seno¨ && op != ”coseno¨)
c.println(a + ” ” + op + ” ” + b + ” = ” + resultado);
else
c.println(op + ”(” + a + ”) = ” + resultado);

¡Est o f unciona!
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
82
Solución al Pr oblema
Ver emos que la solución es mucho más cor t a de lo que pensamos.

public class Dado6 extends Dado {
// Hereda las variables de instancia de Dado

// Constructor que no necesita parámetros
public Dado6() {
// Lo creamos con un dado de 6 caras
super(6);
}

// Los métodos se mantienen por lo que no es necesario
// declarar ninguno de los de la clase Dado
}

y si pensamos como f uncionar ía est o, quedar ía un pr ogr ama como est e:

// ...
Console c = new Console();

// Creamos un dado de 6 caras
Dado6 d = new Dado6();

// Tiramos 3 veces el dado
c.println(d.tirar(3));

// Tiramos 1 vez el dado
c.println(d.tirar());

// Tiramos 10 veces el dado
c.println(d.tirar(10));

Es muy impor t ant e dest acar que se est án ut ilizando los mét odos declar ados en Dado y no
cualquier ot r o mét odo.
Pr oblemas
(a) Pr opuest o. Escr ibir la clase Dado descr it a en la mot ivación.

Exist e una clase Figur a def inida de la siguient e f or ma:

Mét odo Descr ipción
Figur a () Const r uct or vacío. Cr ea una f igur a sin punt os.
void agr egaPunt o (double x, double y) Agr ega un punt o (x, y) a la f igur a.
void dibuj a (Console c) Dibuj a la f igur a en la consola c.
Figur a copia () Ret or na una copia de la misma f igur a
boolean compar a (Figur a f ig) Ret or na TRUE si la f igur a f ig es igual a la f igur a
(t his) y FALSE si no.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
83
(b) Escr iba la clase Cuadr ado que her ede de Figur a y que r epr esent e un cuadr ado. Solo debe
implement ar el const r uct or Cuadr ado (double x, double y, double lado) en donde (x, y)
indica el cent r o del cuadr ado y (lado) es el lar go de cada lado.

(c) Haga lo mismo que en b per o par a la clase Cír culo, que r ecibe en su const r uct or el cent r o
(x, y) y el r adio del cír culo. Nót ese que debe dibuj ar punt o a punt o el cír culo.

Enlace Dinámi co
Recor dando concept os pasados, se desea or ganizar ar chivos a t r avés de clases. Par a est o se
t iene la clase Ar chivo que es capaz de r epr esent ar un ar chivo cualesquier a con las siguient es
f uncionalidades:

• Ar chivo(): Const r uct or de la clase que no hace nada.
• void ser Nombr e(): Le asigna un nombr e al ar chivo.
• St r ing get Nombr e(): Obt iene el nombr e del ar chivo.

Un ej emplo de ut ilización ser ía:

Archivo arch = new Archivo();
arch.setNombre(”Curriculum.doc¨);

La clase Ar chivo est á r epr esent ando cualquier t ipo de ar chivo y posee las oper aciones
genér icas de ellos, sin embar go no se sabe si es de Lect ur a o Escr it ur a.

Par a aliviar est o, podemos def inir 2 subclases más llamadas Ar chivoLect ur a y
Ar chivoEscr it ur a, con los mét odos r espect ivos:

Ar chivoLect ur a Ar chivoEscr it ur a
Const r uct or Ar chivoLect ur a() Ar chivoEscr it ur a()
Par a Leer Dat os St r ing leeLinea() -
Par a Escr ibir Dat os - void escr ibeLinea(St r ing s)
I dent if ica el Fin de Ar chivo boolean esEOF() -
Par a Abr ir el Ar chivo void abr ir () void abr ir ()
Par a Cer r ar el Ar chivo void cer r ar () void cer r ar ()

Como podemos ver , ambas clases se dif er encian por lo mét odos, per o ambas deben her edar las
car act er íst icas y f uncionalidades def inidas par a Ar chivo. Gr áf icament e est o se ver ía como:








CLASE
Ar chivo
SUBCLASE
Ar chivoLect ur a
SUBCLASE
Ar chivoEscr it ur a
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
84


Y como sabemos, podemos cr ear obj et os del t ipo de la subclase y ut ilizar mét odos de la
subclase como de la super clase:

ArchivoLectura al = new ArchivoLectura();
al.setNombre(”misdatos.txt¨); // Método de la Superclase
al.abrir(); // Método de la Subclase

Par a que pr act iques, t r at a de implement ar est as 3 clases.
Concept os
Lo que hemos vist o en la mot ivación ha sido lo que hast a ahor a sabemos de las clases y de las
subclases (apar t e de su sint axis). Per o el t ema no llega hast a ahí, pues por ej emplo no se puede
implement ar una clase que no t enga super clase, por que TODAS las clases son subclases de una
mayor : Obj ect .












En J ava, el modelo j er ár quico de clase pr ediseñadas nace a par t ir de Obj ect (del paquet e
j ava. lang) la cual posee algunas f uncionali dades básicas y un const r uct or genér ico. Es por eso
que una clase que implement emos nosot r os con nuest r as pr opias manos no r equier e un
const r uct or por obligación, ya que por def ect o llama al de Obj ect .

Per o veamos los concept os básicos par a el modelo j er ár quico de clases que posee J ava:
Tipo Est át ico
El Tipo Est át ico de una var iable es el t ipo con el cual es declar ada dicha
var iable, es decir , es la clase o t ipo pr imit ivo que es usado par a indicar a
la comput ador a cuánt a memor ia r eser var .

Est a f or ma complej a de ver la declar ación de una var iable se r esume solo en la pr imer a or ación,
es decir : . . . el t ipo con el cual se declar a . . . Por ej emplo:

String s;
Archivo arch;
ArchivoLectura fd;
Ar chivo
Ar chivoLect ur a Ar chivoEscr it ur a
Obj ect
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
85

En est os 3 casos es llamado Tipo Est át ico a la clase que hast a ahor a hemos llamado TI PO de la
var iable. St r ing, Ar chivo y Ar chivoLect ur a ser ía la r espuest a cor r ect a.
Tipo Dinámico
El Tipo Dinámico de una var iable es el t ipo r ef er enciado por ella, es
decir , es el t ipo con el cual se inst ancia la var iable. Est e t ipo puede
coincidir con el Tipo Est át ico como puede ser una subclase de él.

Est e concept o nos explica un poco más sobr e la inst anciación de una var iable. Por ej emplo:

Archivo arch;
arch = new ArchivoLectura();

Mir ando est e t an básico ej emplo podemos ver que el t ipo est át ico de ar ch es Ar chivo. Sin
embar go, al moment o de su inst anciación (segunda línea) est amos llamando al const r uct or de la
clase Ar chivoLect ur a, es decir , est amos cr eando una inst ancia de est a clase. ¿Cómo es eso?.

El Tipo Di námico nos per mit e r ealizar est a “bar bar idad” ya que la subclase es una
especialización de su padr e (super clase) y es posible decir que: “Todo Ar chivoLect ur a t ambién
es un Ar chivo”.

Est os dos concept os hacen el nacimient o del t er cer o y no menos impor t ant e t ér mino:
Enlace Dinámico
El Enlace Dinámico es una sit uación que ocur r e cuando se invoca un
mét odo de un obj et o r ef er enciado por una var iable, el mét odo que
ef ect ivament e es ej ecut ado es el que cor r esponde al t ipo dinámico de la
var iabl e.

Est e concept o nos abr e muchas puer t as, per o t ambién nos pone algunas r est r icciones. Par a
ent ender lo un poco mej or , veamos algunos ej emplos:

Pr imer o, declar ar emos el t ipo est át ico de ar ch como Ar chivo y el dinámico como
Ar chivoLect ur a.

Archivo arch;
arch = new ArchivoLectura();

Hast a ahor a nada nuevo. Per o qué pasa si hacemos lo siguient e:

arch.setNombre(”miarchivo¨);

Bueno, dir emos que est amos baut izando nuest r o ar chivo de lect ur a. Per o lo impor t ant e es el
enlace dinámico que ocur r e aquí, ya que aunque el mét odo set Nombr e est é declar ado en la
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
86
clase Ar chivo, J ava ej ecut a el mét odo que es her edado (vir t ualment e escr it o, no es el mét odo
or iginal).


No obst ant e a que podamos hacer est o, t ambién hay una limit ant e gr ande en el siguient e
ej emplo:

Archivo arch = new ArchivoEscritura();
arch.setNombre(”salida.txt¨);
arch.abrir();

Est e t r ozo de código que al par ecer no t iene nada de malo, no f unciona.

¿Por qué?

Si analizamos un poco nos dar emos cuent a que ar ch es de t ipo est át ico Ar chivo y no
Ar chivoEscr it ur a que es en donde el mét odo abr ir exist e. En est e caso pr evalece la condición
del t ipo est át ico, por lo que el compilador no encont r ar á como válido pedir la a Ar chivo el
mét odo abr ir . J ava no hace un cast implícit o, así que est o lo podr íamos solucionar lo con un cast
explícit o a la subclase (que si est á per mit ido).

Archivo arch = new ArchivoEscritura();
arch.setNombre(”salida.txt¨);
( (ArchivoEscritura) arch).abrir();
Conclusi ón
El enlace dinámico nos da la f acult ad de escr ibir mét odos genér icos par a un gr upo de clases
“del mismo t ipo”, r eciclando subpr ogr amas.

¿Y par a qué si r ve hacer lo?

Es út il por que si no pudiér amos hacer lo, t endr íamos que escr ibir el mismo código una y ot r a vez
dependiendo de los dist int os t ipos de obj et os que necesit ár amos.
Sint axis
Un element o muy peculi ar en J ava es el llamado I nst anceof .

Con est a inst r ucción uno puede compar ar r ef er encias a obj et os y poder compar ar el t ipo
dinámico sin conocer lo explícit ament e, est o quier e decir , que podr emos saber si una var iable es
inst ancia de una clase o de ot r a. Por ej emplo si t uviér amos un ar r eglo de ar chivos, que no
conocemos si son de lect ur a o escr it ur a:

Archivo archs[];
// ... en alguna parte los crean ...
for (int i=0; i<archs.length; i++) {
c.print (archs[i].getNombre() + ” es de ¨);
if (archs[i] instanceof ArchivoLectura)
c.println(”Lectura¨);
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
87
else if (archs[i] instanceof ArchivoEscritura)
c.println(”Lectura¨);
else // caso que es instancia de Archivo
c.println(”Desconocido¨);
}
I nt er f ace
Clase especial que per mit e def inir las f ir mas de los mét odos que DEBE
poseer t oda clase her eder a de ella misma, es decir , per mit e def inir un
pat r ón par a la cr eación de las clases hij a de una int er f ace.

Est e concept o bast ant e ext r año es muy út il, ya que per mit e dar paut as par a escr ibir clases de
cier t o t ipo. Por ej emplo, podemos declar ar una int er f ace llamada Nodo que per mit e almacenar
un element o cualquier a con car act er íst icas no def inidas. Ent onces la int er f ace Nodo quedar ía
así:

public interface Nodo {
public Object sacarValor();
public void ponerValor(Object o);
}

Como podemos ver no hemos const r uido ni declar ado nada dent r o de Nodo, solo hemos puest o
las f ir mas de los mét odos. Fíj at e que t odos son públicos.

Todos los mét odos que se def inen en una int er f ace DEBEN ser públicos, por que est án
def iniendo la f or ma de comunicación que t endr án los pr ogr amas con las clases que
I MPLEMENTEN est a int er f ace.

Por ej emplo, escr ibamos un Nodo que nos per mit a almacenar una clase Ar chivo:

public class NodoArchivo implements Nodo {
private Archivo arch;

public Object sacarValor() {
return arch;
}

public void ponerValor(Object o) {
// Debemos suponer que o es de tipo dinámico Archivo
arch = (Archivo) o;
}
}

Aquí est amos implement ando un element o llamado NodoAr chivo que almacena un ar chivo e
implement a los mét odos de la int er f ace Nodo. Est o no limit a a que podamos escr ibir más
mét odos, por el cont r ar io. Siempr e nacer án f uncionalidades específ icas que solo NodoAr chivo
t endr á, y que no son comunes a Nodo.

Una I nt er f ace NO PUEDE t ener obj et os, es decir :

Nodo n = new Nodo(); // Esto está errado
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
88
Nodo n = new NodoArchivo(); // Esto está correcto

Un ej emplo pr áct ico es:

public interface Arreglo {
// Dimensionar un arreglo
public void dimensionar (int n);

// Largo de un arreglo
public int largo();
}

Est a I nt er f ace def ine la est r uct ur a (int er f ace) gener al que t ienen t odos los ar r eglos: ver y
dimensionar el t amaño del ar r eglo (cant idad de element os). I mplement emos ahor a ent onces un
ar r eglo de St r ings a par t ir de est a int er f ace:

public class ArregloStrings implements Arreglo {
private String els[];

public ArregloString() {
}

// Se implementan los métodos de la interface
public void dimensionar(int n) {
this.els = new String[n];
}

public int largo() {
return this.els.length;
}

// Los siguientes métodos no corresponden a la definición
// de la interface
public String sacar(int i) {
return this.els[i];
}

public void poner(int i, String x) {
this.els[i] = x;
}
}

Como podemos obser var , t enemos la clase que implement a la int er f ace. Sin embar go la clase
Ar r egloSt r ing posee mét odos que no son comunes con ot r os t ipos de ar r eglos ( Ar r egloEnt er o,
Ar r egloAr chivo, et c), ya que su def inición depende del t ipo de la var iable de inst ancia de la
clase pr opia (els).
Clase Abst r act a
Una Clase Abst r act a es un híbr ido ent r e una I nt er f ace y una Clase
nor mal que per mit e def inir mét odos y var iables de inst ancia (como en
las clases nor males) per o t ambién dej ar por def inir en los hij os de la
clase algunos mét odos (como en las int er f aces).

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
89
Las clases abst r act as en gener al son ut ilizadas como int er f aces más especializadas, per o con
líneas de código út il y que hacen cosas.

La sint axis de una clase abst r act a es muy similar a la de las clases nor males, sin embar go posee
algunos element os adicionales:

abstract class Nodo {
// Puede tener variables de instancia
Object elto;

// Para que se definan en los hijos, igual que INTERFACE
public abstract Object sacarValor();

// y para definir como en clases normales
public void ponerValor(Object o) {
elto = o;
}
}

Ahor a bien, las clases que her eden de Nodo en est e caso NUNCA sabr án que su padr e es una
clase abst r act a. Su única r egla es que DEBEN implement ar aquellos mét odos def inidos como
abst r act os en la super clase. Es decir :

public class NodoArchivo extends Nodo {
// Ya no se necesitan variables de instancia

// Se DEBE implementar
public Object sacarValor() {
return arch;
}

// El método ponerValor() no es necesario implementarlo,
// pues lo está en la superclase Nodo.
}

Al igual que las int er f aces, NO SE PUEDE t ener un obj et o del t ipo de la clase abst r act a.

Veamos el caso de los ar r eglos per o con clase abst r act a (más f ácil):

public abstract class Arreglo {
// Se presentan los métodos que serán implementados
public abstract void dimensionar(int n);

public abstract int largo();

// En este caso no tiene métodos propios
}

Vemos clar ament e que cambia un poco el punt o de vist a que se puede ut ilizar par a est e t ipo de
casos. Sin embar go, queda clar o como la clase se implement a luego:

public class ArregloStrings extends Arreglo {
private String els[];

public ArregloString() {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
90
}

// Se implementan los métodos de la clase abstracta
public void dimensionar(int n) {
this.els = new String[n];
}

public int largo() {
return this.els.length;
}

// Los siguientes métodos no corresponden a la definición
// de la clase abstracta
public String sacar(int i) {
return this.els[i];
}

public void poner(int i, String x) {
this.els[i] = x;
}
}

¿Alguna dif er encia?
Solución al Pr oblema
Es muy int er esant e ver el pr oblema de los Ar chivos de Lect ur a y Escr it ur a con clases
abst r act as e int er f aces. Veamos pr imer o la implement ación con I nt er f ace:

public interface Archivo {
public void darNombre(String nombre);
public void abrir();
public void cerrar();
}

Solo eso, ya que los ar chivos de lect ur a/ escr it ur a se dif er encian en lo que hacen ent r e el abr ir
y cer r ar .

public class ArchivoLectura implements Archivo {
private BufferedReader bf;
private String nombre;

// Constructor vacıo
public ArchivoLectura() {
}

// Los métodos de la interface
public void darNombre (String nombre) {
this.nombre = nombre;
}

public void abrir () {
this.bf = new BufferedReader (
new FileReader( this.nombre ) );
}

public void cerrar () {
this.bf.close();
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
91

// Métodos propios
public String leeLinea() {
return this.bf.readLine();
}
}

public class ArchivoEscritura implements Archivo {
private PrintWriter pw;
private String nombre;

// Constructor vacıo
public ArchivoEscritura() {
}

// Los métodos de la interface
public void darNombre (String nombre) {
this.nombre = nombre;
}

public void abrir () {
this.pw = new PrintWriter (
new FileWriter( this.nombre ) );
}

public void cerrar () {
this.pw.close();
}

// Métodos propios
public void escribeLinea(String linea) {
this.bf.printLine(linea);
}
}

Mucho más bonit o que lo que alguna vez vimos ¿no?. Bueno la ut ilización de est as clases queda a
discr eción de ust edes, ya que si r epasamos más ese t ema quedar emos más complicados... J

Ahor a veamos la implement ación de Ar chivos con Clase Abst r act a.

public abstract class Archivo {
// Declaremos el común de ambos tipos
// No es privado porque quiero que lo lean los hijos
protected String nombre

// Los por implementar son abrir y cerrar
public abstract void abrir ();
public abstract void cerrar ();

// El genérico
public void darNombre (String nombre) {
this.nombre = nombre;
}

public Archivo (String nombre) {
this.darNombre(nombre);
this.abrir();
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
92
Hey, pudimos implement ar el dar Mombr e sin t ener el pr oblema del t ipo de ar chivo. Veamos
como quedan los t ipos:

public class ArchivoLectura extends Archivo {
private BufferedReader bf;

// Constructor
public ArchivoLectura (String nombre) {
super(nombre);
}

// Los métodos de la clase abstracta
public void abrir () {
this.bf = new BufferedReader (
new FileReader( this.nombre ) );
}

public void cerrar () {
this.bf.close();
}

// Métodos propios
public String leeLinea() {
return this.bf.readLine();
}
}

public class ArchivoEscritura extends Archivo {
private PrintWriter pw;

// Constructor vacıo
public ArchivoEscritura() {
}

// Los métodos de la clase abstracta
public void abrir () {
this.pw = new PrintWriter (
new FileWriter( this.nombre ) );
}

public void cerrar () {
this.pw.close();
}

// Métodos propios
public void escribeLinea(String linea) {
this.bf.printLine(linea);
}
}

Se nos simplif ica más la solución.

Per o es cosa de gust os y elegir cuál es mej or no es el pr oblema.
Pr oblemas
Se t iene la clase Car t a que per mit e modelar una car t a de un mazo de car t as inglesas (de
póker ). Su def inición es la siguient e:

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
93
public class Carta {
private String pinta;
private String numero;

public Carta (int p, String n) {
this.pinta = (String) p;
this.numero = n;
}

public String verCarta () {
return this.numero + ”-” + this.pinta
}

static public int compararCarta (Carta c1, Carta c2) {
...
// 1 si c1 > c2
// 0 si c1 = c2
// -1 si c1 < c2
...
}
}

(a) Escr iba l a clase Mazo que per mit e modelar el mazo de car t as. Par a ello ut ilice la siguient e
def inición de la clase:

Mazo ()
(Const r uct or ) Cr ea un nuevo mazo de car t as. Llena
el mazo.
void poner(Carta c)
Pone la car t a c en el mazo (en la pr imer a posición)
Carta sacar()
Saca la pr imer a car t a del mazo. Est o elimina la
car t a del mazo.

Not a: En est e caso consider e las pint as como un númer o, es decir :

1. Diamant es
2. Cor azones
3. Tr éboles
4. Picks
Sol ución
public class Mazo {
private Cartas m[];
private int indice;

public Mazo () {
this.m = new Cartas[52];
this.indice = 0;
for (int pinta=1; pinta<5; pinta++) {
for (int n=1; n<14; n++) {
String numero = (String) n;
if (n > 10)
numero = ”J¨;
if (n > 11)
numero = ”Q¨;
if (n > 12)
numero = ”K¨;
this.m[this.indice] =
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
94
new Carta(pinta, numero);
this.indice++;
}
}
}

public void poner (Carta c) {
this.m[this.indice] = c;
this.indice++;
}

public Carta sacar () {
this.indice--;
return this.m[this.indice];
}
}

(b) Escr iba el mét odo pr ivado void mezclar () que per mit e aleat or iament e mezclar el mazo.
Sol ución
Tiene muchas soluciones, per o ver emos solo una:

private void mezclar() {
// Cortamos el mazo actual
int corte = Math.trunc(Math.random()*52);

// Creamos los 2 mazoz
Cartas c1[] = new Cartas[corte];
Cartas c2[] = new Cartas[52 - corte];

// Luego repartimos los submazos
for (int i=0; i<52; i++) {
if (i < corte)
c1[i] = this.sacar();
else
c2[i - corte] = this.sacar();
}

// Y luego volvemos una a una las cartas del mazo actual
int j1 = 0, j2 = 0;
while (j1 > c1.length && j2 > c2.length) {
if (i % 2 == 0) {
this.poner(c1[j1]);
j1++;
}
else {
this.poner(c2[j2]);
j2++;
}
}

while (j1 > c1.length) {
this.poner(c1[j1]);
j1++;
}

while (j2 > c2.length) {
this.poner(c2[j2]);
j2++;
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
95
}

(c) Ut ilizando (b), escr iba el mét odo r evolver par a los siguient es casos (f ir mas):

• void r evolver (): Revuelve una vez el mazo una vez.
• void r evolver (int n): Revuelve n veces el mazo.
Sol ución
public void revolver() {
mezclar();
}

public void revolver(int n) {
for (int i=0; i<n; i++)
mezclar();
}
(d) Se desea implement ar la clase abst r act a Figur a que per mit a modelar una f igur a genér ica a
par t ir de segment os de r ect as unidas por vér t ices.

La def inición de la clase es la siguient e:

Variables de Instancia
Repr esent ación con 2 ar r eglos de double par a
almacenar las component es x e y.
public double Perimetro()
Calcula el per ímet r o del polígono.
public abstract double Area()
Fir ma del mét odo que def inir á cada uno de las
ár eas de f igur as que her eden de est a clase.
Sol ución
public abstract class Figura {
protected double x[];
protected double y[];

private double distancia (double x1, double y1,
double x2, double y2) {
return Math.sqrt(Math.pow(x2 - x1) +
Math.pow(y2 - y1));
}

public double perimetro () {
double p = 0;
int n = this.x.length;
for (int = 0; i < n - 1; i++) {
p += this.distancia(this.x[i], this.y[i],
this.x[i+1], this.y[i+1]);
}
p += this.distancia(this.x[n - 1], this.y[n - 1],
this.x[0], this.y[0]);
return p;
}

public abstract double area();
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
96
(e) Const r uya la clase Tr iangulo a par t ir de la clase Figur a par a que per mit a modelar un
t r iángulo. Par a ello consider e que est a clase posee el siguient e const r uct or :

public Tr iangulo (double x[ ] , double y[ ] )

en donde x e y son ar r eglos que t r aen 3 valor es par a cada una de las coor denadas de los
punt os del t r iángulo, es decir , (x[ i] , y[ i] ) es un punt o.

Not a: No olvide implement ar lo que sea necesar io.
Sol ución
public class Triangulo extends Figura {
public Triangulo (double x[], double y[]) {
super.x = new double[x.length];
super.x = x;

super.y = new double[y.length];
super.y = y;
}

// Se declara el método abstracto
public double area() {
// PROPUESTO: Calculo a partir del perimetro
}
}

(f ) Rehaga el pr oblema per o ahor a ut ilizando una I nt er f ace en vez de una Clase Abst r act a.
Sol ución
public interface Figura {
public double perimetro();
public abstract double area();
}

public class Triangulo implements Figura {
protected double x[];
protected double y[];

public Triangulo (double x[], double y[]) {
super.x = new double[x.length];
super.x = x;

super.y = new double[y.length];
super.y = y;
}

private double distancia (double x1, double y1,
double x2, double y2) {
return Math.sqrt(Math.pow(x2 - x1) +
Math.pow(y2 - y1));
}

public double perimetro () {
double p = 0;
int n = this.x.length;
for (int = 0; i < n - 1; i++) {
p += this.distancia(this.x[i], this.y[i],
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
97
this.x[i+1], this.y[i+1]);
}
p += this.distancia(this.x[n - 1], this.y[n - 1],
this.x[0], this.y[0]);
return p;
}

public double area () {
// PROPUESTO: Calculo a partir del perimetro
}
}

(d) ¿Qué vent aj as t iene ut ilizar una con r espect o a la ot r a solución?
Sol ución
Al ut ilizar I nt er f ace t enemos la capacidad de, en est e caso, incluir dent r o de la def inición a
Cir culo como una clase que implement a Figur a. Mient r as que en el caso de la ut ilización de
Clase Abst r act a el cír culo lo DEBEMOS r epr esent ar como un polígono.

Sin embar go lo ant er ior , usar Clase Abst r act a queda más apr opiado según las especif icaciones
ya que la r epet ición de algunos mét odos no pasa (por ej emplo el del per ímet r o par a f igur as
como Cuadr ados, Tr iángulos y demases.

El modelo gener al (y más adecuado) ser ía:










Ot r o Pr oblema
(Sacado de un cont r ol de hace un par de años at r ás) Un pr oblema bast ant e r eal ser ía suponer
que exist e una clase Figur a con los siguient es mét odos:

• Figur a(): Const r uct or vacío que no hace nada
• void agr egar Punt o(double x, double y): Agr ega un punt o a la f igur a
• void sacar Punt o(): Saca el últ imo punt o agr egado de la f igur a
• double per ímet r o(): Obt iene el per ímet r o de la f igur a (suma de sus lados)

Con est a def inición, la clase puede r epr esent ar cualquier f igur a en un plano, a par t ir de t r ozos
de r ect as que def inen su cont or no (hast a un cír culo si lo t r ozos son pequeñit os).

(a) Se pide implement ar una subclase Rect angulo que t enga los siguient e mét odos:
Figur a
Polígono Cír culo
Tr iángulo Cuadr ado
I nt er f az
Clases
Clases
Abst r act a
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
98

• Rect angulo(): Const r uct or que t ampoco hace nada
• void def inir Rect angulo(double x1, double y1, double x2, double y2): Def ine un
r ect ángulo a par t ir de dos vér t ices diamet r alment e opuest os.
Sol ución
public class Rectangulo extends Figura {
public Rectangulo() {
super();
}
public void definirRectangulo(double x1, double y1,
double x2, double y2) {
super();
super.agregarPunto(x1, y1);
super.agregarPunto(x1, y2);
super.agregarPunto(x2, y2);
super.agregarPunto(x2, y1);
}
}

(b) I mplement ar la subclase Cuadr ado a par t ir de Rect angulo solo con el const r uct or :

• Cuadr ado(double x, double y, double d): Def ine un cuadr ado desde el punt o (x, y) y
de lado d.
• Cuadr ado(): Const r uct or que no hace nada.

Not a: La super clase de Cuadr ado es Rect ángulo.
Sol ución
public class Cuadrado extends Rectangulo {
public Cuadrado() {
super();
}
public Cuadrado(double x1, double y1, double d) {
super.definirRectangulo(x1, y1, x1+d, y1+d);
}
}

(c) Escr iba un mét odo que per mit a leer desde un ar chivo de punt os f or mat eado como:

• Tipo (1 car áct er ): (C)uadr ado, (R)ect ángulo o (F)igur a
• Punt os: Par de coor denadas del t ipo (X,Y) y separ adas hast a el f in de línea.

Y que las almacene en un ar r eglo de Figur a.

Por ej emplo:

C 1,1 1,2 2,2 2,1
R 3,4 5,4 5,-2 3, -2
F 1,5 -4,7 -1,-1 0,0 9,10 -1,-2 10,10
...

Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
99
(Est as son 3 f igur as, per o una es un cuadr ado, ot r a un r ect ángulo y ot r a una f igur a
cualquier a. Es muy impor t ant e f ij ar se en los espacios que vienen ent r e cada par de dat os)

Not a: El nombr e de ar chivo viene por par ámet r o y vienen 100 f igur as en el ar chivo.
Sol ución
public Figura[] leerArchivo(String nombre) {
// Declaramos el arreglo de resultados
Figura figs[];

// Inicializamos el arreglo
// Ojo que cada casilla requiere un posterior NEW
figs = new Figura[100];

// Leemos el archivo
BufferedReader bf = new BufferedReader(
new FileReader(nombre));
String linea;
int i=0;
for (int i=0; i<100; i++) {
linea = bf.readLine();

// Discriminamos el tipo de figura
String tipo = linea.charAt(0);
switch tipo {
case ”C¨:
figs[i] = new Cuadrado();
case ”R¨:
figs[i] = new Rectangulo();
case ”F¨:
figs[i] = new Figura();
}

// Y ahora ponemos los puntos de la figura
linea = linea.substring(2);
int espacio, coma;
double x, y;
while ((espacio = linea.indexOf(” ”)) > 0) {
coma = linea.indexOf(”,¨);
x = new Double(
linea.substring(0, coma)
).doubleValue();
y = new Double(
linea.substring(coma + 1, espacio - coma)
).doubleValue();
figs[i].agregarPunto(x, y);
linea = linea.substring(espacio + 1);
}
coma = linea.indexOf(”,¨);
x = new Double(
linea.substring(0, coma)
).doubleValue();
y = new Double(
linea.substring(coma + 1, length(linea) - coma)
).doubleValue();
figs[i].agregarPunto(x, y);
}
bf.close();

// Retornamos el arreglo de figuras
return figs;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XII: Clases y Objetos
100
}

(d) Escr ibir un pr ogr ama que ut ilice (c) par a simular el siguient e diálogo:

Nombre de archivo de entrada? puntos.txt
Leyendo puntos... Ok!

Contando cuántas figuras hay:
Cuadrados: 10
Rectángulos: 2
Otras figuras: 27
Sol ución
Console c = new Console();
c.print(”Nombre de archivo de entrada?¨);
String nombre = c.readLine();

// Se leen los puntos
c.print(”Leyendo puntos... ¨);
Figura figs[] = leerArchivo(nombre);
c.print(”Ok!¨);

// Ahora se cuentan las figuras
c.println(”Contando cuántas figuras hay:¨);
int nC = 0, nR = 0, nF = 0;
for (int i=0; i<figs.length; i++) {
if (figs[i] instanceOf Cuadrado)
nC++;
else if (figs[i] instanceOf Rectangulo)
nR++;
else // figs[i] instanceOf Figura
nF++;
}
c.println(”Cuarados: ” + nC);
c.println(”Rectángulos: ” + nR);
c.println(”Otras Figuras: ” + nF);
Pr oblemas Pr opuest os
(a) Volviendo al t ema de la mot ivación, cr ear a par t ir de un Mapa (super clase), la clase
MapaEnt er os (subclase) que per mit a almacenar solo númer os ent er os en el mapa. Par a ello
son necesar ios los siguient es mét odos:

MapaEnteros (int n)
(Const r uct or ) Cr ea un nuevo mapa de ent er os vacío
de n element os.
void agregar (int i, int x)
Agr ega el ent er o x a la posición i del mapa.
int sacar (int i)
Saca el element os de la posición i del mapa.

Not e clar ament e que el agr egar no ha cambiado. ¿Deber á implement ar lo ent onces?

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

101
Capít ulo XI I I : Or denamient o y Búsqueda
Mot ivaci ón
El MTT ha decidido almacenar las mediciones que r ealiza a los vehículos en un lugar de
Sant iago. Par a est o r equier e que se le r ealice un pr ogr ama que haga el siguient e diálogo:

Bienvenido al Sistema de Control de Contaminación
Ingrese el código del Inspector? 538

Bienvenido señor.

Ingrese patente del vehıculo? HG 5857
Indice registrado? 3.8
Clave Verde

Ingrese patente del vehıculo? ZZ 3481
Indice registrado? 2.6
Clave Verde

Ingrese patente del vehıculo? AS 2216
Indice registrado? 5.1
Clave Roja

...

Ingrese patente del vehıculo? 0

Se han registrado 53 mediciones:
(1) ındice de 7.8
(2) ındice de 7.8
(3) ındice de 7.7
(4) ındice de 7.2
...
(53) ındice de 2.6

Como se ve en el diálogo, el pr ogr ama const a de 2 par t es:

1. Recolect ar los dat os de cada medición dur ant e el día. Est as mediciones son al azar , es
decir , no se sabe cuál es el índice que se est á ingr esando (mayor que 5.0 es clave r oj a).
La lect ur a de dat os t er mina con una pat ent e 0 y no e sabe el númer o de mediciones, sin
embar go, puede ser un máximo de 100 (par a que use un ar r eglo).
2. Desplegar en pant alla las mediciones r ealizadas, per o est a vez or denadas de mayor a
menor , par a t ener una est adíst ica más clar a.

La solución a est e pr oblema es bast ant e sencilla:

Console c = new Console();
c.println(”Bienvenido al Sistema de Control de Contaminación¨);
c.print(”Ingrese el código del Inspector?¨);
int code = c.readInt();

c.println(”Bienvenido señor.¨);

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

102
double mediciones[] = new double[100];
int n = 0;
while(true);
c.print(”Ingrese patente del vehıculo?¨);
String pat = c.readLine();

if (pat.equals(”0¨) || n == 100)
break;

c.print(”Indice registrado?¨);
mediciones[n] = c.readDouble();

if (mediciones[n] > 5.0)
c.println(”Clave Roja¨);
else
c.println(”Clave Verde¨);

n++;
}

// n sale con el número del siguiente elemento o 100
// que es lo mismo que el NÚMERO de elementos
// por lo tanto enviaremos a un método el arreglo
// entre 0 y el máximo + 1 para que quede completa-
// mente ordenado.
ordenarArreglo(mediciones, 0, n);

// Ahora que está ordenado, desplegamos
c.println(”Se han registrado ” + n + ¨ mediciones:¨);

for (int i=0; i<n; i++) {
c.println(”(” + (i+1) + ¨) ındice de ¨ + mediciones[i]);
}

Solo nos queda pendient e como or denar el ar r eglo... J
Concept os
Or denami ent o
Es un algor it mo que nos per mit e cambiar el or den (de posición) los
element os par a dej ar los or denados según un cr it er io f ij o
(numér icament e, lexicogr áf icament e, de menor a mayor , de mayor a
menor , et c).

Est a def inición bast ant e básica es la que nos per mit e ent ender que es un algor it mo de
or denamient o, per o no t iene mucho sent ido si no hay una aplicación t angible.

El or denamient o de ar r eglos es muy út il par a r ealizar búsquedas de element os, puest o que
cuando buscamos dent r o de un ar r eglo un element o específ ico (por ej emplo el nombr e de una
per sona) deber íamos usar la “f uer za br ut a” par a encont r ar lo. Por ej emplo:

String nombres[] = new String[100];
// en alguna parte de se ingresan los nombres
// desordenadamente
String nombreBuscado = ”Morales Gutierrez Carlos Alberto¨;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

103
int i = 0;
while ( ! nombres[i].equals(nombreBuscado) ) {
i++;
}

Si nos ponemos a analizar est e pr ogr amit a par a buscar un nombr e, t enemos el pr oblema que si
la per sona hubiese sido la úl t ima en el ar r eglo, t uvimos que r ecor r er lo complet o par a
encont r ar lo. ¿Se imaginan que pasar ía si la guía de t eléf ono est uvier a desor denada y ust edes
quisier an encont r ar el t eléf ono de un t ío? ¡¡Qué locur a!!.

Si la list a de nombr es est á or denada, a “Mor ales” no lo buscar emos al pr incipio, por que lo más
pr obable que allí est én “Ast or ga”, “Ar aya” y t odos los pr imer os apellidos, por lo t ant o
empezamos de un punt o más en la mit ad, en donde est án los “Lor ca”, “Mar t inez” y “Or t ega”.

Bueno, per o par a eso, el ar r eglo hay que or denar lo. ¿Cómo se hace?.

Exist en algor it mos de or denamient o, par t iendo del base que es una f or ma exhaust iva, es decir ,
de la siguient e f or ma:

1. Buscar el mayor de t odos
2. Poner lo en la pr imer a (o últ ima) posición de un ar r eglo auxiliar
3. “Anular ” el mayor
4. Volver a hacer desde 1 hast a que no quede ninguno

Est a es la f or ma básica. Per o ¿qué dif er encia hay con los algor it mos de or denamient o?, en el
f ondo nada, pues al f inal siempr e or denan un ar r eglo (de lo que sea). Sin embar go def inir emos
lo que es la ef iciencia de los algor it mos, algo que puede ser un punt o cr ít ico al moment o de
elegir una f or ma de or denar una ser ie de dat os.
Ef iciencia
En los algor it mos, la ef iciencia se mide como el t iempo que t oma un
algor it mo en r ealizar su f inalidad.

Per o no es t an sencillo medir ese t iempo como t omar un cr onómet r o y ver cuánt o se demor a en
hacer un algor it mo su t r abaj o con 10, 100 o 1.000 dat os, pues los t iempos que puede t omar son
milisegundos.

Par a medir la ef iciencia exist e un examen llamado análisis de t iempo que nos per mit e obt ener
el valor algebr aico del t iempo que nos da la idea de la magnit ud del t iempo que puede t omar el
algor it mo es su ej ecución expr esado en f unción de la cant idad de element os que posee
(cant idad de element os del ar r eglo en el caso de or denamient o).

Veamos cómo analizar el caso de or denamient o exhaust ivo:

public void ordenar (int[] arreglo, int nEls) {
int auxiliar[] = new int[nEls];

// Ciclo 1
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

104
for (int i=nEls-1; i>0; i--) {
int maximo = 0

Ciclo 2
for (j=0; j<nEls; j++) {
// Ponemos el máximo en la última posición
if (arreglo[maximo] < arreglo[j])
máximo = j;
}

auxiliar[i] = arreglo[máximo];
arreglo[máximo] = -1; // Se elimina como posible sgte
}

arreglo = auxiliar;
}

Def inamos como T0 el t iempo de ej ecución de t oda línea de código f uer a de los ciclos, T1 el
t iempo que t oma las líneas del ciclo 1 y T2 las del ciclo 2. Todas se miden en f or ma
independient e de las ot r as, es decir no consider a los valor es dent r o de su ej ecución. Ent onces,
or denar un element o t omar á el siguient e t iempo:

T(1) = T0 + 1 * T1 + 1 * T2

T0 es siempr e const ant e, ya que siempr e se ej ecut ar á 1 vez independient e de la cant idad de
veces que ej ecut emos el mét odo, sin embar go T1 y T2 est án dependiendo de la cant idad de
element os, ya que el f or r epit e esas inst r ucciones como númer o de element os t engamos, es
decir , par a n element os nos quedar ía:

T(n) = T0 + n * T1 + n * (n * T2)

Desar r ollando un poquit o:
T(n) = T2 * n
2
+ T1 * n + T0


Dir emos ent onces que el or den del algor it mo es el t ér mino var iable de mayor exponent e
dent r o de la cuadr át ica, est o quier e decir (y lo anot ar emos así) que:

T(n) = O(n
2
)

Se leer á como: “El t iempo que t oma el algor it mo es de or den n
2
”. Est o signif ica que si t omamos
un ar r eglo de 100 element os, el or den de magnit ud del algor it mo ser á de 10.000 (5 cer os algo
alt o cuando hablamos de 1.000.000 de element os). Per o no t odo es t an malo, pues est o es en
t eor ía. En la pr áct ica (aunque par ezca un chist e) podemos t omar 3 casos:

• Mej or Caso (ar r eglo or denado): O(n
2
)
• Peor Caso (ar r eglo muuuuuy desor denado): O(n
2
)
• Caso Pr omedio (ot r o caso nor mal): O(n
2
)

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

105
Exist en muchos algor it mos de or denamient o def inidos que nos per mit en ef iciencia en el
or denamient o. Se han def inido como base los siguient es:

Algor it mo de Selección y Reemplazo
Algor it mo de la Bur buj a (BubbleSor t )
QuickSor t
Mer geSor t

Adver t encia: Lo algor it mos de or denamient o en gener al se pueden implement ar en f or ma
it er at iva (f or , while) per o son mucho más ef icient e cuando se ut iliza la r ecur sividad. Es
r ecomendable que r epacen el capít ulo de Recur sividad par a ent ender mej or est e.
Algor it mo de Selección y Reemplazo
Pr obablement e est e sea el algor it mo más int uit ivo que exist e, pues ut iliza una met odología
bast ant e básica que se puede analizar . Es muy ef icient e y f ácil de implement ar , per o solo
cuando los ar r eglos son pequeños.

Veamos como lo har ía una per sona inexper t a y sin conocimient os par a or denar un ar r eglo (solo
valor es posit ivos por simplicidad):

void ordenarArreglo (int arreglo[], int nEls) {
// Crearemos un arreglo auxiliar del mismo tamaño
int auxiliar[] = new int[nEls];

// Vamos sacando cada uno de los elementos y
// los vamos almacenando el el auxiliar ordenadamente
// (Supongamos valores positivos)
for (int i=nEls-1; i>0; i--) {
int maximo = 0
for (j=0; j<nEls; j++) {
// Ponemos el máximo en la última posición
if (arreglo[maximo] < arreglo[j])
máximo = j;
}

auxiliar[i] = arreglo[máximo];
arreglo[máximo] = -1; // Se elimina como posible sgte
}

arreglo = auxiliar;
}

Est e mét odo lo que hace es or denar en FORMA BRUTA un ar r eglo no es muy ef icient e, ya que
no lleva un pat r ón f ij o de búsqueda del máximo valor (lo que pasa cuando buscamos en un
ar r eglo desor denado, como ya mencionamos). Veamos como f unciona el algor it mo se selección
que no ut iliza un ar r eglo auxiliar .

1. El ar r eglo se or dena ent r e 0 y nEls
a. Se busca donde est á el máximo
b. Se int er cambia el últ imo element o por donde est á el máximo
c. Olvidar se del máximo ahor a y seguir .
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

106
2. El ar r eglo se or dena ent r e 0 y nEls-1
a. Se busca donde est á el siguient e máximo
b. Se int er cambia el penúlt imo element o por donde est á el siguient e máximo
c. Olvidar se del siguient e máximo ahor a y seguir .
3. ...
Ult ima. El ar r eglo se or dena ent r e 0 y 0
a. Ter minar , por que un ar r eglo de un element o est á or denado.

Gr áf icament e podemos ver est o como:















Así, no r epasamos t odo el ar r eglo en cada it er ación... J

Veamos ahor a cómo escr ibir íamos eso en f or ma it er at iva:

void ordenarArreglo (int arreglo[], int nEls) {
for (int i=nEls-1; i>0; i--) {
int maximo = 0
for (j=0; j<i; j++) {
// Buscamos el máximo
if (arreglo[maximo] < arreglo[j])
máximo = j;
}

int auxiliar = arreglo[maximo];
arreglo[maximo] = arreglo[i];
arreglo[i] = auxiliar;
}
}

¿No hay demasiada dif er enci a con la “f uer za br ut a” como le llamamos?... Pues sí... por que si
obser vamos con algo de det ención nos dar emos cuent a que el segundo f or (j ) solo r ecor r e
hast a el element o en donde pondr emos el máximo –1, es decir , hast a ant es de donde debe
est ar .

Per o de t odas f or mas hicimos 2 ciclos. Veamos como se ver ía r ecur sivament e:

3

8

2

9

4

1

3

8

2

1

4

9

3

4

2

1

8

9

3

1

2

4

8

9

1

2

3

4

8

9

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

107
void ordenarArreglo (int arreglo[], int nEls) {
if (nEls == 1)
return;

int maximo = 0
for (j=0; j<nEls-2; j++) {
// Buscamos el máximo
if (arreglo[maximo] < arreglo[j])
máximo = j;
}

int auxiliar = arreglo[máximo];
arreglo[máximo] = arreglo[nEls-1];
arreglo[nEls-1] = auxiliar;

ordenarArreglo(arreglo, nEls-1);
}

Acá podemos ver lo que hace exact ament e lo que explicamos ar r iba como algor it mo, pues ut iliza
el caso gener al (or denar ent r e 0 y nEls) y luego va y vuelva a llamar al caso gener al con un
element o menos (or denar ent r e 0 y nEls-1). Así sucesivament e quedar ía al f inal or denando el
ar r eglo HASTA que quede un element o.

Veamos como se compor t a la ef iciencia de est e algor it mo:

void ordenarArreglo (int arreglo[], int nEls) {
// Ciclo 1
for (int i=nEls-1; i>0; i--) {
int maximo = 0

// Ciclo 2
for (j=0; j<i; j++) {
if (arreglo[maximo] < arreglo[j])
máximo = j;
}

int auxiliar = arreglo[máximo];
arreglo[máximo] = arreglo[i];
arreglo[i] = auxiliar;
}
}

T0 : En est e caso es 0
T1 : Se ej ecut a n veces
T2 : Se ej ecut a una cant idad de veces var iable dependiendo del valor de i

Hagamos la ecuación gener al de inmediat o:

T(n) = T0 + n * T1 + A

donde A es la cant idad de veces que se ej ecut ó el ciclo 2 y se expr esa como:

A = T2 * n + T2 * (n-1) + ... + T2 * 2 + T2 * 1 <= T2 * n
2


Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

108
Con est a últ ima igualdad podemos decir que:

T(n) <= T2 * n
2
+ T1 * n
T(n) = O(n
2
)

Nuevament e volvemos a ver que es un or den cuadr át ico. Y veamos en la pr áct ica:

• Mej or Caso: O(n
2
)
• Peor Caso: O(n
2
)
• Caso Pr omedio: O(n
2
)

Malo malo... no ha sido mej or que el f uer za br ut a.

Desaf ío: Realizar el int er cambio de posiciones, es decir :

int auxiliar = arreglo[máximo];
arreglo[máximo] = arreglo[nEls-1];
arreglo[nEls-1] = auxiliar;

Per o sin ut ilizar una var iable auxiliar . J uega con las mat emát icas.
Algor it mo de la Bur buj a (Bubblesor t )
La desvent aj a de ut ilizar selección y r eemplazo es que en ar r eglos muy gr andes, t ar da mucho
en or denar los. Así que los gr andes genios de la comput ación est uvier on buscando ot r o similar y
t an f ácil de apr ender como el de selección par a así dar a luz est e algor it mo llamado de la
Bur buj a.

La idea es muy similar al de selección, de ir int er cambiando los valor es hast a dej ar el máximo
en el últ imo lugar del ar r eglo. La dif er encia est á en que no solo int er cambia el máximo con el
últ imo, sino que va “desplazando” los candidat os a máximo hast a posiciones más avanzadas de
las que se encuent r an, es decir , va or denando par cialment e.

El algor it mo (paso gener al) quedar ía algo como:

1. Or denar ent r e 0 y nEls:
a. Tomar el pr imer o como pot encial máximo dent r o de una bur buj a.
b. Si el segundo es menor que el que t engo en la bur buj a, int er cambiar por el
pot encial máximo. Si el segundo es mayor que el de la bur buj a, poner el segundo
ahor a como pot encial máximo.
c. Si el t er cer o es menor que el que t engo en la bur buj a, int er cambiar por el
pot encial máximo. Si el t er cer es mayor que el de la bur buj a, poner el t er cer o
ahor a como pot encial máximo.
d. ...
e. Si el siguient e es menor que el que t engo en la bur buj a, int er cambiar por el
pot encial máximo. Si el siguient e es mayor que el de la bur buj a, poner el
siguient e ahor a como pot encial máximo.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

109
f . Al últ imo, r event ar la bur buj a, y volver a r epet ir t odo el pr ocedimient o hast a
nEls-1.

¡Hey, es como super r ar o!... Veamoslo gr áf icament e:














A modo explicat ivo suele ser complej o escr ibir una descr ipción ver bal... Per o no es dif ícil de
ent ender al pr ogr amar lo. Veámoslo en f or ma it er at iva pr imer o:

void ordenarArreglo (int arreglo[], int nEls) {
for (int i=nEls-1; i>0; i--) {
for (j=0; j<i-1; j++) {
if (arreglo[j] > arreglo[j+1]) {
int auxiliar = arreglo[j];
arreglo[j] = arreglo[j+1];
arreglo[j+1] = auxiliar;
}
}
}
}

Como podemos ver usamos mucho menos código, pues lo que vamos haciendo es ir desplazando
al máximo desde donde est é, encont r ándolo en el camino, y dej ándolo al f inal, sin andar lo
“buscando” ant es.

La f or ma r ecur siva es bast ant e sencilla, y es:

void ordenarArreglo (int arreglo[], int nEls) {
// Arreglo de 1 elemento está ordenado
if (nEls == 1)
return;

for (j=0; j<nEls-2; j++) {
if (arreglo[j] > arreglo[j+1]) {
int auxiliar = arreglo[j];
arreglo[j] = arreglo[j+1];
arreglo[j+1] = auxiliar;
}
}

3

8

2

9

4

1

3
-
8
3

8

2

9

4

1

8
-
2
3

2

8

9

4

1

8
-
9
3

2

8

9

4

1

9
-
4
3

2

8

4

9

1

9
-
1
3

2

8

4

1

9

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

110
ordenarArreglo(arreglo, nEls-1);
}

Dif ier e en casi nada la f or ma gener al. De hecho, el f or de i que est aba ant es casi ni se not a que
no est á, cosa que en el algor it mo de selección no ocur r ía, por que en el int er cambio si inf luía.

Midamos la ef iciencia de est e algor it mo:

void ordenarArreglo (int arreglo[], int nEls) {
// Ciclo 1
for (int i=nEls-1; i>0; i--) {
// Ciclo 2
for (j=0; j<i-1; j++) {
if (arreglo[j] > arreglo[j+1]) {
int auxiliar = arreglo[j];
arreglo[j] = arreglo[j+1];
arreglo[j+1] = auxiliar;
}
}
}
}

Veamos el análisis:

T(n) = T0 + n * T1 + A

donde A es la cant idad de veces que se ej ecut ó el ciclo 2 y se expr esa como:

A = T2 * n + T2 * (n-1) + ... + T2 * 2 + T2 * 1 <= T2 * n
2


Con est a últ ima igualdad podemos decir que:

T(n) <= T2 * n
2
+ T1 * n
T(n) = O(n
2
)

Nuevament e volvemos a ver que es un or den cuadr át ico. Per o en est e caso, si vemos la pr áct ica:

• Mej or Caso: O(n)
• Peor Caso: O(n
2
)
• Caso Pr omedio: O(n
2
)

¿Por qué ha cambiado el mej or caso? Pues por que ese caso est á condicionado por un if que
puede anular T2 cuando est á or denado el ar r eglo (j amás ent r a). No es t an malo después de
t odo, ya que en ar r eglos semi -or denados, bur buj a puede ser más ef icient e, ya que no pasar á el
100% de las veces por el código del ciclo 2.

Per o veamos r ealment e en ser io cómo podemos ser ef icaces al moment o de or denar un ar r eglo:
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

111
Mer geSor t
Est e algor it mo se basa en el pr incipio de “dividir par a r einar ”, es decir , va dividiendo el ar r eglo
en pr oblemas más pequeños par a r ealizar el or denamient o.

Es r ecur sivo y f unciona bast ant e bien. Veamos cómo lo hace:

Caso Base:
• Si el ar r eglo t iene uno o ningún element o, est á or denado.

Caso Gener al:
• Cor t a por la mit ad el ar r eglo
• Or dena cada mit ad con Mer geSor t
• Mezcla las mit ades par a que queden or denadas.

Ahor a, escr ibamos el algor it mo en líneas de código con J ava:

void mergeSort (int a[], int iMin, int iMax) {
// Caso Base
if(iMin >= iMax) {
return;
}

// Cortamos para aplicar mergeSort recursivamente
int k = (iMin+iMax) / 2;
mergeSort(a, iMin, k);
mergeSort(a, k+1, iMax);

// Utilizamos un arreglo temporal
int l = iMax-iMin+1;
int temp[] = new int[l];
for(int i = 0; i < l; i++) {
temp[i] = a[iMin+i];
}

// Mezclamos
int i1 = 0;
int i2 = k-iMin+1;
for(int i = 0; i < l; i++) {
if(i2 <= iMax-iMin) {
if(i1 <= k-iMin) {
if(temp[i1] > temp[i2]) {
a[i+iMin] = temp[i2++];
}
else {
a[i+iMin] = temp[i1++];
}
}
else {
a[i+iMin] = temp[i2++];
}
}
else {
a[i+iMin] = temp[i1++];
}
}
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

112

¡Es como mezclar 2 t r ozos de una bar aj a de car t as (como en Las Vegas)!

Si vemos el análisis de or den llegar emos a:

T(n) = O(n Log2n) en el caso pr omedio

QuickSor t
Est e algor it mo, más ef icient e que los ant er ior es, se ha desar r ollado baj o r ecur sividad. Su
nombr e nos indica (y hast a ahor a es así) que es el más ópt imo que exist e.

La idea es que QuickSor t t oma un element o dent r o de el ar r eglo como pivot e y luego pasa
t odos los element os menor es que el pivot e a la izquier da y los mayor es que el pivot e a la
der echa. Es decir debe cumpl ir que:

A[ i] <pivot e, par a t odo i <k
A[ i] = pivot e, par a i = k
A[ i] >pivot e, par a t odo i >k

Per o no signif ica que a cada lado del pivot e est é or denado. Veamos como f unciona el código:

void quickSort (int arreglo[], int iMin, int iMax) {
// Caso base
if (iMin >= iMax)
return;

// Caso general
int k = particionar(arreglo, iMin, iMax);
quickSort(arreglo, iMin, k-1);
quickSort(arreglo, k+1, iMax);
}

Est e mét odo or dena un ar r eglo ent r e los índices iMin y iMax. Es sumament e cor t o, ya que la
mayor par t e del t r abaj o la hace el mét odo par t icionar :

int particionar (int a[], int iMin, int iMax) {
int iPiv = iMin;
int k = iMin;
int j = k + 1;

while(j <= iMax) {
if (a[j] < a[iPiv] ) {
// Vamos poniendo el pivote en medio
k = k+1;
int aux = a[k];
a[k] = a[j];
a[j] = aux;
}
j++;
}
int aux = a[k];
a[k] = a[iPiv];
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

113
a[iPiv] = aux;
return k;
}

El cómo f unciona es bien simple.

1. Se t oma la posición iMin como pivot e.
2. En cada it er ación con j mayor que el pivot e y menor que iMax, se compar a el a[ j ] con el
pivot e.
a. Si es menor , se hace cr ecer k en una posición y se int er cambia el element o k
con el element o j , par a que se cumpla la sit uación de:

a[ i] <pivot e si i <k
a[ i] >= pivot e si i >= k

3. En ambos caso se incr ement a j par a cont inuar y se vuelve a 2.
4. Al f inal del ciclo se int er cambia el a[ k] por el pivot e y queda la sit uación r equer ida.
5. Ret or namos el pivot e.

Con est o vamos or denando “r elat ivament e” cada t r ozo de ar r eglo. En cada r ecur sión el t amaño
de los t r ozos se va achicando, hast a llegar al mínimo: 1 element o or denado.

Si analizamos est e algor it mo, t endr emos que:

T(n) = O(n Log2n)

Y si vemos la pr áct ica:

• Mej or Caso: ?
• Peor Caso: O(n
2
)
• Caso Pr omedio: O(n Log2n)

Es r ealment e mej or en el caso pr omedio que los ant er ior es. Hast a ahor a el mej or .
Ej emplo
Par a t odos los casos de or denamient o que ya hemos vist o, cada uno t iene su f ir ma dist int iva.
Veamos cada una:

• void select Sor t (int [ ] a, int n): Algor it mo de selección donde a es el ar r eglo y n es la
cant idad de element os.
• void bubbleSor t (int [ ] a, int n): Algor it mo de bur buj a donde a es el ar r eglo y n es la
cant idad de element os.
• void mer geSor t (int [ ] a, int iMin, int iMax) : Algor it mo Mer geSor t donde a es el
ar r eglo, iMin es donde empieza el ar r eglo (0) y iMax es donde t er mina el ar r eglo
(cant idad de element os-1).
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

114
• void quickSor t (int [ ] a, int iMin, int iMax) : Algor it mo QuickSor t donde a es el
ar r eglo, iMin es donde empieza el ar r eglo (0) y iMax es donde t er mi na el ar r eglo
(cant idad de element os-1).

Podemos hacer una liger a modif icación a los algor it mos iniciales, par a que los 4 sean similar es.
Veamos como es eso:

• void select Sor t (int [ ] a, int iMin, int iMax)
• void bubbleSor t (int [ ] a, int iMin, int iMax)
• void mer geSor t (int [ ] a, int iMin, int iMax)
• void quickSor t (int [ ] a, int iMin, int iMax)

Es decir , con est os 4 mét odo puedo or denar t r ozos de un ar r eglo. En su def ect o, bast ar ía que
hicier a:

selectSort(a, 0, a.length-1);
bubbleSort(a, 0, a.length-1);
mergeSort(a, 0, a.length-1);
quickSort(a, 0, a.length-1);

Par a or denar el ar r eglo a de las 4 f or mas dist int as.
Solución al Pr oblema
Con los algor it mos de or denamient o y sus f or mas it er at ivas o r ecur sivas, t enemos en t ot al 8
soluciones al pr oblema que pueden ser ut ilizadas en f or ma indist int a (solo debemos cambiar el
I NT por DOUBLE y list o).

Ya no es necesar io pensar en un pr oblema específ ico par a r esolver lo, pues si el pr oblema
hubiese sido ot r o, no impor t a cuál es, por que los mét odos de or denamient o son complet ament e
I GUALES.
Concept os
Ahor a que ya hemos r evisado como or denar un ar r eglo, es muy impor t ant e apr ender como
t ambién buscar dent r o de un ar r eglo. Por eso def inimos:
Búsqueda
Algor it mo que per mit e encont r ar valor es dent r o de una list a (or denada)
de ellos.

Es sencillo, ya que lo hemos ut ilizado ant es.
Búsqueda Secuencial
Veamos como encont r ar un valor dent r o de un ar r eglo en f or ma inef icient e:

int buscar (int a[], int nEls, int x) {
int i = -1;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

115
for (int j = 0; j < nEls; j++)
if (a[j] == x)
i = j;
return i;
}

Est e pequeño código busca en f or ma secuencial un valor x dent r o del ar r eglo a y r et or na la
posición en la cual se encuent r a, Sencillo de ver , ent ender y escr ibir , per o es inef icient e.
Fíj ense en el mej or de los casos (est á en la pr imer a posición) igual se r ecor r e TODO el ar r eglo
par a encont r ar lo.

• Mej or Caso: n it er aciones
• Peor Caso: n it er aciones
• Caso Pr omedio: n it er aciones

Vamos a ver algunas opt imizaciones par a cor r egir est o.

int buscar (int a[], int nEls, int x) {
int i = -1;
int j = 0;
while(j < nEls) {
if (a[j] == x) {
i = j;
break;
}
j++;
}
return i;
}

Con est e pequeño cambio podemos baj ar el t iempo de búsqueda:

• Mej or Caso: 1 it er ación
• Peor Caso: n it er aciones
• Caso Pr omedio: n/ 2 it er aciones apr oximadas

Est o mej or a un poco nuest r o algor it mo. Per o aún exist e una f or ma más ópt ima de buscar un
element o.
Búsqueda Binar ia
Est e t ipo de búsquedas se basa en el mismo concept o que ut iliza Mer geSor t y QuickSor t : El
hecho de subdividir el ar r eglo par a opt imizar la búsqueda. Su solución es r ecur siva, así que
añadir emos un par ámet r o adicional en la f i r ma:

int buscar (int a[], int iMin, int iMax, int x) {
if (iMin > iMax)
return -1;

int iCentro = (imin + imax) / 2;
if (a[iCentro] == x)
return iCentro;
else if (a[iCentro] > x)
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

116
return buscar(a, iMin, iCentro-1, x);
else
return buscar(a, iCentro+1, iMax, x);
}

En est e caso se ut iliza como pivot e el cor t ar por la mit ad el t r ozo de búsqueda.

Es muy f ácil ver que:

• Mej or Caso: 1 it er ación
• Peor Caso: n/ 2 it er aciones
• Caso Pr omedio: log2n it er aciones

Si lo vemos de una f or ma pr áct ica, la búsqueda binar ia en muchísimo más r ápida que la
secuencial.
Pr oblemas
Tenemos un ar chivo “not as” con las not as del cont r ol 1 con el siguient e f or mat o:

• Código del alumno (3 car act er es)
• Not a Pr egunt a 1 (3 car act er es, como 6.1, 5.0, 3.9, et c)
• Not a Pr egunt a 2 (3 car act er es)
• Not a Pr egunt a 3 (3 car act er es)

Además, posee un ar chivo llamado “alumnos.t xt ” que cont iene los nombr es de los alumnos
asociados a los códigos, es decir :

• Código del alumno (3 car act er es)
• Nombr e del alumno (el r est o de la línea)

Not a:
• El ar chivo “alumnos.t xt ” est á or denado LEXI COGRÁFI CAMENTE.
• El ar chivo “not as.t xt ” no est á or denado.
• En t ot al son 110 alumnos (“alumnos.t xt ”), pues es la list a complet a. No t odos los
alumnos t ienen not as (“not as.t xt ”) y a ellos se les r ecomienda que le ponga un 1.0
• Los códigos de los alumnos par t en desde 001 y t er minan en 110 (1 a 110 par a ser más
clar o).

(a) Escr iba un mét odo que modif ique la bur buj a par a que or dene de MAYOR A MENOR el
ar r eglo (no impor t a si es RECURSI VO o I TERATI VO).
Sol ución
Par a hacer est o es cosa de cambiar la condición de or den del mét odo:

void ordenarArreglo (int arreglo[], int nEls) {
if (nEls == 1)
return;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

117
for (j=0; j<nEls-2; j++) {
if (arreglo[j] < arreglo[j+1]) {
int auxiliar = arreglo[j];
arreglo[j] = arreglo[j+1];
arreglo[j+1] = auxiliar;
}
}
ordenarArreglo(arreglo, nEls-1);
}

(b) Escr iba un pr ogr ama que per mit a leer las not as de los alumnos y escr iba en pant alla los
pr omedios or denados de MAYOR A MENOR indicando Código del Alumno y Pr omedio,
ut ilizando el mét odo ant er ior .
Soluci ón
Console c = new Console();

// Creamos el arreglo
double notas[] = new double[110];

// Inicialmente TODOS tienen un 1.0
for (int i=0; i<110; i++)
notas[i] = 1.0;

// Leemos el archivo
BufferedReader bf = new BufferedReader (
new FileReader(”notas.txt¨));
while ((String linea = bf.readLine()) != null) {
int codigo = Integer.parseInt(linea.substring(0, 3));
double p1 = new Double(linea.substring(3, 3)).doubleValue();
double p2 = new Double(linea.substring(6, 3)).doubleValue();
double p3 = new Double(linea.substring(9, 3)).doubleValue();
notas[codigo] = (p1 + p2 + p3) / 3;
}
bf.close();

// Ordenamos
ordenarArreglo(notas, 110);

// Desplegamos en pantalla ordenadamente
for (int i=0; i<110; i++) {
c.println(i + ” sacó un ” + notas[i]);
}

(c) Siga con el pr ogr ama par a que luego per mit a cr ear un nuevo ar chivo llamado “list a.t xt ” en el
cual se escr iban los siguient es dat os:

• Nombr e del Alumno
• Espacio (1 car áct er )
• Pr omedio del Cont r ol 1

Nót ese que ust ed YA debe t ener or denado el ar r eglo de MAYOR A MENOR con las not as de
los alumnos.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

118
Sol ución
Cont inuando con el pr ogr ama, no declar amos nada de nuevo, pues est á t odo list o.

PrintWriter pw = new PrintWriter (
new FileWriter(”lista.txt¨);

BufferedReader bf2 = new BufferedReader (
new FileReader(”alumnos.txt¨));

while ((String linea = bf2.readLine()) != null) {
// Obtenemos el código del alumno
int codigo = Integer.parseInt(linea.substring(0, 3));

// Escribimos en lista.txt
pw.print(linea.substring(3));
pw.print(” ”);
pw.println(notas[codigo]);
}

bf2.close();
pw.close();

(d) Escr ibir una int er f az llamada EsCompar able que cont enga una f ir ma que per mit e a
cualquier clase her edada compar ar se con ot r o de su mismo t ipo. Debe poseer ent onces
est a f ir ma:
public int compar ar Con(EsCompar able b);

y que r et or na:

§ nº >0 si el obj et o es mayor que b
§ 0 si el obj et o es igual a b
§ nº <0 si el obj et o es menor que b
Sol ución
public interface EsComparable {
public int compararCon(EsComparable b);
}

(e) Escr ibir una clase Ent er o que implement e EsCompar able y que per mit a r eal izar el siguient e
mét odo est át ico:

public st at ic int compar ar (int a, int b);

Est e mét odo int er nament e cr ea un obj et o Ent er o (que debe poseer un const r uct or que
r eciba un ent er o y que lo almacena como var iable de inst ancia) y lo compar a con ot r o
ent er o del mismo t ipo (cr ea ot r o obj et o de la clase Ent er o con b), r et or nando lo que
ent r ega el mét odo de la par t e (a).
Sol ución
public class Entero extends EsComparable{
protected int n;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

119

public Entero(int x) {
this.n = x;
}

public int compararCon(EsComparable b) {
return this.n - (Entero b).n;
}

static public int comparar(int a, int b) {
Entero A = new Entero (a);
Entero B = new Entero (b);
return A.comparaCon(B);
}
}

(f ) Escr ibir el QuickSor t en f or ma genér ica par a que compar e con el mét odo compar ar que de
la par t e (e).
Sol ución
void quickSort (int arreglo[], int iMin, int iMax) {
// Caso base
if (iMin >= iMax)
return;

// Caso general
int k = particionar(arreglo, iMin, iMax);
quickSort(arreglo, iMin, k-1);
quickSort(arreglo, k+1, iMax);
}

int particionar (int a[], int iMin, int iMax) {
int iPiv = iMin;
int k = iMin;
int j = k + 1;

while(j <= iMax) {
if (Entero.comparar(a[j], a[iPiv]) < 0) {
// Vamos poniendo el pivote en medio
k = k+1;
int aux = a[k];
a[k] = a[j];
a[j] = aux;
}
j++;
}
int aux = a[k];
a[k] = a[iPiv];
a[iPiv] = aux;
return k;
}

(g) Escr ibir la Búsqueda Binar ia (igual que el la par t e c).
Sol ución
int buscar (int a[], int iMin, int iMax, int x) {
if (iMin > iMax)
return -1;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIII: Ordenamiento y Busqueda

120

int iCentro = (imin + imax) / 2;
if (Entero.comparar(a[iCentro], x) == 0)
return iCentro;
else if (Entero.comparar(a[iCentro], x) > 0)
return buscar(a, iMin, iCentro-1, x);
else
return buscar(a, iCentro+1, iMax, x);
}
Pr oblemas Pr opuest os
(a) Desar r olle el mét odo de SELECCI ÓN par a que en vez de or denar de MENOR A MAYOR lo
haga en f or ma inver sa, es decir de MAYOR A MENOR.

(b) Desar r olle el mét odo de la BURBUJ A par a que en vez de or denar llevando el MAYOR
dent r o de la bur buj a, haga el pr oceso inver so de llevar el MENOR a la pr imer a posición.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIV: Archivos de Texto

121
Capít ulo XI V: Ar chivos de Text o
Mot ivaci ón
En J ava se pueden ut ilizar dist int os t ipos de ar chivos par a lect ur a y escr it ur a. Los de más f ácil
acceso son los llamados Ar chivos de Text o.

La idea es poder obt ener dat os desde un ar chivo de t ext o guar dado en el disco dur o en vez del
t eclado y/ o escr ibir los en ot r o ar chivo de t ext o que t ambién se guar da en disco dur o, en vez
de la f amosa vent ana de la Consola.

Sin embar go la ut ilización de los ar chivos es un poco engor r osa y complicada.
Sint axis
Lect ur a de un Ar chivo de Text o
Par a leer un ar chivo de t ext o en J ava, exist en 2 clases que son muy impor t ant es:

1. Buf f er edReader es el t ipo de dat o que guar da la r ef er encia a una ENTRADA de dat os
(que t ambién se ut iliza t ant o par a ar chivos como par a t eclado en el J ava est ándar ).
2. FileReader es una clase que per mit e obt ener un LECTOR par a Buf f er edReader desde
un Ar chivo de Text o.

Es así como abr ir un ar chivo de t ext o par a la lect ur a quedar ía de la siguient e f or ma:

BufferedReader <var> = new BufferedReader(
new FileReader(”<nombre de archivo>¨));

Algo bast ant e f eo J . Per o eso no es t odo, sino que exist e un mét odo muy ut ilizado par a la
lect ur a y es r eadLine() (si, al igual que la consola).

Por lo t ant o, par a leer un ar chivo de t ext o de inicio a f in, t enemos el siguient e ej emplo
(incomplet o por supuest o):

// se abre el archivo
BufferedReader arch = new BufferedReader(
new FileReader(”archivo.txt¨));

// se lee la primera lınea del archivo
String linea = arch.readLine();

// se repite mientras no esté en el final del archivo
while (linea != null) {

// se procesa la lınea leıda desde el archivo
<instrucciones>

// se lee siguiente lınea
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIV: Archivos de Texto

122
linea = arch.readLine();
}

// Se cierra el archivo
arch.close();

Ot r a f or ma de hacer lo es:

// se abre el archivo
BufferedReader arch = new BufferedReader(
new FileReader(”archivo.txt¨));

// se repite mientras no esté en el final del archivo
while (true) {
// se lee siguiente lınea
linea = arch.readLine();

// se verifica que no se esté al final del archivo
if (linea == null) {
break;
}

// se procesa la lınea leıda desde el archivo
<instrucciones>
}

// Se cierra el archivo
arch.close();
Escr it ur a de un Ar chivo de Text o
Par a escr ibir un ar chivo de t ext o en J ava, exist en 2 clases que son muy impor t ant es:

1. Pr int Wr it er es el t ipo de dat o que guar da la r ef er encia a una SALI DA de dat os (que
t ambién se ut iliza t ant o par a ar chivos como par a pant alla en el J ava est ándar ).
2. FileWr it er es una clase que per mit e obt ener un ESCRI TOR par a Pr int Wr it er a un
Ar chivo de Text o.

Es así como abr ir un ar chivo de t ext o par a la escr it ur a quedar ía de la siguient e f or ma:

PrintWriter <var> = new PrintWriter(
new FileWriter(”<nombre de archivo>¨));

Algo igualment e f eo J . Per o eso no es t odo, sino que exist e dos mét odos muy ut ilizado par a la
escr it ur a y son pr int (St r ing) y pr int ln(St r ing) (si, al igual que la consola).

Por lo t ant o, par a escr ibir un ar chivo de t ext o t enemos el siguient e ej emplo:

// se abre el archivo
PrintWriter arch = new PrintWriter(
new FileWriter(”archivo.txt¨));

// se repite mientras hayan datos
while (<condicion para terminar el archivo>) {
// se obtiene los datos para una lınea
<instrucciones>
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIV: Archivos de Texto

123

// se escribe la lınea en el archivo
arch.println(datos);
}

// se cierra el archivo
arch.close();
Ej emplo de Ar chivos
Escr ibir un pr ogr ama que lea desde el t eclado una ser ie de not as y las escr iba en un ar chivo.
Luego, debe ut ilizar est e ar chivo par a obt ener el pr omedio del cur so complet o.

//...
Console c = new Console(”Lector de Notas¨);
c.println(”Ingrese las notas de los alumnos. Termine con un 0¨);

// Trozo de programa que lee de pantalla y
// almacena en archivo c:\notas.txt
PrintWriter pw = new PrintWriter(
new FileWriter(”c:\\notas.txt¨));
double nota = c.readDouble();
while (nota != 0) {
pw.println(nota);
nota = c.readDouble();
}
pw.close();

// Trozo de programa que lee el archivo de notas
BufferedReader br = new BufferedReader(
new FileReader(”c:\\notas.txt¨));
int n = 0;
double suma = 0;
String linea = br.readLine();
while(linea != null) {
suma += Double.parseDouble(linea);
linea = br.readLine();
n++;
}
br.close();

// Despliega la nota
c.println(”El promedio es ” + (suma / n));
Pr oblema
(a) Escr ibir un pr ogr ama que simule la conexión de un usuar io con nombr e y clave. Realice el
siguient e diálogo:

Inicio de Sesión

Nombre de usuario? jperez
Clave? jp
ERROR: Su clave no corresponde

Nombre de usuario? jperez
Clave? Jpa
INGRESO ACEPTADO

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIV: Archivos de Texto

124
Además, consider e que los nombr es de usuar io y claves se encuent r an en un ar chivo llamado
claves. t xt y t iene la siguient e est r uct ur a:

amendoza:lskksa
jperez:Jpa
nromero:nata1.0
...

Hint : Par a separ ar nombr e de usuar io y clave de acceso puedes ut ilizar :

// ...
// Suponemos que tenemos en linea lo leido
int i = linea.indexOf(”:¨);
String nombre = linea.substring(0, i);
String clave = linea.substring(i+1);
// Con nombre y clave comparas los ingresados
// por el usuario
// ...
Solución 1
Est a solución ut iliza el HI NT que se ent r ega,

Console c = new Console();
c.println(”Inicio de Sesión¨);

// Iniciamos el ciclo de sesión
while (true) {
c.print(”Nombre de Usuario?¨);
String sunombre = c.readLine();
c.print(”Clave de Acceso?¨);
String suclave = c.readLine();

// Se abre el archivo de claves
BufferedReader bf = new BufferedReader(
new FileReader(”claves.txt¨));
String linea = bf.readLine();

String nombre;
String clave;

while (linea != null) {
// Se obtiene el nombre y la clave del archivo
int i = linea.indexOf(”:¨);
nombre = linea.substring(0, i);
clave = linea.substring(i+1);

// Se compara solo el nombre
if (nombre.equals(sunombre))
break;

// Siguiente usuario
linea = bf.readLine();
}
bf.close();

// Ahora verificamos por qué salió.
if (linea == null)
c.println(”ERROR: El usuario no existe¨);
else {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIV: Archivos de Texto

125
if (clave.equals(suclave))
break;
c.println(”ERROR: La clave es incorrecta¨);
}
}

// Como solo sale si la clave es correcta
c.println(”INGRESO ACEPTADO!!!!¨);
Solución 2
Est a ot r a solución t ambién f unciona, per o no ut iliza el j uego con subst r ings y es algo más cor t a.

Console c = new Console();
c.println(”Inicio de Sesión¨);

// Iniciamos el ciclo de sesión
while (true) {
c.print(”Nombre de Usuario?¨);
String sunombre = c.readLine();
c.print(”Clave de Acceso?¨);
String suclave = c.readLine();

// Se abre el archivo de claves
BufferedReader bf = new BufferedReader(
new FileReader(”claves.txt¨));
String linea = bf.readLine();

String nombre;
String clave;

while (linea != null) {
// Se compara la linea completa
if (linea.equals(sunombre + ”:¨ + suclave))
break;

// Siguiente usuario
linea = bf.readLine();
}
bf.close();

// Ahora verificamos por qué salió.
if (linea == null)
c.println(”ERROR: La clave es incorrecta¨);
else
break;
}

// Como solo sale si la clave es correcta
c.println(”INGRESO ACEPTADO!!!!¨);

(b) Escr iba un pr ogr ama que r eemplace t ext os en un ar chivo, es decir , que simule el siguient e
diálogo:

Ingrese el nombre del archivo? micarta.txt
Ingrese el patrón a reemplazar? @
Ingrese valor a reemplazar? Juanita
El resultado quedó en Juanita_micarta.txt

La dea es que, por ej emplo si el ar chivo micar t a.t xt t iene el siguient e t ext o:
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIV: Archivos de Texto

126

Mi amada @:

A través de la presente carta he querido invitarte para que mañana
podamos ir al cine y luego tal vez quien sabe.

Ası que, por favor @, contéstame este mail y te espero...

Siempre tuyo
Tu amado

PS: @, no olvides llevar plata, porque no tengo... :)

El r esult ado de cambiar “@” por “J uanit a” ent r egar ía el siguient e ar chivo J uanit a_micar t a.t xt :

Mi amada Juanita:

A través de la presente carta he querido invitarte para que mañana
podamos ir al cine y luego tal vez quien sabe.

Ası que, por favor Juanita, contéstame este mail y te espero...

Siempre tuyo
Tu amado

PS: Juanita, no olvides llevar plata, porque no tengo... :)

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

127
Capít ulo XV: I nt er f aces Gr áf icas AWT
Mot ivaci ón


Hast a ahor a, t odos los pr ogr amas int er act úan con el usuar io t al como lo dice la f igur a
11
:
Most r ar dat os en pant alla y pedir dat os por el t eclado.

Nuest r o f oco ha est ado t odo est e t iempo en lo que son los pr ogr amas y solo hemos hecho
int er acciones sencillas con el usuar io ut ilizando una her r amient a llamada “Console”. Per o ¿Qué
es Console? ¿Cómo f unciona? ¿Podemos hacer ot r o t ipo de vent anas más bonit as?

Es hor a de llevar nuest r a at ención a r ealizar int er f aces dist int as a Console, gr áf icas, y que
puedan ser nos de mucha ut ilidad.
Concept os
I nt er f az Gr áf ica
Pr ogr ama (en J ava) que per mit e una int er acción con el usuar io a t r avés
de una vent ana con bot ones y ot r as component es haciendo más amigable
la int er acción con el Usuar io.

Las int er f aces gr áf icas son pr ogr amas son component es que nos per mit en t r abaj ar
dir ect ament e con gr áf icos como bot ones, t ext os, et c.

11
Se r ef ier e solo a la int er acción humano-comput ador , es decir , usuar io del pr ogr ama con el
comput ador . Exist en más int er acciones como por ej emplo con Ar chivos y Bases de Dat os, per o
que no involucr an al usuar io dir ect ament e.
Pant alla
Pr ogr ama
Teclado
Usuar io
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

128
Sint axis
Par a la ut ilización de int er f aces gr áf icas es obligat or io ut ilizar unos paquet es de clases que se
encuent r an en la API del J DK (J ava Delevopment Kit ). Es por eso que t odos los pr ogr amas J ava
que ut ilizan int er f aces gr áf icas empiezan con la impor t ación de:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class MiInterfazGrafica {
...

public MiInterfazGrafica() {
// Creamos la ventana y las componentes
...
}

...
}

Con est o nos asegur amos que nuest r a clase J ava pueda cr ear vent ana gr áf icas y escr ibir en
ellas (como lo hacemos en la Console) o dibuj ar sobr e ellas.

Par a ej ecut ar est a int er f az gr áf ica es impor t ant e r ecalcar que se debe cr ear una clase que
cr ee nuest r a int er f az per sonalizada (al igual que la console):

public class MiPrograma {
static public void main (String args[]) {
MiInterfazGrafica ig = new MiInterfazGrafica();
}
}

Como se ve en el ej emplo, lo que hacemos r ealment e es cr ear una clase que almacenar á nuest r a
int er f az dent r o de si las component es y t odo. La idea es que el cont r uct or de la clase sea el
const r uct or de la int er f az y que per mit a que se r ef lej e en pant alla.
Concept os
Component e
Element o u obj et o (en J ava) que se ut iliza par a const r uir una int er f az
gr áf ica.

Los component es pueden ser bot ones, ár eas de t ext o, ár eas de dibuj o, imágenes, list as de
valor es y cualquier t ipo de element o gr áf ico (de J ava) que se puede inser t ar dent r o de una
int er f az.

Est os element os son sensibles a “ocur r encias” de la int er f az llamadas “event os”.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

129
Sint axis
Exist en muchos component es par a las int er f aces gr áf icas
12
:
Fr ame
Un f r ame es un ár ea que nos per mit ir á dent r o de ella cr ear la int er f az gr áf ica. Pr act icament e
es la vent ana que se abr e al ej ecut ar nuest r a clase:

Est a vent ana es pr oducida por el siguient e código:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class MiInterfazGrafica {
private Frame ventana;
public MiInterfazGrafica() {
ventana = new Frame("Mi Interfaz Gráfica");
ventana.pack();
ventana.show();
}
}

Ent onces, podemos ver que la component e Fr ame posee var ios mét odos que aquí se descr iben
13
:

Mét odo Descr ipción
Fr ame() Const r uct or sin par ámet r os que cr ea una vent ana de t amaño
0x0 (sin ár ea de cont enido) y sin t ít ulo def inido.

12
Mayor inf or mación en la API del J DK: ht t p:/ / j ava.sun.com/ j 2se/ 1.3/ docs/ api/ index.ht ml
13
Los par ámet r os se encuent r an en el mismo or den de apar ición que en la descr ipción.
Aquí va el cont enido de nuest r a
I nt er f az Gr áf ica
Aquí va el t ít ulo de nuest r a I nt er f az
Gr áf ica
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

130
Mét odo Descr ipción
Fr ame(St r ing) Const r uct or que cr ea una vent ana de t amaño 0x0 y con el
t ít ulo def inido por el par ámet r o.
void set Size(int , int ) Dimensiona el f r ame par a que t enga un t amaño (x, y) en
pixeles r ef lej ados en los 2 par ámet r os del mét odo.
void set Resizable(boolean) Hace que el f r ame quede sin per miso par a r edimensionar el
t amaño con el mouse.
void set Layout (Layout ) Le indica la gr illa que va a ut ilizar el f r ame par a cont ener los
component es. Est as gr illas ser án descr it as más adelant e.
void add(Component ) Pone la component e dent r o del f r ame en la pr imer a posición
libr e del mismo (dependiendo de la gr illa).
void add(St r ing, Component ) Pone la component e dent r o del f r ame y en la posición de la
gr illa indicada en el par ámet r o St r ing.
void addXList ener (XList ener ) Agr ega un list ener par a ej ecut ar una acción cuando ocur r e el
event o X. X va var iando dependiendo del list ener (lo ver emos
más adelant e).
void pack() Pr epar a el despliegue del f r ame en pant alla.
void show() Muest r a el f r ame en pant alla.
Layout
Las gr illas o Layout son ut ilizados dent r o de los f r ames par a dar le “espacios disponi bles” par a
poner un Component e. Par a que un f r ame pueda cont ener “component er ” es necesar io def inir
cuánt os puede cont ener y luego empezar a gener ar los.

Exist en dist int os t ipos de gr illa (Layout Manager es la clase que def ine una gr illa) y las ver emos
con dibuj os a cont inuación:

Gr idLayout : Est e layout cor r esponde a una dist r ibución cuadr iculada (t ipo planilla excel)
y que ocupan el mismo t amaño t odos los cuadr it os.








Por ej emplo, est a gr illa t iene 6 posiciones. Par a cr ear un Fr ame con esa
dist r ibución, se debe escr ibir :

...
f. setLayout(new GridLayout(3,2));
...

donde f es el f r ame que quier o dar le esa gr illa. Una vez que se set ea, se van
poniendo en or den las component es con cada void add(Component ) que se va
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

131
r ealizando en el const r uct or de la I G.

FlowLayout : Est e layout per mit e en gener al poner un ar r eglo de component es uno al lado
del ot r o per o con t amaño var iable de cada uno, como si se est uvier a poniendo
una caj it a al lado de ot r a.




Por ej emplo, est e ar r eglo de bot ones se puede ut ilizar dent r o de una I G y se
declar a de la f or ma:

...
f.setLayout(new FlowLayout());
...

donde f es el f r ame que se quier e usar . Una vez que se set ea, se van
poniendo en or den las component es con cada void add(Component ) que se va
r ealizando en el const r uct or de la I G.

Bor der Layout : Est e layout es el más elabor ado y ut iliza una dist r ibución de punt os
car dinales par a las component es que se van inser t ando.













Par a cr ear una gr illa como est a se debe hacer :

...
f.setLayout(new BorderLayout());
...

donde f es el f r ame al cual se le asigna esa gr illa. Una vez que se set ea la
gr illa, las component es deben ser asignadas según dónde van con add(pos,
Component e). La posición es un St r ing que cor r esponde al ár ea deseada
“Nor t h”, “Sout h”, et c.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

132
Exist en ot r os Layout s más complej os, per o con una composición de est os 3 se puede cr ear lo
que uno desee.
Panel
Los paneles son component es “cont enedor as” que nos per mit en cr ear sub-int er f aces dent r o de
nuest r os Fr ames. El uso de paneles es una f or ma muy út i l, ya que par a componer o mezclar
dist int os Layout s de pant alla, ut ilizamos paneles.

También, dent r o del panel podemos t r abaj ar como si f uese un f r ame, es decir , agr egamos
component es a libr e elección según el layout seleccionado.

La def inición de un panel se hace a t r avés de obj et os de la clase Panel
14
:

Mét odo Descr ipción
Panel() Const r uct or del panel.
void set Layout (Layout ) Le indica la gr illa que va a ut ilizar el panel par a cont ener los
component es.
void add(Component ) Pone la component e dent r o del panel en la pr imer a posición
libr e del mismo (dependiendo de la gr illa).
void add(St r ing, Component ) Pone la component e dent r o del panel y en la posición de la
gr illa indicada en el par ámet r o St r ing.

Un ej emplo de uso ser ía el siguient e pr ogr ama:

public class MiInterfazGrafica {
// Frame
private Frame ventana;

// Paneles
private Panel p;

public MiInterfazGrafica() {
ventana = new Frame("Mi Interfaz Gráfica");
ventana.setLayout(new GridLayout(4, 4));

p = new Panel();
p.setLayout(new BorderLayout());

... // Creación de la interfaz

ventana.add(p);

ventana.pack();
ventana.show();
}
}

Como podemos ver en el ej emplo, est amos cr eando un f r ame de dist r ibución cuadr ada de 4x4 y
con un panel en la pr imer a casilla con dist r ibución de Bor der Layout .

14
Panel posee más mét odos, per o par a ef ect os académicos no nos ser án út iles.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

133

I mpor t ant e: Recuer da que par a cr ear int er f aces más complej as, la idea es siempr e ir
componiendo a t r avés de paneles par a llegar a los Layout s básicos.

I maginemos que quer emos la siguient e dist r ibución:


Podemos dist inguir clar ament e var i os paneles dent r o de est e f r ame
15
:

§ El Layout del f r ame es Bor der Layout (mar cado más gr ueso)
§ En el cent r o hay un Panel con Gr idLayout de 3 x 3.
§ En la izquier da hay un Panel con Gr idLayout de 8 x 1.
§ Abaj o puede ser un Panel con Gr idLayout de 1 x 2 o FlowLayout .
§ A la der echa y ar r iba no es necesar io un Panel.

y eso quedar ía escr it o cómo:

public class MiInterfazGrafica {
private Frame ventana;
private Panel p1, p2, p3;

public MiInterfazGrafica() {
ventana = new Frame("Mi Interfaz Gráfica");
ventana.setLayout(new BorderLayout());

p1 = new Panel();
p1.setLayout(new GridLayout(3, 3));
ventana.add("Center", p1);


15
Todas est as líneas son imaginar ias, ya que la dist r ibución se ve r ef lej ad a en las component es
que cada panel cont iene r ealment e.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

134
p2 = new Panel();
p2.setLayout(new GridLayout(8, 1));
ventana.add("West", p2);

p3 = new Panel();
p3.setLayout(new FlowLayout());
ventana.add("South", p3);

ventana.pack();
ventana.show();
}
}

Ahor a veamos ot r as component es par a que vayamos cr eando nuest r as int er f aces:
Label
Las ár eas de t ext o o et iquet as son súmament e út il en t odas las int er f aces, ya que pueden
ser vir nos de inf or mat ivos o más bien de t ít ulos par a algunas cosas. La clase Label posee los
siguient es (r educidos) mét odos:

Mét odo Descr ipción
Label(St r ing) Const r uct or del label que pone el t ext o en su cont enido.
Label(St r ing, int ) Const r uct or del label que pone el t ext o en su cont enido y lo
alínea según el segundo par ámet r o.

El alineamient o que va como par ámet r o es ident if icado como:
§ Label.CENTER
§ Label.LEFT
§ Label.RI GHT
St r ing get Text () Ret or na el t ext o que posee el label.
void set Text (St r ing) Cambia el t ext o or iginal por ot r o que va como par ámet r o.
void set Alignment (int ) Alinea el t ext o dent r o del label.

El alineamient o que va como par ámet r o es ident if icado como:
§ Label.CENTER
§ Label.LEFT
§ Label.RI GHT

Ej emplo:

// Crear un label con un texto fijo
Label titulo = new Label(”Este es un tıtulo¨);

// Cambiar el texto del label
titulo.setText(”Cambio de tıtulo¨);

// Alinea a la derecha el label
titulo.setAlignment(Label.RIGHT);

// Crea un nuevo label, centrado, con el texto del otro
Label tit2 = new Label(titulo.getText(), Label.CENTER);
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

135
Text Field
Son campos de ingr eso de dat os de una sola línea.

La clase Text Field posee los siguient es (r educidos) mét odos:

Mét odo Descr ipción
Text Field() Const r uct or de un t ext f ield vacío.
Text Field(int ) Const r uct or de un t ext f ield de lar go def inido.
Text Field(St r ing) Const r uct or de un t ext f ield con un t ext o def inido.
Text Field(St r ing, int ) Const r uct or de un t ext f ield con un t ext y lar go def inido.
void set Columns(int ) Fij a el lar go del t ext f ield.
void set Text (St r ing) Pone el t ext o como cont enido del t ext f ield.
St r ing get Text () Ret or na el t ext o del t ext f ield.
void set Edit able(boolean) Conf igur a par a que el t ext f ield sea edit able (TRUE) o solo de
lect ur a (FALSE).
boolean isEdit able() Ret or na si el t ext f ield es edit able (TRUE) o no (FALSE).

Ej emplo:

// Crea un textfield de 20 caracteres de largo
TextField tf = new TextField(20);

// Lo pone como solo de lectura
tf.setEditable(false);

// Escribe en el textfield un texto
tf.setText(”Este texto es fijo¨);
But t on
Las component es but t ons son sencillos bot ones de acción que se ut ilizan en las int er f aces
gr áf icas como gat illador es de event os específ icos (ver sección de event os más adelant e).


La clase But t on posee los siguient es mét odos:

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

136
Mét odo Descr ipción
But t on() Const r uct or de un bot ón vacío.
But t on(St r ing) Const r uct or que da a un bot ón un t ext o como et iquet a.
void set Label(St r ing) Asigna a un bot ón una et iquet a específ ica.
void set Enable(boolean) Act iva (TRUE) o desact iva (FALSE) el bot ón.
boolean isEnabled() Ret or na si el bot ón est á act ivado (TRUE) o desact ivado
(FALSE).

Por ej emplo:

// Creamos un botón con texto
Button b = new Button (”Aceptar¨);

// Desactivamos el botón
b.setEnable(false);
Text Ar ea
Los t ext ar ea son ár eas de t ext o en donde se pueden escr ibir múlt iples líneas, a dif er encia de
los t ext f ield.

La clase Text Ar ea posee los sigui ent es mét odos:

Mét odo Descr ipción
Text Ar ea() Const r uct or de un t ext ar ea vacío.
Text Ar ea(int , int ) Const r uct or de un t ext ar ea de lar go def inido como f ilas x
columnas.
Text Ar ea(St r ing) Const r uct or de un t ext ar ea con un t ext o def inido.
Text Ar ea(St r ing, int , int ) Const r uct or de un t ext ar ea con un t ext y lar go def inido con
f ilas x columnas.
Text Ar ea(St r ing, int , int , int ) Const r uct or de un t ext ar ea con un t ext , lar go def inido con
f ilas x columnas y los scr ollbar s:

§ Text Ar ea.SCROLLBARS_BOTH
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

137
Mét odo Descr ipción
§ Text Ar ea.SCROLLBARS_HORI ZONTAL_ONLY
§ Text Ar ea.SCROLLBARS_VERTI CAL_ONLY
§ Text Ar ea.SCROLLBARS_NONE
void set Columns(int ) Fij a la cant idad de columnas del t ext ar ea.
void set Rows(int ) Fij a la cant idad de f ilas del t ext ar ea.
void set Text (St r ing) Pone el t ext o como cont enido del t ext ar ea.
St r ing get Text () Ret or na el t ext o del t ext ar ea.
void set Edit able(boolean) Conf igur a par a que el t ext ar ea sea edit able (TRUE) o solo de
lect ur a (FALSE).
boolean isEdit able() Ret or na si el t ext ar ea es edit able (TRUE) o no (FALSE).

Por ej emplo, par a gener al la vent ana que apar ece como ej emplo, es necesar io cr ear el t ext ar ea
de la siguient e f or ma:


Textarea area = new TextArea(10, 30);

Choice
El choice es un element o de selección que puede ser t omado desde una list a más gr ande de
dat os.

Una vez que uno pr esiona la f lecha del cost ado der echo, apar ece la list a complet a de valor es
del choice. La clase Choice se def ine como:

Mét odo Descr ipción
Choice() Const r uct or de un choice vacío.
void add(St r ing) Agr ega un nuevo element o al choice (al f inal).
void inser t (St r ing, int ) I nser t a un nuevo element o al choice en la posición indicada.
int get I t emCount () Ret or na el númer o de element os que t iene el choice.
int get Select edI ndex() Ret or na el índice del element o seleccionado.
St r ing get Select edI t em() Ret or na el valor del element o seleccionado.
St r ing get I t em(int ) Ret or na el element o de la posición indicada.
void select (int ) Selecciona el element o de la posición indicada.
void select (St r ing) Selecciona el element o indicado.

Por ej emplo

Choice c = new Choice();
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

138
for (int i=2000; i<2100; i++) {
c.add(”Año ” + i);
}

Est a list a ent r egar ía t odos los años ent r e el 2000 y el 2099.
Li st
Las list as son uno de los element os más út iles después de los bot ones y las ár eas de t ext o.

La clase List del awt posee la siguient e def inición:

Mét odo Descr ipción
List () Const r uct or de una list a vacía con un númer o de líneas visibles
igual a 4 con selección única.
List (int ) Const r uct or de una list a con un númer o de líneas visibles
def inido y selección única.
List (int , boolean) Const r uct or de una list a con un númer o de líneas visibles
def inido y con opción de selección única (FALSE) o múlt iple
(TRUE).
void add(St r ing) Agr ega una nueva opción al f inal de la list a.
void add(St r ing, int ) Agr ega una nueva opción en la posición indicada.
void select (int ) Selecciona el element o de la posición indicada.
boolean isI ndexSelect ed(int ) I ndica si una posición est á (TRUE) o no (FALSE) seleccionada.
int get I t emCount () Ret or na la cant idad de element os de la list a.
int get Select edI ndex() (Modo de selección simple) Ent r ega el índice del element o
seleccionado.
int [ ] get Select edI ndexes() (Modo de selección múlt iple) Ent r ega un ar r eglo con t odos los
índices seleccionados.

Por ej emplo, si quer emos una list a con muchas opciones:

List l = new List(10, false);
for (int i=0; i<100; i++) {
l.add(”Opción ” + i);
}

Est a list a ent r egar ía 100 opciones con selección simple.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

139
Checkbox y CheckboxGr oup
Los checkboxes son opciones que per mit en mar car un t ext o específ ico y que le per mit en al
pr ogr amador int er act uar con opciones (alt er nat ivas). Dependiendo si se usan la opción de gr upo
checkboxgr oup, es dependiendo si se puede o no mar car múlt iples opciones.


La clase Checkbox ident if ica solo una opción de selección con est os disposit ivos y posee la
siguient e def inición:

Mét odo Descr ipción
Checkbox() Cr ea una opción vacía.
Checkbox(St r ing) Cr ea una opción con un t ext o def inido.
Checkbox(St r ing, boolean) Cr ea una opción con un t ext o y le indica si est á o no
mar cada.
Checkbox(St r ing, boolean,
CheckboxGr oup)

o bi en

Checkbox(St r ing, CheckboxGr oup,
boolean)
Cr ea una opción con un t ext o, indicando si est á o no
mar cada y además agr upada según un gr upo de
opciones.

Al asignar las al mismo gr upo, las opciones quedan
con la posibilidad de mar car SOLO 1 de ellas, y su
f or ma cambia a la de select or r edondo en vez del
cuadr ado (como se ve en la f igur a).

Si no se desea ningún gr upo, est a opción debe ser
“null”.
void set Label(St r ing) Pone el t ext o a la et i quet a que acompaña al
select or .
boolean get St at e() Ret or na si la opción si est á seleccionada (TRUE) o
no (FALSE).
void set CheckboxGr oup(CheckboxGr oup) Asigna al gr upo la opción.
CheckboxGr oup get CheckboxGr oup() Obt iene el gr upo al que per t enece la opción.

Por ej emplo, si quer emos un select or de sexo de una per sona (si es Masculino o Femenino)
hacemos:

CheckboxGroup sexo = new ChekboxGroup();
Checkbox sexoM = new Checkbox(”Masculino¨, sexo, true);
Checkbox sexoF = new Checkbox(”Femenino¨, sexo, false);

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

140
Per o si quer emos sabes por ej emplo los gr upos de int er és de un usuar io, podemos hacer un
gr upo de selección dif er enciada:

Checkbox gr01 = new Checkbox(”Deportes¨, null, false);
Checkbox gr02 = new Checkbox(”Música¨, null, false);
Checkbox gr03 = new Checkbox(”Televisión¨, null, false);
...
Canvas
Un canvas es un r ect ángulo blanco dent r o de la int er f az en donde se puede dibuj ar cualquier
cosa (t ext o, líneas, polígonos) y se puede at r apar event os sobr e él.

La clase Canvas est á def inida como:

Mét odo Descr ipción
Canvas() Const r uct or que cr ea un canvas.
void paint (Gr aphics) Per mit e r e-dibuj ar en el canvas lo que est é almacenado en él.

Por ser un t ema especial, canvas lo dej ar emos par a más adelant e.
Ej emplos de Component es
Un pr imer ej emplo de ut ilización de component es es el j uego del gat o (solo int er f az):

Est a int er f az sencillit a, es r esuelt a por el siguient e pr ogr ama:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Gato {
private Frame ventana;

// Acá van solo las componentes que son útiles
// para el programa
private Choice jugadas[][];
private Button salir;

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

141
public MiInterfazGrafica() {
ventana = new Frame("Juego del Gato");
ventana.setLayout(new GridLayout(3, 1));

// Le ponemos el tıtulo a nuestro ejemplo
Label titulo = new Label("Gato", Label.CENTER);
ventana.add(titulo);

// Dibujamos el tablero para jugar gato
Panel gato = new Panel();
gato.setLayout(new GridLayout(3, 3));

Choice jugadas[][] = new Choice[3][3];
for(int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
jugadas[i][j] = new Choice();
jugadas[i][j].add(" ");
jugadas[i][j].add("X");
jugadas[i][j].add("O");
gato.add(jugadas[i][j]);
}
}

ventana.add(gato);

// Y el botón de salida del juego
salir = new Button("Terminar");
ventana.add(salir);

ventana.pack();
ventana.show();
}
}

Y por supuest o, nuest r o amigo y her mano ej emplo: El pr ogr ama J alisco.

Que se r esuelve con el siguient e código:

public class Jalisco {
private Frame ventana;

private TextField numero;
private Button ok;

public MiInterfazGrafica() {
ventana = new Frame("Jalisco");
ventana.setLayout(new FlowLayout());

// Esto nos puede evitar tener una variable para el
// texto que no nos sirve más.
ventana.add(new Label("Ingresa un número? "));

numero = new TextField(4);
ventana.add(numero);

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

142
ok = new Button("Ok");
ventana.add(ok);

ventana.pack();
ventana.show();
}
}
Pr opiedades her edadas de Component
Todas las component es est án def inidas como clases dent r o de la est r uct ur a de la API . Es por
eso que t odas ellas t ienen una super clase llamada Component y que posee algunas pr opiedades y
f uncionalidades especiales que af ect an a t odas.




















La clase Component posee las siguient es f uncionalidades út iles
16
:

Mét odo Descr ipción
void set Visible(boolean) Hace apar ecer (TRUE) o desapar ecer (FALSE) la component e.
boolean isVisible() Ver if ica si la component e est á (TRUE) o no (FALSE) visible.
void set Size(int , int ) Le da un t amaño dado por lar go x ancho par a la component e.
void set Size(Dimension) Le da un t amaño dado por un obj et o a un t ipo Dimension.
Dimension get Size() Obt iene en un obj et o Dimension el t amaño de l a component e.
void set Locat i on(int , int ) Pone la component e en la posición (x, y).
void set Locat ion(Point ) Pone la component e en la posición dada por el obj et o Point .
Point get Locat ion() Obt iene la posición de la component e en un obj et o Point .

16
Todos est os mét odos son solo un ext r act o de los que r ealment e t iene la clase Component .
Par a mayor inf or mación se r ecomienda consult ar la document ación de la API de J DK 1.3 en:
ht t p:/ / j ava.sun.com/ j 2se/ 1.3/ docs/ api/ j ava/ awt / Component .ht ml
Component
Label
Text Component
But t on Choice
List
Checkbox
Text Field Text Ar ea
Canvas
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

143
Mét odo Descr ipción
void set Font (Font ) A la component e le da un est ilo de let r a. Par a dar le un f ont , uno
puede ut ilizar el const r uct or de la clase Font :

x.set Font (new Font (“Ar ial”, Font .I TALI C, 12));
Font get Font () Obt iene el est ilo que t iene el component e.
void set Backgr ound(Color )
y t ambién
void set For egr ound(Color )
Le da color al f ondo (Back) o al f ont (For e) de la component e.
Par a ut ilizar el color , se usa la clase Color :

x.set Backgr ound(Color .black);

o t ambién se puede obt ener gr acias a la r epr esent ación de
color es en codif icación RGB (cant idad de Roj o, Ver de y Azúl):

x.set For egr ound((new Color (100, 100, 100)).get Color ());
Color get Backgr ound()
y t ambién
Colo get For egr ount ()
Obt iene el color que est á def i nido par a la component e en el
f ondo (Back) o en el f ont (For e).
void r epaint () Redibuj a t oda la component e.
Concept os
Event o
Acción que ocur r e dent r o en una component e y que es ut ilizada par a
gat illar acciones sobr e la int er f az (al pr esionar un bot ón, al escr ibir un
t ext o o al hacer click en un ár ea específ ica).

El f uncionamient o de las int er f aces gr áf icas no es aut omát ico como lo hace cualquier
pr ogr ama, pues debe haber alguna int er acción con el usuar io en algún moment o. Hast a ahor a
habíamos vist o esa int er acción como un ingr eso por t eclado de dat os por par t e del usuar io. En
las I G (I nt er f aces Gr áf icas) exist en ot r as f or mas de ingr eso de dat os que cor r esponden a
disposit ivos comunes como son el t eclado y el mouse.

Esos ingr esos o esa int er acción se hace a t r avés de los event os.






Al hacer click en el bot ón
“Ok” se est á gat illando un
event o de acci ón en la I G.
Al escr ibir un t ext o en la casilla se
est á gat illando un event o dent r o de
la I G.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

144
Li st ener
Element o que le per mit e a un component e det ect ar cuándo ocur r e un
event o sobr e él e indicar qué debe hacer en la int er f az.

Tal como dice la def inición, los list ener s son asignados a obj et os o component es de una I G y le
per mit en dar se cuent a cuándo les est án enviando un event o a ellos.

Al moment o de decir le al component e: “escucha el event o”, se le dice t ambién que cuando
ocur r a r ealice cier t as acciones. Esas acciones pueden ser cambios en la int er f az, acciones
sobr e ar chivos, bases de dat os, et c.
Sint axis
En las int er f aces gr áf icas par a J ava exist en dist int os t ipos de event os, que son capt ur ados por
los list ener . Algunos de est os event os son:
Event os de Acción (Act ionEvent )
Cualquier acción que es gat illada por una component e se le llama event o de acción. Est os
event os son r epr esent ados por l a clase Act ionEvent y es ella la que se encar ga de almacenar a
qué component e cor r esponde el event o.

Par a capt ur ar est os event os, es necesar io ut ilizar un list ener del t ipo Act ionList ener :

...
Button b = new Button(”Activa¨);
b.addActionListener(new <Listener de Accion Personalizado>);
...

de est a f or ma, le decimos a la I G que, al ocur r ir un event o de acción sobr e la component e
(act ivar el bot ón en est e caso) que capt ur e ese event o y ej ecut e el “List ener de Acción
Per sonalizado”.

Est e list ener debe ser declar ado dent r o de la I G como una nueva clase (¡si! una clase dent r o de
ot r a) que implement e un Act ionList ener . Por ej emplo:

...
public class MiInterfazGrafica {
...
public MiInterfazGrafica() {
...
t = new TextField(20);
t.addActionListener(new MiActionListener);
...
}
...
class MiActionListener implements ActionListener {
...
}
...
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

145

Así, le est ar íamos indicando a nuest r a I G que el list ener que quer emos ut ilizar se llama
MiAct ionList ener . Est e es solo el nombr e y podr ías haber ut ilizado el que t e gust e más.

Todas las clases que implement en un Act ionList ener DEBEN t ener est a est r uct ur a f ij a:

class <nombre> implements ActionListener {
public void actionPerformed(ActionEvent e) {
// Aquı van las acciones que se ejecutan cuando ocurre
// un ActionEvent
}
}

Las acciones que se ej ecut an pueden ut ilizar element os de la I G libr ement e, ya que por est ar
dent r o de la misma clase pueden acceder a t odos los element os de ella sin necesit ar de un
obj et o.

Veamos el t ípico ej emplo del pr ogr ama J alisco con event os:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

class Jalisco {
// Acá esta nuestra IG fısicamente referenciada
private Frame programa;

// Estos son los componentes que van a actuar cuando ocurre el
// ActionEvent respectivo
private Label respuesta;
private TextField numero;
private Button salir;

public Jalisco() {
// Creamos nuestra nueva ventana
programa = new Frame("Jalisco");
programa.setLayout(new GridLayout(3, 1));

// Ponemos el texto antes del campo de datos
programa.add(new Label("Ingresa un número? ",
Label.CENTER));

// Ponemos el cuadro de ingreso del usuario
numero = new TextField(4);
numero.addActionListener(new UnEscuchador());
programa.add(numero);

// Ponemos el area en donde el computador da
// su respuesta
respuesta = new Label("", Label.CENTER);
programa.add(respuesta);

// Mostramos la IG
programa.pack();
programa.show();
}
...

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

146
Hast a aquí vamos bien, ya que la única dif er encia con lo que ya habíamos vist o es la línea en la
cual le indicamos el Act ionList ener a la I G. En est a opor t unidad, el Act ionList ener lo ponemos
en el Text Field (ingr eso de dat os) par a que se act ive SOLO SI el usuar io pr esiona ENTER
dent r o de esa casilla (simulando que ingr esa númer o y pr esiona ENTER).

...
class UnEscuchador implements ActionListener {
public void actionPerformed(ActionEvent e) {
int n = Integer.parseInt(numero.getText());
respuesta.setText((n+1) + " te gané!!!");
numero.setText("");
}
} // Fin del ActionListener
} // Fin de la IG

Est e ej emplo pr oduce est a vent ana:

suponiendo la sit uación de que el usuar io ingr ese 27 como númer o de ent r ada. Cada vez que el
usuar io pr esione ENTER en la casilla de t ext o dej ada par a que ingr ese su númer o, el
comput ador t omar á ese númer o (con el comando numer o. get Text ()) y lo pondr á como valor de
ent r ada en la casilla de r espuest as sumado en 1, es decir :

// Toma el número de la casilla de texto (numero) y lo transforma
// a un entero dejándolo en la variable n
int n = Integer.parseInt(numero.getText());

// Escribe en el area de respuesta el número que ingreso el usuario
// (n) incrementado en 1 (n+1) y el texto ”te gané!!!¨
respuesta.setText((n+1) + " te gané!!!");

// Borra el contenido de la casilla de texto.
numero.setText("");

Así de simple f unciona.

Not a: Par a que un applet se cier r e al pr esionar un bot ón, en el Act ionList ener def inido par a
ese bot ón se debe usar Syst em. exit (0).
Event os del Mouse (MouseEvent )
Los event os del mouse son event os que pueden ocur r i r sobr e una component e cuando con el
mouse uno r ealiza algo: ingr esar a la component e, pr esionar el bot ón, solt ar el bot ón, salir de la
component e, mover se, et c.

Par a capt ur ar los MouseEvent s es necesar io ut ilizar un escuchador del t ipo MouseList ener
(caso obvio después de ver los Act ionList ener s) o uno del t ipo MouseMot ionList ener .
27
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

147

...
Canvas c = new Canvas();
b.addMouseListener(new <Listener de Raton Personalizado>);
...

A dif er encia de los Act ionList ener s, los MouseList ener s t ienen una est r uct ur a más complej a,
por que los event os posibles por el mouse son más que uno solo. Es por eso que la est r uct ur a de
los MousList ener s cambia:

class <nombre> implements MouseListener {
public void mouseClicked(MouseEvent e) {
// Se ejecuta solo cuando se hace un click del mouse
}

public void mouseEntered(MouseEvent e) {
// Se ejecuta solo cuando el mouse ingresa a una
// componente (el puntero ingresa al área de la
// componente)
}

public void mouseExited(MouseEvent e) {
// Se ejecuta solo cuando el mouse abandona a una
// componente (el puntero abandona del área de la
// componente)
}

public void mousePressed(MouseEvent e) {
// Se ejecuta solo cuando el botón del mouse es
// presionado y se mantiene ası (no es un click rápido)
}

public void mouseReleased(MouseEvent e) {
// Se ejecuta solo cuando el botón del mouse es
// soltado después de ser presionado (caso anterior)
}
}

Como pueden ver la cant idad de cosas que hay que implement ar es más gr ande. Per o ¿qué pasa
si solo quier o hacer algo cuando el usuar io hace CLI CK en el mouse? Pues simplement e debes
dej ar los ot r os mét odos en blanco y escr ibir solo en el mét odo que cor r esponde al event o de
CLI CK del mouse:

class UnEventoClick implements MouseListener {
public void mouseClicked(MouseEvent e) {
// ACA SE ESCRIBE CODIGO
}

public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
}

y así f unciona. Veamos un ej emplo sencillo. J uguemos al Gat o ent r e 2 per sonas:

import java.applet.*;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

148
import java.awt.*;
import java.awt.event.*;

public class Gato {
// IG
private Frame ventana;

// Para despliegue de mensajes de sistema
private Label mensaje;

// El GATO
private TextField[][] gato;

// Quien juega
private boolean jugador1;

public Gato() {
ventana = new Frame("Gato");
ventana.setLayout(new BorderLayout());

ventana.add("North",
new Label("Juego del Gato", Label.CENTER));

mensaje = new Label("Jugador 1", Label.CENTER);
jugador1 = true;
ventana.add("South", mensaje);

// Creamos el arreglo para el gato y
// el panel que lo contiene
Panel pgato = new Panel();
gato = new TextField[3][3];
pgato.setLayout(new GridLayout(3, 3));
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
gato[i][j] = new TextField(1);
// A cada casilla le ponemos un
// mouselistener
gato[i][j].addMouseListener(
new JuegaGato());
pgato.add(gato[i][j]);
}
}
ventana.add("Center", pgato);

// Está listo el juego
ventana.pack();
ventana.show();
}
...

Hast a aquí t enemos la int er f az def inida par a quedar de la siguient e f or ma:

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

149
Ahor a manipulemos que, cuando el usuar io haga click sobr e los campos en blanco se ponga una
“X” o una “O” dependiendo si es el j ugador 1 o 2 r espect ivament e:

...
class JuegaGato implements MouseListener {
public void mouseClicked(MouseEvent e) {
// Buscamos casilla seleccionada
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
if (e.getSource() == gato[i][j]) {
if (jugador1) {
gato[i][j].setText("X");
jugador1 = false;
mensaje.setText("Jugador 2");
}
else {
gato[i][j].setText("O");
jugador1 = true;
mensaje.setText("Jugador 1");
}
}
}
}
}

public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
}
}

Como podemos ver , solo implement amos el mét odo mouseClicked(MouseEvent e) par a
solucionar el t ema de mar car el gat o. Así evit amos hacer los demás mét odos.

Not a: Ut ilizamos algo nuevo par a ident if icar qué component e se est á haciendo click. Si
pensamos un poco, son 9 casillas dist int as que gat illan el mismo event o. Podr íamos hacer 9
event os dist int os, per o eso es poco ópt imo. Así que dif er enciamos dent r o de los list ener s a
cuál component e cor r esponde con el mét odo get Sour ce() del event o.

e. get Sour ce() : Ret or na una r ef er encia a la component e a la cual se le accionó el event o.

Es por eso que podemos compar ar lo con la component e en f or ma dir ect a como

...
if (e.getSource() == gato[i][j]) {
...
}
...

ya que le est amos diciendo implícit ament e “ si el event o f ue gat illado sobr e la component e
gat o[ i] [ j ] ...”. Est e mét odo sir ve no solo par a los MouseEvent s, si no que par a cualquier event o
(Act ionEvent , I t emEvent , et c.).

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

150
El ot r o t ipo de list ener par a el mouse es el MouseMot ionList ener quien se pr eocupa de los
movimient os libr es que el mouse puede r ealizar :

class <nombre> implements MouseMotionListener {
public void mouseDragged(MouseEvent e) {
// Se ejecuta solo cuando se presiona el botón en una
// componente y luego se arrastra.
}

public void mouseMoved(MouseEvent e) {
// Se ejecuta solo cuando el mouse se muerve dentro
// del área de una componente, cualquiera sea.
}
}

Par a est os últ imos event os es muy i mpor t ant e dest acar que la var iable e, además de ident if icar
la component e seleccionada, posee ot r as car act er íst icas (mét odos) que pueden ser de gr an
impor t ancia:

Mét odo Descr ipción
int get ClickCount () Ret or na el númer o de cli cks que se r ealizar on.
int get X() y int get Y() Ret or na el valor de la posición hor izont al (X) y ver t ical (Y)
donde ocur r ió el event o, r elat ivo a la component e asignada.

Todo est o r esult a út il cuando est amos t r at ando de dibuj ar en un Canvas, sin embar go, est os
mét odos se pueden ut ilizar dent r o del MouseList ener sin pr oblemas (si f uer a necesar io).
Event os de Selección (I t emEvent )
Los event os de selección son event os que ocur r en cuando en una component e de selección
(Checkbox, List o Choice) cambia su est ado, es decir , se selecciona un it em o se act iva o
desact iva una opción.

Par a capt ur ar los I t emEvent s es necesar io ut ilizar un escuchador del t ipo I t emList ener .

...
List c = new List(10);
b.addItemListener(new <Listener de Seleccion Personalizado>);
...

Al igual que los MouseEvent s, los list ener s de est e t ipo poseen un mét odo que DEBE ser
implement ado par a poder capt ur ar los I t emEvent s:

class <nombre> implements ItemListener {
public void itemStateChanged(ItemEvent e) {
// Aquı van las acciones que se ejecutan cuando ocurre
// un ItemEvent
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

151
Más Event os
Ot r os event os que se pueden ut ilizar se det allan en la siguient e t abla:

Event o List ener Mét odos a I mplement ar en el List ener
de Text o Text List ener void t ext ValueChanged(Text Event e)
void keyPr essed(KeyEvent e)
void keyReleased(KeyEvent e)
del Teclado KeyList ener
void keyTyped(KeyEvent e)
void windowAct ivat ed(WindowEvent e)
void windowClosed(Event e)
void windowClosing(Event e)
void windowDeact ivat ed(Event e)
void windowDeiconif ied(Event e)
de Vent ana WindowList ener
void windowOpened(Event e)

Sin dej ar de consider ar que t oda la inf or mación que se ha desplegado es simplement e
r ef er encial y no necesar iament e est á complet a. Par a mayor inf or mación se r ecomienda visit ar
la página de la API de J DK en la página de la empr esa SUN Micr osyst ems
17
.
Canvas
Ahor a veamos como se ut iliza la component e Canvas en las int er f aces gr áf icas.

En el Canvas, al igual que en ot r as component es, pueden ocur r ir event os de lo más nor males. De
hecho, una f or ma de poner un Canvas en una I G es igual que cualquier ot r a component e,
indicando eso si el t amaño de él:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Paint {
private Frame programa;
private Canvas area;

public Paint() {
programa = new Frame("Java Paint");
programa.setLayout(new FlowLayout());

area = new Canvas();
area.setSize(800, 600);
area.addMouseListener(new Pincel());

programa.add(area);
programa.pack();
programa.show();
}
...
}


17
API del J DK: ht t p:/ / j ava.sun.com/ j 2se/ 1.3/ docs/ api/ index.ht ml
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

152
Como se ve en el ej emplo, lo que est amos haciendo es cr eando un Canvas de 800 x 600 pixeles
de t amaño, solo en la I G con la int ención de que al ocur r ir un event o de mouse, el list ener
llamado Pincel lo capt ur e.

Per o ¿cuál es la gr an dif er encia con los component es que ya hemos vist o? hast a aquí, ninguna,
pues cambia cuando t enemos que dibuj ar sobr e el Canvas algun element o.
Gr aphics
Est a clase es ut ilizada por el canvas par a dibuj ar . Gr aphics a dif er encia de las component es de
las I G es una clase que cont r ola el cont enido de un Canvas y no t iene nada que ver con su layout
o event os que ocur r an por que no es un espacio f ísico en pant alla.

Se def inen los mét odos de l a clase Gr aphics:

Mét odo Descr ipción
set Color (Color ) Cambia el pincel al color de t ipo Color . Los color es se
def inen como const ant es en la clase Color :

§ Color .black = Negr o
§ Color .whit e = Blanco
§ Color .blue = Azúl
§ Color .r ed = Roj o
§ Color .gr een = Ver de
§ Color .yellow = Amar illo
§ et c

Una vez que se set ea el color , t odas las f igur as que se
r ealicen quedan con ese color def inidas.

Si quier es def inir más color es, busca la document ación de
la clase Color en el sit io de la API del J DK.
dr awLine(int , int , int , int ) Dibuj a una línea ent r e el punt o 1 (x, y) y el punt o 2 (x, y).
dr awOval(int , i nt , int , int ) Dibuj a el cont or no de una elipse en la posición cent r o (x,
y) con un t amaño hor izont al y ver t ical def inido.
f illOval(int , int , int , int ) Dibuj a una elipse r ellena en la posición cent r o (x, y) con
un t amaño hor izont al y ver t ical def inido.
dr awRect (int , i nt , int , int ) Dibuj a el cont or no de un r ect ángulo con vér t ice super ior
izquier do (x, y) y un t amaño hor izont al y ver t ical
def inido.
f illRect (int , int , int , int ) Dibuj a un r ect ángulo r elleno con vér t ice super ior
izquier do (x, y) y un t amaño hor izont al y ver t ical
def inido.
set Font (Font ) Pone un est ilo de let r a especif ico a los element os de
t ext o que se escr iban en adelant e.
dr awSt r ing(St r ing, int , int ) Escr ibe el t ext o en la posición (x, y) de la I G.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

153
Mét odo Descr ipción
clear Rect (int , int , int , int ) Limpia un ár ea def inida por el r ect ángulo asociado (ver
dr awRect ).

Con est os mét odos, podemos hacer muchas cosas. Veamos un ej emplo de ut ilización del canvas:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Paint {
// Las componentes importates de la IG
private Frame programa;
private Canvas area;
private Label pos;
private Button salir;

public Paint() {
// Creamos primero la ventana de nuestro Paint
programa = new Frame("Java Paint");
programa.setLayout(new GridLayout(3, 1));

// Le ponemos un LABEL para la posición del Mouse
pos = new Label("", Label.CENTER);
programa.add(pos);

// Creamos el Canvas que nos permitirá dibujar en él
area = new Canvas();
area.setSize(800, 600);
area.addMouseListener(new Pincel());
area.addMouseMotionListener(new Movimiento());
programa.add(area);

// Ponemos un botón para terminar y cerrar la ventana
salir = new Button(”Salir¨);
salir.addActionListener(new AccionBoton());
Panel p = new Panel();
p.setLayout(new FlowLayout());
p.add(salir);
programa.add(p);

// Mostramos la IG creada
programa.pack();
programa.show();
}
...

Como podemos ver en est as pocas líneas, lo que quer emos hacer es un ár ea de dibuj o ut ilizando
un Canvas (muy similar al ej emplo que habíamos vist o ant er ior ment e).

Es muy impor t ant e dest acar var ios punt os:

§ El Canvas r ecibe acciones de MouseList ener y MouseMot ionList ener en est e ej emplo.
§ Exist e un bot ón que per mit ir á t er minar la ej ecución del pr ogr ama.
§ Hay un label que nos indicar á la posición (en pixeles) de donde se encuent r a el punt er o.

Todo est o queda dist r ibuído y nos muest r a algo como lo siguient e:
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

154


Per o como sabemos que el Canvas no es f acil de t r abaj ar , pr epar ar emos algunos mét odos que
nos per mit ir án hacer “algo” dent r o de él. En est e caso par t icular , nuest r o J ava Paint solo
dibuj ar á punt os (por ahor a):

...
// Acciones que se realizan dentro del Canvas
private void dibujaPunto(int x, int y) {
// Se obtiene primero el pincel del canvas
Graphics g = area.getGraphics();

// Seteamos el color azúl para dibujar el punto
g.setColor(Color.blue);

// Dibujamos un punto, es decir, un óvalo de radio 5
// pixeles x 5 pixeles en el punto x, y indicado en
// el parámetro.
g.fillOval(x, y, 5, 5);
}
...

Ahor a bien, como podemos ver no t enemos idea donde se est á dibuj ando cada punt o. Ese si
ser ía t r abaj o del list ener que, cuando se pr esione el bot ón del mouse nos diga en qué posición
(en pixeles) se hizo el click par a dibuj ar el punt o.

Ent onces, debemos implement ar el pr imer o de los list ener , que es el MouseList ener , el cual nos
per mit ir á hacer que si se pr esiona el bot ón del mouse, dibuj ar un punt o en la posición aquella,
ut ilizando el mét odo ant er ior ment e def inido:

...
class Pincel implements MouseListener {
public void mouseClicked(MouseEvent e) {
En est e sect or est á
nuest r o CANVAS
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

155
dibujaPunto(e.getX(), e.getY());
}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

public void mousePressed(MouseEvent e) {
dibujaPunto(e.getX(), e.getY());
}

public void mouseReleased(MouseEvent e) {
}
}
...

Como podemos ver suponemos en ambos event os en los cuales se pr esiona el bot ón (click y
pr essed) par a que dibuj e el punt o en x, y dado por e.get X() y e.get Y.

Ahor a implement emos el que nos indicar á en qué posición se encuent r a el mouse par a most r ar la
en el label que def inimos sobr e el ár ea de dibuj o:

...
class Movimiento implements MouseMotionListener {
public void mouseMoved(MouseEvent e) {
pos.setText("(" + e.getX() + ", " +
e.getY() + ")");
}

public void mouseDragged(MouseEvent e) {
}
}
...

En est e caso, mouseMoved nos indica si el mouse se mueve o no. Per o en est e caso no t enemos
que dibuj ar , per o si indicar en qué posición est á el punt er o del mouse. Es por eso que ponemos
esa posición como un par or denado en el label def inido sobr e el ár ea llamado pos.

Por últ imo, complet amos con el Act ionList ener par a el bot ón salir , el cual cier r a la I G:

...
class AccionBoton implements ActionListener {
public vois actionPerformed(ActionEvent e) {
// La IG se cierra si el programa termina
System.exit(0);
}
}
}
Pr oblemas
(a) Escr ibir la clase Consola que es una int er f az gr áf ica similar a la clase Console que hemos
ut ilizado hast a ahor a. Solo pr ogr ame los siguient es mét odos:

Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

156
Mét odo Descr ipción
Consola() Cr ea una consola con el t ít ulo “Consola” y de t amaño 320 x 240.
Consola(St r ing) Cr ea una consola con el t ít ulo i ndicado y de t amaño 320 x 240.
void impr imir (St r ing) I mpr ime dent r o de la consola el t ext o indicado en la posición
act ual sin salt o de línea.
void impr imi r sl(St r ing) I mpr ime dent r o de la consola el t ext o indicado en la posición
act ual salt ando una línea después de hacer lo.
void limpiar () Limpia la consola.

La I G que debe pr ogr amar debe ser similar a est a:


Not a: Los label vacío son solo par a dar le un t oque de mar gen al cuent o. Oj o con el Layout
que est á casi dir ect o con el gr áf ico.
Sol ución
Par t amos pr imer o por la par t e de dibuj o de la I G:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Consola {
// Primero van las componentes necesarias para controlar
// esta nueva consola.
private Frame ventana;
private Canvas area;
private Button salir;

// También necesitaremos un punto para indicar en donde nos
// encontraremos escribiendo dentro del Canvas
private int linea, caracter;
Canvas
Label vacío
Bot ón
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

157

public Consola(String titulo) {
// Creamos la ventana con BorderLayout, con el tıtulo
// pasado por parámetro y color de fondo gris claro.
ventana = new Frame(titulo);
ventana.setLayout(new BorderLayout());
ventana.setBackground(Color.lightGray);

// Creamos el Canvas de tamaño definido 320x240, con
// color de fondo blanco (diferenciarlo del frame) y
// puesto al centro del layout del frame.
area = new Canvas();
area.setSize(320, 240);
area.setBackground(Color.white);
ventana.add("Center", area);

// Creamos el botón salir y lo ponemos al sur del
// layout del frame. Ojo que para que quede pequeñito
// usamos un panel con FlowLayout.
salir = new Button("Salir");
Panel p = new Panel();
p.setLayout(new FlowLayout());
p.add(salir);
ventana.add("South", p);

// Le damos el listener para que cierre la ventana
// al click en el botón ”Salir¨.
salir.addActionListener(new Finalizar());

// Ponemos los labels vacıo de margen al rededor del
// Canvas, es decir, al norte, este y oeste.
ventana.add("North", new Label());
ventana.add("East", new Label());
ventana.add("West", new Label());

// Mostramos la ventana.
ventana.pack();
ventana.show();

// Inicializamos como inicio de escritura.
linea = 1;
caracter = 1;
}

public Consola() {
// Llama al otro constructor, pero con el tıtulo fijo.
this("Consola");
}

// Ahora le damos el listener del botón.
class Finalizar implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}

Una vez que la par t e gr áf ica est á list a, podemos poner los mét odos que t r abaj ar án sobr e el
canvas y escr ibir án o bor r ar án algo:

// Método que limpia la pantalla
public void limpiar() {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XV: Interfaces Graficas

158
// Obtenemos el pincel
Graphics g = area.getGraphics();

// Limpia la pantalla completa.
g.clearRect(0, 0, 320, 240);

// La posición vuelve al inicio.
linea = 1;
caracter = 1;
}

// Métodos que imprimen en pantalla
public void imprimir(String s) {
// Obtenemos el pincel
Graphics g = area.getGraphics();

// Escribimos el texto en el canvas
g.drawString(s, (caracter - 1)*7, linea * 12);

// Dejamos el cursor al final
caracter += s.length() + 1;
}

public void imprimirsl(String s) {
// Usamos el método anterior
imprimir(s);

// Movemos el lapiz a la lınea siguiente
linea++;
caracter = 1;
}
}

Como los car act er es son de un t amaño de 12 pixeles de alt o y 7 pixeles de ancho, podemos
simular que escr ibimos el st r ing en la posición (car act er -1)* 7, linea* 12 (consider ando que par a
escr ibir necesit amos indicar la base del st r ing).

Ahor a si pr obamos algo, podr emos saber como queda:

public class MiPrograma {
static public void main(String[] args) {
Consola c = new Consola("Mi Consola");
c.imprimirsl("1234567890");
c.imprimir("123");
c.imprimir("123");
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVI: Interfaces Graficas SWING

159
Capít ulo XVI : I nt er f aces Gr áf icas SWI NG
(En const r ucción)


Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

160
Capít ulo XVI I : Excepciones y Cont r ol de Er r or es
Mot ivaci ón
Lo más común al hacer pr ogr amas en J ava son los er r or es que apar ecen en la “pant alla de la
muer t e” o salida de er r or es.

Cómo manej ar los, ent ender lo y logr ar pr ever los posibles pr oblemas en t iempo de ej ecución es
un t r abaj o de lo que se llaman Excepciones. Lo más impor t ant e es que J ava pr ovee una f or ma
par a que el pr ogr amador cont r ole f ácilment e est os er r or es sin conocer las condiciones en las
que ocur r en pr eviament e, baj o solo suposiciones del est ilo “el ar chivo puede t ener pr oblemas
de lect ur a/ escr it ur a, no exist ir o simplement e est ar malo”.
Concept os
Exist en 2 clases de er r or es:
Er r or es de Compilación
Los er r or es de compilación son aquel los er r or es que son det ect ados por
el compilador (j avac) en el moment o en que se gener a l a clase ej ecut able
(ar chivo .class) deseada.

Est os er r or es comúnment e ocur r en cuando exist e un er r or de sint axis o f alt a alguna clase que
es llamada en los ar chivos que cr ea el pr ogr amador .

Lo int er esant e de est os er r or es es que se pueden det ect ar r ápidament e, pues el compilador
indica exact ament e qué pasó y donde ocur r ió, lo que los hace muy f ácil de cont r olar y cor r egir .
Sin embar go, lo int er esant e no es est a clase de er r or es sino la que viene a cont inuación.
Er r or es de Ej ecución (Runt ime)
Los er r or es que ocur r en en t iempo de ej ecución o r unt ime son
pr oblemas que, al moment o de ej ecut ar las clases ya compiladas, suelen
ocur r ir por ingr eso de dat os, manipulación de disposit ivos de
ent r ada/ salida, condiciones de bor de, conver sión de t ipos de dat os, et c.

Exist e una inf inidad de r azones de por qué el pr ogr ama se cae en t iempo de ej ecución. Veamos
un pequeño ej emplo:

public class UnArreglo {
static public void main (String[] args) {
int[] ar = new int[10];
ar[10] = 25;
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

161
Est e sencillísimo pr ogr ama lo que hace es asignar f uer a del r ango del ar r eglo un valor . Bueno, si
compilan est e pr ogr amit a, se dar án cuent a que no hay er r or det ect able. Per o al moment o de
ej ecut ar la clase UnAr r eglo, lanzar á el si guient e er r or :

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at UnArreglo.main(UnArreglo.java:4)

Est e t ext o indica el er r or o Excepción que ha ocur r ido al ej ecut ar la clase. Analicemos un poco
la excepción par a saber cómo solucionar la:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10

El t ext o dest acado Ar r ayI ndexOut BoundsExcept ion indica qué ha ocur r ido. En est e caso (y
solo bast ar ía ut ilizar un diccionar io de I nglés-Español) podemos dar nos cuent a que nos dice:

Excepción de Í ndice Fuer a del Rango del Ar r eglo.

Tenemos ident if icado cuál es el er r or (que obviament e er a el que pr edij imos al escr ibir el
pr ogr ama). Per o ¿dónde y por qué ocur r ió?. Bueno, cont inuemos el análisis.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10

Est e pequeño numer it o casualment e coincide con el valor del r ango que quer íamos sobr epasar .
Bueno, no es casualidad, por que en est e caso ese valor indica la posición del ar r eglo que hemos
quer ido asignar o r ef er enciar y que est á f uer a del r ango. El r ango en est e caso t er minaba en la
posición 9 y quer íamos acceder a la 10. Por eso obt uvimos el er r or . Siguiendo:

at UnArreglo.main(UnArreglo.java:4)

Est a línea nos indica dónde ocur r ió. En gener al est a línea no es una, sino var ias, dependiendo
cuánt os mét odos est emos llamando. Per o lo que indica es que en el mét odo main de UnAr r eglo
(est o lo dice en la par t e UnAr r eglo. main) f ue la excepción. Más específ icament e, en la línea 4
del ar chivo UnAr r eglo. j ava.

Ahor a que sabemos t odo, sint et icemos nuest r o análisi s:

1. Tenemos una asignación f uer a del r ango de un ar r eglo.
2. Tr at amos de poner o r ef er enciar la posición 10 del ar r eglo.
3. El er r or est á en el mét odo main de la clase UnAr r eglo.
4. La línea es la 4 del ar chivo UnAr r eglo.j ava.

Con est a inf or mación es f ácil cor r egir el pr oblema.

Analicemos ot r o pr oblema algo más complej o:

public class Programa {
static public void main (String[] args) {
double[] ar = new double[10];
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

162
ar[0] = new Double("ALFA1").doubleValue();
}
}

El st ack de excepción quedar ía:

Exception in thread "main" java.lang.NumberFormatException: ALFA1
at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.
java:1180)
at java.lang.Double.valueOf(Double.java:172)
at java.lang.Double.<init>(Double.java:244)
at Programa.main(Programa.java:4)

Bueno, ahor a es un poquit o más gr ande que en el ej emplo ant er ior , per o es analizable.

Paso 1: Tomemos la línea que indi ca el t ipo de excepción:

Exception in thread "main" java.lang.NumberFormatException: ALFA1

Est o nos i ndica que la excepción es Number For mat Except ion o t r aducida Excepci ón de
For mat o Numér ico (o de Númer o). ¿Por qué?. El valor que viene a cont inuación “ALFA1” es el
pr oblema, puest o que (como pueden ver ) no es numér ico. Ese es el pr oblema.

Paso 2: Veamos el r est o de la excepción par a ver si logr amos obt ener donde ocur r ió:

at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.
java:1180)
at java.lang.Double.valueOf(Double.java:172)
at java.lang.Double.<init>(Double.java:244)
at Programa.main(Programa.java:4)

Lo que ant er ior ment e habíamos dicho se cumple, pues ya no es una línea, sino que son 4 líneas.
Per o es sencillo descubr ir donde est á el er r or , pues buscamos aquellos pr ogr amas que hemos
hecho par a buscar el er r or , en est e caso, Pr ogr ama. j ava es nuest r o (los demás ni siquier a
sabíamos que exist ían). Est a últ ima línea nos dice nuevament e que el er r or est á en el mét odo
main de la clase Pr ogr ama, en la línea 4 del ar chivo Pr ogr ama. j ava.

Sencillo ahor a que sabemos cómo hacer lo.
Sint axis
I dent if icar Excepciones en J ava
Las excepciones en gener al pueden ser de 2 t ipos:

• Er r or es de Pr ogr amación: Aquellos er r or es en donde el pr ogr amador puede evit ar lo
por que es un er r or al codif icar el pr ogr ama
• Er r or es de Dat os: Aquellos er r or es que el pr ogr amador puede evit ar , o simplement e
no puede hacer lo, ya que son pr oblemas en la int er acción pr ogr ama-usuar io.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

163
Es clar o que los pr imer os son muy gr aves, pues al ut ilizar los no deber ían exist ir . Sin embar go
est os er r or es no son los más comunes.

J ava pr ovee una f or ma de at r apar los er r or es de dat os y poder cont r olar así los pr ogr amas
evit ando que el usuar io ut ilice mal el pr ogr ama o simplement e no pasen impr evist os como f alt a
el ar chivo, no t iene per misos par a escr ibir o que se haya cer r ado el puer t o.

¿Cómo se hace?

Ya hemos ut ilizado una f or ma de cont r ol de est o en ar chivos. Veamos el siguient e ej emplo:

public class Archivo {
static public void main (String[] args) throws Exception {
BufferedReader br = new BufferedReader(
new FileReader (”archivo.txt¨));

// ... continúa el programa

br.close();
}
}

Est e sencillo código nos muest r a como ut ili zamos un ar chivo de t ext o (vist o en clases
ant er ior es). A dif er encia de los pr ogr amas t r adicionales, est e mét odo posee una sent encia
adicional en su f ir ma que dice t hr ows Except ion, est o quier e decir , que manej e (handle) las
excepciones que ocur r an. Si no pusiér amos est e handler , el compilador nos da el er r or :

Archivo.java:6: Exception java.io.FileNotFoundException must be
caught, or it must be declared in the throws clause of this method.
new FileReader ("archivo.txt"));
^
Archivo.java:10: Exception java.io.IOException must be caught, or it
must be declared in the throws clause of this method.
br.close();
^
2 errors

De esa f or ma (y solo en est e caso) el compilador nos indica cuáles son las excepciones que debe
manej ar el mét odo. También, es por eso que podr íamos poner :

public class Archivo {
static public void main (String[] args)
throws IOException, FileNotFoundException {
BufferedReader br = new BufferedReader(
new FileReader (”archivo.txt¨));

// ... continúa el programa

br.close();
}
}

y t ambién est á cor r ect o. Per o solo en el caso especial de los ar chivos se obliga poner un t hr ows
en la f ir ma del mét odo.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

164

Veamos ot r o ej emplo, en el cuál no es necesar ia una cláusula t hr ows per o si se pueden
cont r olar excepciones de ot r o t ipo:

class Datos {
private BufferedReader lector;
public Datos () {
lector = new BufferedReader(
new InputStreamReader(System.in));
}

public int leeEntero() throws NumberFormatException {
return Integer.parseInt(lector.readLine());
}
}

public class Lector {
static public void main (String[] args) throws Exception {
Datos l = new Datos();

System.out.print("Ingrese un Entero?");
int e = l.leeEntero();

System.out.print("Ingrese un Real?");
int r = l.leeEntero();
}
}

En est e caso (y como se puede ver ) se piden 3 valor es dist int os, per o se leen los 3 como
ent er os. En est e caso y si el usuar io ingr esa lo que le piden, enviar á un
Number For mat Except ion al ingr esar el r eal.

Aquí ocur r e algo muy int er esant e, pues en el mét odo leeEnt er o(), se est á indicando que capt ur a
la excepción Number For mat Except ion, per o en el mét odo padr e (llamador ) main(St r ing[ ] ar gs)
se indica que es Except ion la que debe manej ar . ¿Por qué?. En r ealidad la r azón f ue solament e
por comodidad, pues Except ion es una super clase de t odas las excepciones
18
:


class j ava. lang. Except ion
class j ava.awt .AWTExcept ion
class j ava.secur it y.acl.AclNot FoundExcept ion
class j ava.r mi.Alr eadyBoundExcept ion
class j ava.lang.ClassNot FoundExcept ion
class j ava.lang.CloneNot Suppor t edExcept ion
class j ava.r mi.ser ver .Ser ver CloneExcept ion
class j ava.ut il.zip.Dat aFor mat Except ion
class j ava.secur it y.Digest Except ion


class j ava.io.I OExcept ion
class j ava.io.Char Conver sionExcept ion


class j ava.io.EOFExcept ion


class j ava.io.FileNot FoundExcept ion

18
Se muest r a una list a complet a de excepciones. Aquellas que se encuent r an mar cadas son las que comunment e les
podr ía ocur r ir . Las demás son par a que conozcan t odas las excepciones que exist en
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

165
class j ava.io.I nt er r upt edI OExcept ion
class j ava.net .Malf or medURLExcept ion
class j ava.io.Obj ect St r eamExcept ion
class j ava.io.I nvalidClassExcept ion
class j ava.io.I nvalidObj ect Except ion
class j ava.io.Not Act iveExcept ion
class j ava.io.Not Ser ializableExcept ion
class j ava.io.Opt i onalDat aExcept ion
class j ava.io.St r eamCor r upt edExcept ion
class j ava.io.Wr it eAbor t edExcept ion
class j ava.net .Pr ot ocolExcept ion
class j ava.r mi.Remot eExcept ion
class j ava.r mi.AccessExcept ion
class j ava.r mi.Connect Except ion
class j ava.r mi.Connect I OExcept ion
class j ava.r mi.ser ver .Expor t Except ion
class j ava.r mi.ser ver .Socket Secur it yExcept ion
class j ava.r mi.Mar shalExcept ion
class j ava.r mi.NoSuchObj ect Except ion
class j ava.r mi.Ser ver Er r or
class j ava.r mi.Ser ver Except ion
class j ava.r mi.Ser ver Runt imeExcept ion
class j ava.r mi.ser ver .Skelet onMismat chExcept ion
class j ava.r mi.ser ver .Skelet onNot FoundExcept ion
class j ava.r mi.St ubNot FoundExcept ion
class j ava.r mi.Unexpect edExcept ion
class j ava.r mi.UnknownHost Except ion
class j ava.r mi.Unmar shalExcept ion
class j ava.net .Socket Except ion
class j ava.net .BindExcept ion
class j ava.net .Connect Except ion
class j ava.net .NoRout eToHost Except ion
class j ava.io.SyncFailedExcept ion
class j ava.io.UTFDat aFor mat Except ion
class j ava.net .UnknownHost Except ion
class j ava.net .UnknownSer viceExcept ion
class j ava.io.Unsuppor t edEncodingExcept ion
class j ava.ut il.zip.ZipExcept ion
class j ava.lang.I llegalAccessExcept ion
class j ava.lang.I nst ant iat ionExcept ion
class j ava.lang.I nt er r upt edExcept ion
class j ava.beans.I nt r ospect ionExcept ion
class j ava.lang.r ef lect .I nvocat ionTar get Except ion
class j ava.secur it y.KeyExcept ion
class j ava.secur it y.I nvalidKeyExcept ion
class j ava.secur it y.KeyManagement Except ion
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

166
class j ava.secur it y.acl.Last Owner Except ion
class j ava.secur it y.NoSuchAlgor it hmExcept ion


class j ava.lang.NoSuchFieldExcept ion


class j ava.lang.NoSuchMet hodExcept ion
class j ava.secur it y.NoSuchPr ovider Except ion
class j ava.r mi.Not BoundExcept ion
class j ava.secur it y.acl.Not Owner Except ion
class j ava.t ext .Par seExcept ion
class j ava.beans.Pr oper t yVet oExcept ion
class j ava.lang.Runt imeExcept ion
class j ava.lang.Ar it hmet icExcept ion
class j ava.lang.Ar r aySt or eExcept ion


class j ava.lang.ClassCast Except ion
class j ava.ut il.Empt ySt ackExcept ion
class j ava.lang.I llegalAr gument Except ion
class j ava.lang.I llegalThr eadSt at eExcept ion
class j ava.secur it y.I nvalidPar amet er Except ion


class j ava.lang.Number For mat Except ion
class j ava.lang.I llegalMonit or St at eExcept ion
class j ava.lang.I llegalSt at eExcept ion
class j ava.awt .I llegalComponent St at eExcept ion


class j ava.lang.I ndexOut Of BoundsExcept ion


class j ava.lang.Ar r ayI ndexOut Of BoundsExcept ion


class j ava.lang.St r ingI ndexOut Of BoundsExcept ion
class j ava.ut il.MissingResour ceExcept ion
class j ava.lang.Negat iveAr r aySizeExcept ion
class j ava.ut il.NoSuchElement Except ion


class j ava.lang.NullPoint er Except ion
class j ava.secur it y.Pr ovider Except ion
class j ava.lang.Secur it yExcept ion
class j ava.r mi.RMI Secur it yExcept ion
class j ava.sql.SQLExcept ion
class j ava.sql.SQLWar ning
class j ava.sql.Dat aTr uncat ion
class j ava.r mi.ser ver .Ser ver Not Act iveExcept ion
class j ava.secur it y.Signat ur eExcept ion
class j ava.ut il.TooManyList ener sExcept ion
class j ava.awt .dat at r ansf er .Unsuppor t edFlavor Except ion

Ent onces, uno puede at r apar t odas las excepciones ut ilizando la clase Except ion. El ot r o punt o
impor t ant e es que, al capt ur ar una excepción dent r o de un mét odo, t odos los llamador es deben
t r aspasar el cont r ol de ella hast a el mét odo mai n (o al pr incipal). Por eso es r equer ido que el
main t uvier a el t hr ows en su f ir ma. Sin embar go, no es est r ict ament e esa sent encia la que se
debe usar (ver emos ot r a).
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

167
At r apar y Cont r olar Excepciones
Lo siguient e que ver emos es la f or ma en que se puede at r apar una excepción y evit ar que el
pr ogr ama se caiga por ello (lo que siempr e hemos deseado).

Una sección cr it ica es línea o t r ozo de código que pueden “caer se” por
causa de una excepción.

Una sección cr ít ica se delimit a con la sent encia t r y. . . cat ch. Su sint axis es:

try {
// Código que se quiere evitar una excepción
}
catch (Exception1 <var1>) {
// Código que reemplaza la ejecución cuando ocurre Exception1
}
catch (Exception2 <var2>) {
// Código que reemplaza la ejecución cuando ocurre Exception2
}
...
catch (ExceptionN <varN>) {
// Código que reemplaza la ejecución cuando ocurre ExceptionN
}

Cuando exist e una sección cr ít ica, los cat chs indican las excepciones que pueden ocur r ir en
cualquier nivel de ést e. Las Except ion1 ... Except ionN son los nombr es de las excepciones que
ocur r en. Un ej emplo es:

public class Archivo {
static public void main (String[] args) {
try {
BufferedReader br = new BufferedReader(
new FileReader (”archivo.txt¨));

// ... continúa el programa

br.close();
}
catch(Exception e) {
System.out.println(”Ha ocurrido un error¨);
}
}
}

Est a es la ver sión más simple. Si ej ecut an est e código, el r esult ado si ar chivo. t xt no exist e es
“Ha ocur r ido un er r or ”, y no el molest o st ack de excepción indicando qué ocur r ió. Per o se puede
dividir t ambién en dist int as excepciones:

public class Archivo {
static public void main (String[] args) {
try {
BufferedReader br = new BufferedReader(
new FileReader (”archivo.txt¨));

// ... continúa el programa

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

168
br.close();
}
catch(FileNotFoundException e) {
System.out.println(”No existe el archivo¨);
}
catch(IOException e) {
System.out.println(”Error al leer el archivo¨);
}
}
}

En est e segundo caso, el “handler ” cambia, pues por r azones de dist int os er r or es pueden
ocur r ir las 2 excepciones, y dependiendo del t ipo de er r or que ocur r a, se despliega el mensaj e
adecuado.

Veamos ot r o ej emplo:

class Datos {
private BufferedReader lector;
public Datos () {
try {
lector = new BufferedReader(
new InputStreamReader(System.in));
}
catch (Exception e) {
System.out.println (”Imposible abrir entrada¨);
System.exit(0);
}
}

public int leeEntero() throws NumberFormatException {
return Integer.parseInt(lector.readLine());
}
}

public class Lector {
static public void main (String[] args) {
Datos l = new Datos();
boolean entero = false;

while (!entero) {
System.out.print("Ingrese un Entero?");
try {
int e = l.leeEntero();
entero = true;
}
catch (NumberFormatException e) {
System.out.println (”No ingresó entero¨);
}
}

System.out.println(”Ahora si fue un entero¨);
}
}

Est e nuevo código per mit ir ía que el usuar io nunca ingr esar a un valor dist int o a un ent er o (es
decir let r as, r eales, ot r as cosas) sin que el pr ogr ama se caiga, por supuest o.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

169
Ahor a, ¿par a qué sir ve la var iable e que posee el cat ch?.

La var iable que va def inida en el cat ch a un cost ado del t ipo de excepción es una r ef er encia a
un obj et o del t ipo de esa excepción. Sir ve par a obt ener mayor inf or mación de ella:

• St r ing get Message(): Obt iene un cor t o mensaj e descr ipt ivo del er r or que ocur r ió.
• void pr int St ackTr ace(): I mpr ime en la salida de er r or (est ándar ) el st ack de excepción
de la que ocur r ió.

Por ej emplo, si mir amos el mai n ant er ior (últ imo ej emplo):

static public void main (String[] args) {
Datos l = new Datos();
boolean entero = false;

while (!entero) {
System.out.print("Ingrese un Entero?");
try {
int e = l.leeEntero();
entero = true;
}
catch (Exception e) {
System.out.print (”Error: ”);
System.out.println (e.getMessage());
e.printStackTrace();
}
}
System.out.println(”Ahora si fue un entero¨);
}

En est e caso, si ocur r e el er r or , se puede saber qué ocur r ió. Un ej emplo de ej ecución:

Ingrese un Entero?A
Error: A
java.lang.NumberFormatException: A
at java.lang.Integer.parseInt(Integer.java:409)
at java.lang.Integer.<init>(Integer.java:544)
at Datos.leeEntero(Lector.java:11)
at Lector.main(Lector.java, Compiled Code)

Ingrese un Entero?8.5
Error: 8.5
java.lang.NumberFormatException: 8.5
at java.lang.Integer.parseInt(Integer.java:418)
at java.lang.Integer.<init>(Integer.java:544)
at Datos.leeEntero(Lector.java:11)
at Lector.main(Lector.java, Compiled Code)

Ingrese un Entero?6
Ahora si fue un entero

Si no pusiér amos el mét odo pr int St ackTr ace() el pr ogr ama queda:

Ingrese un Entero?A
Error: A

Ingrese un Entero?8.5
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

170
Error: 8.5

Ingrese un Entero?6
Ahora si fue un entero

Algo mucho más limpio y or denado.
Lanzar Excepciones
J ava pr ovee además la posibilidad de lanzar excepciones pr opias. Est o se hace a t r avés de la
sent encia t hr ow (si, par ecido a un t hr ows per o sin la s f inal).

Por ej emplo:

class Datos {
private BufferedReader lector;
public Datos () {
try {
lector = new BufferedReader(
new InputStreamReader(System.in));
}
catch (Exception e) {
System.out.println ("Imposible abrir entrada");
System.exit(0);
}
}

public int leeEntero() throws NumberFormatException {
String linea = "";
try {
linea = lector.readLine();
}
catch (IOException e) {
}
if (linea.length() <= 0)
throw new NumberFormatException();
return Integer.parseInt(linea);
}
}

public class Lector {
static public void main (String[] args) {
Datos l = new Datos();
boolean entero = false;

while (!entero) {
System.out.print("Ingrese un Entero?");
try {
int e = l.leeEntero();
entero = true;
}
catch (NumberFormatException e) {
System.out.println ("No ingresó entero");
}
}
System.out.println("Ahora si fue un entero");
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

171
Est e pr ogr ama obliga al sist ema a enviar una excepción de t ipo Number For mat Except ion
cuando es ingr esado por el t eclado un st r ing vacío. Nót ese que es muy impor t ant e poner la
sent encia t hr ows par a que la excepción lanzada sea capt ur ada por el mét odo llamador .

Es muy int er esant e est e punt o de vist a, ya que, mezclado con la sent encia t r y... cat ch puede
ser una her r amient a út il al moment o de cont r olar er r or es que ant es no podíamos. Veamos ot r o
ej emplo:

public class Selector {
static public BufferedReader b = new BufferedReader (
new InputStreamReader(System.in));

static public String leeOpcion() throws Exception {
String op;
try {
op = b.readLine();
}
catch (IOException e) {
op = Ӭ;
}

if (op.length() <= 0)
throw new Exception(”Debe ingresar una opcionó);
if (!op.equals(”A¨) &&
!op.equals(”B¨) &&
!op.equals(”C¨))
throw new Exception(”Las opciones son A, B, Có);

return op;
}

static public void main (String[] args) {
while (true) {
System.out.print(”Ingrese A, B o C?¨);
String op = Ӭ;
try {
op = leeOpcion();
break;
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}

La salida de est e pr ogr ama ser ía:

Ingrese A, B o C?
Debe ingresar una opcion
Ingrese A, B o C? 34
Las opciones son A, B, C
Ingrese A, B o C? sdf
Las opciones son A, B, C
Ingrese A, B o C? A

Como podemos not ar , ahor a solo per mit imos lanzar excepciones de t ipo Except ion per o con
mensaj e per sonalizado.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

172
Cr ear Excepciones
El pr oblema que hay con ut ilizar Except ion dir ect ament e, es que a veces ocur r en ot r as
excepciones y se pier de saber qué ocur r ió. Es por eso que podemos cr ear pr opias excepciones
que se aj ust en al nivel del pr ogr ama.

Veamos el mismo ej emplo, per o algo modif icado:

public class Selector {
static public BufferedReader b = new BufferedReader (
new InputStreamReader(System.in));

static public String leeOpcion() throws OptionException {
String op;
try {
op = b.readLine();
}
catch (IOException e) {
op = Ӭ;
}

if (op.length() <= 0)
throw new OptionException();
if (!op.equals(”A¨) &&
!op.equals(”B¨) &&
!op.equals(”C¨))
throw new OptionException();

return op;
}

static public void main (String[] args) {
while (true) {
System.out.print(”Ingrese A, B o C?¨);
String op = Ӭ;
try {
op = leeOpcion();
break;
}
catch (OptionException e) {
System.out.println(e.getMessage());
}
}
}
}

Cambiamos la excepci ón por una llamada Opt ionExcept ion. ¿De dónde salió?. Pues la idea es que
implement emos esa clase par a que se pueda ut ilizar como excepción igual que las ot r as:

public class OptionException extends Exception {
public OptionException {
super(”Opción inválida. Las opciones son A, B o C¨);
}
}

Ahor a, el pr ogr ama impide que se ingr ese algo dist int o de A, B o C lanzando una excepción
Opt ionExcept ion y t odo queda solucionado.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

173
Pr oblemas
Se quier e cr ear un visor de ar chivos de t ext o. Par a ello se le pide:

(a) Const r uya una clase que manipule los ar chivos de t ext o encapsulando la clase
Buf f er edReader y cont r olando las I OExcept ion que puedan ocur r ir (No exist e el ar chivo,
Fin de Ar chivo inesper ado, et c.)
Sol ución
Ver sión sin cr ear una Excepción:

public class Visor {
private String nombre;

public Visor (String nombre) {
this.nombre = nombre;
}

public String leeArchivo () throws IOException {
BufferedReader lector;
lector = new BufferedReader (
new FileReader(this.nombre));
String texto = Ӭ;
String linea = Ӭ;
while ( (linea = lector.readLine()) != null)
texto = texto + ”\n¨ + linea;
lector.close();
return texto;
}
}

Ver sión usando Except ion:

public class Visor {
private String nombre;

public Visor (String nombre) {
this.nombre = nombre;
}

public String leeArchivo () throws Exception {
BufferedReader lector;
try {
lector = new BufferedReader (
new FileReader(this.nombre));
}
catch (FileNotFoundException e) {
throw Exception(”El archivo no existe¨);
}
String texto = Ӭ;
try {
while (true)
texto = texto + ”\n¨ + lector.readLine();
}
catch (EOFException e) {
}
lector.close();
return texto;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

174
}
}

Nót ese que en est a segunda ver sión ya no se usa el NULL como f in de ar chivo.

(b) Escr iba un pr ogr ama (main) que simule el siguient e diálogo:

Bienvenido al Visor 1.0

Ingrese el Nombre del Archivo: tarea.java
No existe el Archivo

Ingrese el Nombre del Archivo: tarea4.java
[INICIO DEL ARCHIVO]
... // Aquı aparece el archivo de texto lınea a lınea
[FIN DEL ARCHIVO]
Posee 57 lıneas y 453 caracteres

Ingrese el Nombre del Archivo:

Se utilizó el programa 2 veces
1 archivos leıdos
1 archivos no existıan
Sol ución
Ut ilizando la ver sión sin cr ear una Excepción:

static public void main (String[] args) throws IOException {
BufferedReader in = new BufferedReader (
new InputStreamReader (System.in));
System.out.println(”Bienvenido al Visor 1.0¨);

// Variables que se leen al final
int siL = 0;
int noL = 0;

// Ciclo de Lectura
while (true) {
System.out.print(”Ingrese el Nombre del Archivo: ”);
String nombre = in.readLine();
if (nombre.length() <= 0) break;

// Leemos el arhivo y controlamos la excepción
Visor v = new Visor(nombre);
try {
String texto = v.leeArchivo();

// Si ocurrió una excepción, no continúa
System.out.println(”[INICIO DEL ARCHIVO]¨);
System.out.println(texto);
System.out.println(”[FIN DEL ARCHIVO]¨);

// Contamos las lıneas y los caracteres
int ls = contarLineas(texto);
int cs = texto.length();

System.out.println(”Posee ” + ls +
” lınea y ” + cs + ” caracteres¨);
siL++;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

175
}
catch (FileNotFoundException e) {
System.out.println (”No existe el archivo¨);
noL++;
}
}

// Fin del programa
System.out.println(”Se utilizó el programa ” +
(siL + noL) + ” veces¨);
System.out.println(siL + ” archivos leıdos¨);
System.out.println(noL + ” archivos no existıan¨);
}

Ut ilizando la ver sión con Except ion:

static public void main (String[] args) throws IOException {
BufferedReader in = new BufferedReader (
new InputStreamReader (System.in));
System.out.println(”Bienvenido al Visor 1.0¨);

// Variables que se leen al final
int siL = 0;
int noL = 0;

// Ciclo de Lectura
while (true) {
System.out.print(”Ingrese el Nombre del Archivo: ”);
String nombre = in.readLine();
if (nombre.length() <= 0) break;

// Leemos el arhivo y controlamos la excepción
Visor v = new Visor(nombre);
try {
String texto = v.leeArchivo();

// Si ocurrió una excepción, no continúa
System.out.println(”[INICIO DEL ARCHIVO]¨);
System.out.println(texto);
System.out.println(”[FIN DEL ARCHIVO]¨);

// Contamos las lıneas y los caracteres
int ls = contarLineas(texto);
int cs = texto.length();

System.out.println(”Posee ” + ls +
” lınea y ” + cs + ” caracteres¨);
siL++;
}
catch (Exception e) {
System.out.println (e.getMessage());
noL++;
}
}

// Fin del programa
System.out.println(”Se utilizó el programa ” +
(siL + noL) + ” veces¨);
System.out.println(siL + ” archivos leıdos¨);
System.out.println(noL + ” archivos no existıan¨);
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVII: Excepciones y Control de Errores

176

Y ahor a el que cuent a líneas

static public int contarLineas (String texto) {
int total = 1;
for (int i=0;
texto.indexOf(”,¨, i) > 0;
i = texto.indexOf(”,¨, i) + 1)
total++;
}

(c) Pr opuest o. Const r uya un applet que ut ilice el Visor const r uído en (a) par a que f uncione
gr áf icament e.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

177
Capít ulo XVI I I : Tipos y Est r uct ur as de Dat os
Mot ivaci ón
Con t odo lo que ya hemos vist o hast a ahor a podemos r esolver un sin númer o de pr oblemas
comput aciones aplicando los concept os, esquemas, pat r ones de pr ogr amación e inst r ucciones
que ut iliza J ava.

Veamos un pr oblema:

Los auxiliar es de CC10A cor r igen las pr egunt as de un gr upo de mechones de t odas las
secciones por separ ado. Se les ha pedido que cada vez que cor r ij an const r uyan un ar chivo
llamado “pX- auxNN” en donde X indica el númer o de la pr egunt a y NN el númer o del auxiliar
(numer ado ent r e 01 y 18). Lo más simpát ico es la cor r espondencia de cor r ección, es decir
siempr e ocur r e que:

• Auxiliar 1 cor r ige Pr egunt a 1
• Auxiliar 2 cor r ige Pr egunt a 2
• Auxiliar 3 cor r ige Pr egunt a 3
• Auxiliar 4 cor r ige Pr egunt a 1
• Auxiliar 5 cor r ige Pr egunt a 2
• ...

Se pide const r uir un pr ogr ama que per mit a leer TODOS LOS ARCHI VOS de las 3 pr egunt as
del cont r ol 2, almacenándolas en memor ia, par a luego que un alumno ingr ese su númer o int er no
muest r e las not as de las 3 pr egunt as, el pr omedio del cont r ol y el código del auxiliar que le
cor r igió. Suponga que hay un máximo de 1000 alumnos (de 000 a 999) y que la est r uct ur a de los
ar chivos es:

• Código int er no del alumno (3 car act er es)
• Not a del alumno en la pr egunt a (3 car act er es con . en medio)

¿Por qué no podr íamos r esolver est e pr oblema? Es bast ant e sencillo pues t enemos t oda la
inf or mación posible. Veamos como se r esolver ía con lo que sabemos:

public class NotasControl {
// Lector de la Entrada Estándar
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));

static public void main (String args[]) {
// Arreglos que almacenarán las notas y
// el código del auxiliar que corrigió
double[][] notas = double[1000][3];
int[][] aux = int [1000][3];

// Se inician notas en 1 y auxiliaries en 0
for (int x=0; x<1000; x++) {
for (int y=0; y<3; y++) {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

178
notas[x][y] = 1.0;
aux[x][y] = 0;
}
}

// Ciclo lector de las preguntas
int nn = 1;
for (int x=0; x<3; x++) {
String nombre = ”p¨;
nombre += x;
nombre += ¨-aux¨;
if (nn < 10)
nombre += ”0¨;
nombre += nn;

BufferedReader bf = new BufferedReader(
New FileReader(nombre));
String linea;
while( (linea=bf.readLine()) != null ) {
int cod = Integer.parseInt(
linea.substring(0, 3));
double nota = new Double(
linea.substring(3, 3)
).doubleValue();

notas[cod][x] = nota;
aux[cod][x] = nn;
}
bf.close();

nn++;
}

// Ya tenemos leido todos los datos.
// Veamos el ciclo de consulta de notas.
while(true) {
System.out.print(”Código de alumno?¨);
int codigo = Integer.parseInt(in.readLine());

System.out.println(”Tus notas son: ”);
double suma = 0;
for (int p=0; p<3; p++) {
System.out.println(”Pregunta ” + (p+1) +
¨ = ” + notas[codigo][p] +
” (Aux: ” + aux[codigo][p] + ”)¨);
suma += notas[codigo][p];
}
double prom = suma / 3;
System.out.println(”Promedio = ” + prom);
}
}
}

Podemos ver que la solución no es par a nada dif ícil de r ealizar , sin embar go se est án ut ilizando
2 ar r eglos par a almacenar los valor es. ¿Podr ía haber sido solo uno?.

Ver emos que las Est r uct ur as de Dat os nos per mit en r ealizar o almacenar obj et os y cualquier
t ipo de element o que se nos ocur r a ut ilizando una clase la cual almacena la inf or mación que
nosot r os quer emos manipular .
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

179
Concept o
Tipo de Dat o Abst r act os
Se denominar á Tipo de Dat o a una clase que ser á const r uida par a
almacenar un element o especial. Nos per mit ir á modelar est r uct ur as
combinados con ot r os t ipos u obj et os de clases de J ava.

Est a def inición nos abr e la ment e par a t r abaj ar en f or ma más genér ica de lo que hemos est ado
haciéndolo hast a ahor a. Por ej emplo nos gust ar ía modelar el r anking de la ATPsabiendo que:

• Todo t enist a posee un nombr e
• También una nacionalidad
• Y un cant idad de punt os

Unos dir ían: “est o es una mat r iz”. Per o no es t an sencillo, ya que la cant idad de punt os es un
valor ent er o y los ot r os 2 campos son St r ings. ¿Cómo mezclamos est o? Sencillo. Def inamos el
t ipo de dat o Tensit a:

public class Tenista {
public String nombre;
public String pais;
public int puntos;

public Tenista (String nombre, String pais) {
this.nombre = nombre;
this.pais = pais;
this.puntos = 0;
}
}

Una sencilla clase que def ine por complet o al t enist a. Si obser vamos un poco el const r uct or que
se ha declar ado es la idea de un nuevo t enist a que r ecién ent r a al r anking. Además, podemos
def inir t odas aquellas f uncionalidades que pueden ser út iles como ganar Punt os(int punt os)
agr ega la cant idad de punt os al t enist a.

Per o ¿par a qué sir ve?. Bueno, si pensamos un poco, ahor a bast ar ía cr ea solo 1 ar r eglo de t ipo
Tenist a y car gar t odo allí de la siguient e f or ma:

Tenista ranking[];
...
ranking[37] = new Tenista(”Marcelo Rıos¨, ”Chile¨);
ranking[37].ganarPuntos(1000);

y t enemos un nuevo t enist a en la ATPcon 1.000 punt os.

Ahor a, ¿cuál ser ía la ut ilidad al moment o de quer er or denar el ar r eglo? Analicemos est e no t an
sencillo pr oblema y démosle una solución.

void bubbleSort (Tenista[] a, int nMin, int nMax) {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

180
// Versión Recursiva de BUBBLESORT
if (nMax <= nMin)
return;

for (int j=nMin; j<nMax; j++) {
if (a[j] > a[j+1]) {
Tenista auxiliar = a[j];
a[j] = a[j+1];
a[j+1] = auxiliar;
}
}

bubbleSort (a, nMin, nMax-1);
}

Todo est á bien EXCEPTO por la línea dest acada en la cual se compar an los element os, ya que
clar ament e se t r at a de compar ar 2 obj et os de t ipo Tenist a en donde no est á def inido el
compar ador >(mayor que) dir ect ament e.

Par a solucionar est o, usar emos lo que en l a últ ima clase quedó como pr oblema, ut ilizar una clase
que per mit ier a que los obj et os se compar ar an: EsCompar able. Sin embar go, y gr acias a los
cr eador es de J ava, se han adelant ado a est o y la int er f ace Compar able ya exist e es:

public interface Comparable {
public int compareTo (Object obj);
}

Con est o hacemos ahor a que nuest r a clase Tenist a sea Compar able:

public class Tenista implements Comparable {
public String nombre;
public String pais;
public int puntos;

public Tenista (String nombre, String pais) {
this.nombre = nombre;
this.pais = pais;
this.puntos = 0;
}

public int compareTo(Object obj) {
return this.puntos - ((Tensita) obj).puntos;
}
}

Ent onces, podemos modif icar nuest r o or denamient o y ahor a per mit ir ut ilizar est a compar ación:

void bubbleSort (Tenista[] a, int nMin, int nMax) {
// Versión Recursiva de BUBBLESORT
if (nMax <= nMin)
return;

for (int j=nMin; j<nMax; j++) {
if (a[j].compareTo(a[j+1]) > 0) {
Tenista auxiliar = a[j];
a[j] = a[j+1];
a[j+1] = auxiliar;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

181
}
}

bubbleSort (a, nMin, nMax-1);
}

¡Hemos cr eado un or denador de obj et os genér icos!

Si, ya que si mir amos bien bast ar ía cambiar el mét odo compar eTo de la clase Tensit a par a
cambiar la f or ma de or denamient o y NO el mét odo de or denamient o.

Además, si ahor a gener alizamos un poco más la f ir ma del mét odo:

void bubbleSort (Comparable[] a, int nMin, int nMax) {
...
// Cambiar Tensita por Comparable
...
}

Tendr emos un mét odo que puede or denar CUALQUI ER clase de Tipos de Dat o que sean
Compar able
19
.

I nt er esant e.
Est r uct ur a de Dat os
Una Est r uct ur a de Dat os es una combinación de element os de un mismo
Tipo de Dat o t r adicional o abst r act o, que puede ser r ef er enciado con
var iables y que posee algunas car act er íst icas que la hacen especial y
dif er ent e a ot r as est r uct ur as de dat os conocidas.

Est a def inición de lo que son las Est r uct ur as de Dat os nos per mit e ampliar el espect r o de los
que son los Ar r eglos de Dat os a ot r as est r uct ur as más comeplej as.

Por la def inición, un ar r eglo es una Est r uct ur a de Dat os, ya que nos per mit e almacenar un
mont ón de element os del mismo t ipo en una misma var iable. Veamos ot r as est r uct ur as de dat os
que son út iles y que se implement an usando t ipos de dat os conocidos. Luego ver emos t ipos
nuevos con los cuales se podr ían implement ar las est r uct ur as:
Sint axis
Pilas y Colas
Est as est r uct ur as de dat os t ienen algunas car act er íst icas especiales y pueden ser
r epr esent adas a t r avés de ar r eglos de valor es. Sin embar go ambos son encapsulados par a
conver t ir los en est r uct ur as.

19
El Tipo de Dat o St r ing es compar able por def inición. Solo en el caso de los t ipos numér icos
nat ivos no f uncionar ía est e mét odo, per o ellos t ienen compar ador es >, <, >=, <= y ==.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

182

Pila (LI FO): Es una est r uct ur a lineal que se asemej a a las t or r es de cosas (de plat os, de
papeles, de t ar r os de salsa o de obj et os). Su car act er íst ica pr incipal est á dada por la sigla con
la cuál se les llama LI FO (“ Last I n Fir st Out ”) que signif ica que el últ imo que llega a una pila es
el pr imer o que sale.

Por ej emplo: Si ponemos un CD sobr e ot r o CD y así sucesivament e hast a llegar a 20 CD’s
apilados, solo podr emos VER y/ o SACAR el de ar r iba sin af ect ar a los demás, ya que est e f ue
el últ imo que puse en la pila de CD’s.

Su implement ación puede ser hecha a t r avés de un ar r eglo
20
(con un mar gen máximo)
encapsulada dent r o de una clase Pila (la har emos de obj et os que son compar ables. En el caso
del t ipo de dat o St r ing f unciona per f ect ament e, ya que es compar able):

class Pila {
protected Comparable[] pila;
protected int n;

public Pila (int n) {
this.pila = new Comparable[n];
this.n = 0;
}

public void push(Comparable obj) {
if (this.n == this.pila.length)
return; // PILA LLENA
this.pila[this.n] = obj;
this.n++;
}

public Comparable pop() {
if (this.n == 0)
return null; // PILA VACIA
this.n--;
return this.pila[this.n];
}
}

La def inición est ándar de pila indica que debe t ener 2 mét odos: uno par a poner al t ope de la
pila (push) y ot r o par a sacar del t ope de la pila (pop). El const r uct or solo cr ea la pila con un
máximo númer o de element os y luego pone el t ope en 0 par a indicar que el siguient e element o
que puede ent r ar , ent r ar á en esa posición de la pila.

Un ej emplo de ut ilización de la pila puede ser :

Pila p = new Pila (100);
Tenista t1 = new Tenista(”Marcelo Rıos¨, ”Chile¨);
Tenista t2 = new Tenista(”Boris Becker¨, ”Alemania¨);
p.push(t2);
p.push(t1);

20
No es la única f or ma de r epr esent ación. Más adelant e se ven ot r as f or mas de implement ar
una Pila y una Cola.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

183

Est e ej emplo pone a Mar celo Ríos en el t ope de la pila dej ando a Bor is Becker par a salir
después de Mar celo.

Cola (FI FO): Es una est r uct ur a lineal que se asemej a a las f ilas o colas en la vida r eal (la cola
de un banco, la f ila del colegio o f ila de f ichas de dominó). Su car act er íst ica pr incipal est á
dada por la sigla con la cuál se les llama FI FO (“Fir st I n Fir st Out ”) que signif ica que el
pr imer o que llega a una cola es el pr imer o que sale (que se at iende).

El ej emplo más clásico es el de los bancos, ya que el que llega pr imer o a la f ila siempr e sale
pr imer o del banco. Aunque aquí ocur r en algunas singular idades, por ej emplo, paso a
embar azadas y ancianos, et c, en el f ondo es una cola FI FO.

Al igual que en el caso de las pilas, las colas t ienen una r epr esent ación en J ava a t r avés de un
ar r eglo cir cular que se encapsula en una clase llamada Cola:

class Cola {
protected Comparable[] cola;
protected int beg, end;
protected boolean full;

public Cola (int n) {
this.cola = new Comparable[n];
this.beg = 0;
this.end = 0;
this.full = false;
}

public void put(Comparable obj) {
if (full)
return; // COLA LLENA
this.cola[this.end] = obj;
this.end++;
full = (this.beg == this.end);
}

public Comparable get() {
if (this.beg == this.end)
return null; // COLA VACIA
this.beg++;
return this.cola[this.beg-1];
}
}

La def ini ción est ándar de pila cola que debe t ener 2 mét odos: uno par a poner al f inal de la cola
(put ) y ot r o par a sacar del inicio de la cola (get ). El const r uct or solo cr ea la cola con un máximo
númer o de element os y luego pone el f inal en 0 par a indicar que el siguient e element o que
puede ent r ar , el inicio en 0 por que la cola est á vacía y un indicador booleano que dir á cuándo
est ar á llena la cola.

Un ej emplo de ut ilización de la cola puede ser :

Cola p = new Cola (100);
Tenista t1 = new Tenista(”Marcelo Rıos¨, ”Chile¨);
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

184
Tenista t2 = new Tenista(”Boris Becker¨, ”Alemania¨);
p.put(t2);
p.get(t1);

Est e ej emplo, a dif er encia del de Pilas (aunque par ezcan iguales) pone a Mar celo Ríos en el f inal
de la cola dej ando a Bor is Becker par a salir ant es que Mar celo de la f il a.

Per o la mej or f or ma de ent ender est as cosas es pr act icando, así que, manos a la obr a.
List as Enlazadas
Nodo: Tipo de Dat o Abst r act o que per mit e almacenar element os con cier t a est r uct ur a y que
se pueden enlazar con uno o más element os del mismo t ipo.

Est a sencilla def inición es par a declar ar t ipos de dat os dinámicos que nos per mit as ir
combinando las pr opiedades de los ar r eglos, per o en f or ma más dinámica y cr ecida.

Un Nodo se compone genér icament e de:

• Campo de I nf or mación: Almacena la i nf or mación asociada al Tipo de Dat o que def ine el
Nodo.
• Punt er os: Enlace a ot r o (s) element o(s) del mismo t ipo de dat o.

Gr áf icament e se ver ía como:






List a Enlazada (1): Conj unt o de Nodos que per mit en simular un ar r eglo dinámico, es decir , que
puede cr ecer con el t iempo.

List a Enlazada (2): Est r uct ur a de Dat os que per mit e almacenar un númer o var iable de Nodos
y que puede est ar r est r ingido SOLO por la cant idad de memor ia del pr ocesador que est á
almacenando la list a.

En f or ma r ápida y sencilla, una List a Enlazada es la est r uct ur a que es f or mada por un conj unt o
de Nodos enlazados ent r e sí. Una list a con enlace simple se ver ía como:






I NFO
Enlaces
I nf o I nf o I nf o I nf o
public class Nodo {
Object info;
Nodo sgte;
public Nodo(Object o) {
this.info = o;
this.sgte = null;
}
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

185
Par a poder r ef er encias est a est r uct ur a de dat os se r equier e de una Cabeza Lect or a que
apunt a al inicio de la list a enlazada, y el r est o se r ecor r e siguient e los punt er os al siguient e
element o de la list a (es como caminar de Nodo en Nodo).

Per o veámoslo de ver dad cómo f uncionan.

I nser ción al I nicio de la List a: Veamos gr áf icament e cómo f unciona est e caso:

Paso 1: Cr eamos un nuevo NODO y lo apunt amos por p.






Paso 2: Apunt amos el siguient e de p a lo que apunt a la cabeza.






Paso 3: Per mit imos que la cabeza ahor a r ef er encie como pr imer element o de la list a a p.





Veámoslo en J ava con el ej emplo de inser t ar STRI NGS a la list a:

// La lista está vacıa
Nodo cabeza = null;

// Ingreso de nombres:
while(true) {
System.out.print (”Nombre? ”);

// Creamos el nodo con su nombre
Nodo p = new Nodo(in.readLine);

// Luego lo ponemos en la lista
p.sgte = cabeza;
cabeza = p;
}

Per o est a solo es una f or ma de inser t ar un nuevo Nodo a una list a enlazada. En gener al exist en
3 casos de cómo inser t ar un element o: Al inicio de la list a (lo vist o ant er ior ment e), en medio y
al f inal. Veamos gr áf icament e cómo se inser t an en los siguient es 2 casos:

I nf o I nf o X
p cabeza
I nf o I nf o X
p cabeza
I nf o I nf o X
cabeza
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

186
I nser ción Al Final de la List a:

Paso 1: Recor r emos la list a hast a el element o últ imo con un it er ador q.






Paso 2: Cr eamos un nuevo NODO y lo apunt amos por p.






Paso 3: Apunt amos el siguient e de q a lo que apunt a el p.






Veamos como se implement an est as líneas en lenguaj e J ava con el mismo ej emplo ant er ior :

// La lista está vacıa
Nodo cabeza = null;

// Ingreso de nombres:
while(true) {
System.out.print (”Nombre? ”);

// Iteramos hasta que llegamos al final
Nodo q = cabeza
while (q != null && q.sgte != null)
q = q.sgte;

// Creamos el nodo con su nombre
Nodo p = new Nodo(in.readLine);

// Luego lo ponemos en la lista
if (q != null) {
q.sgte = p;
}
else { // Lista vacıa
cabeza = p;
}
}

Ummm... Se puede ver que est e caso es un poco más complej o que el de inser t ar al inicio de la
list a, per o se asemej a más al caso gener al que viene en seguida:

I nf o I nf o X
p cabeza
I nf o I nf o X
p cabeza
I nf o I nf o
cabeza q
q
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

187
I nser ción En Medio de la List a:

Paso 1: Recor r emos la list a hast a ant es de la posición donde debe ir con un it er ador q.






Paso 2: Cr eamos un nuevo NODO y lo apunt amos por p.










Paso 3: Apunt amos el siguient e de p a lo que apunt a el siguient e de q.









Paso 4: Apunt amos el siguient e de q a lo que apunt a p.







Veamos como se implement an est as líneas en lenguaj e J ava con el mismo ej emplo ant er ior :

// La lista está vacıa
Nodo cabeza = null;

// Ingreso de nombres:
while(true) {
System.out.print (”Nombre? ”);

// Iteramos hasta que llegamos al punto de inserción
I nf o I nf o
X
p
cabeza
I nf o I nf o
cabeza q
q
I nf o
I nf o
I nf o I nf o
X
p
cabeza q
I nf o
I nf o I nf o
X
p
cabeza q
I nf o
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

188
Nodo q = cabeza
while (q != null && <condición de inserción>)
q = q.sgte;

// Creamos el nodo con su nombre
Nodo p = new Nodo(in.readLine);

// Luego lo ponemos en la lista
if (q != null) {
p.sgte = q.sgte;
q.sgte = p;
}
else { // Lista vacıa
cabeza = p;
}
}

Nos f alt a ver como eliminar de una li st a enlazada en sus 3 casos t ambién.

Eliminación Al I ni cio de la List a:

Paso 1: Apunt amos p a la cabeza de la list a.






Paso 2: Apunt amos la cabeza de la list a al siguient e de p.







Paso 3: Se dest r uye lo apunt ado por p.






Veamos como se implement an est as líneas en lenguaj e J ava con el mismo ej emplo ant er ior :

Nodo p = cabeza;
cabeza = p.sigte;
p = null;

En gener al se puede o no hacer el null par a liber ar la var iable ya que J ava posee un Gar bage
Collect or que limpia cada cier t o t iempo la memor ia de var iables que apunt an a nada.
X I nf o
cabeza
X I nf o
cabeza
p
p
I nf o
I nf o
I nf o
cabeza
I nf o
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

189

Eliminación Al Final de la List a:

Paso 1: Apunt amos p al penúlt imo element o de la list a.






Paso 2: Apunt amos la cabeza de la list a al siguient e de p.






Paso 3: Se dest r uye solit o el nodo (por el GC
21
).






Veamos como se implement an est as líneas en lenguaj e J ava con el mismo ej emplo ant er ior :

Nodo p = cabeza;

while(p != null && p.sgte != null && p.sgte.sgte != null) {
p = p.sgte;
}

if (p != null && p.sgte != null) {
p.sgte = null;
}
else if (p != null) {
// Es el único caso especial
cabeza = null;
}


21
Gar bage Collect or : Se pr eocupa de limpiar la memor ia inút il del comput ador convir t iéndola en
memor ia út il.
I nf o I nf o
cabeza p
X
I nf o
cabeza
I nf o
I nf o I nf o
cabeza p
X
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

190
Eliminación En Medio de la Li st a:

Paso 1: Apunt amos p al ant er ior del element o de la list a a eliminar .






Paso 2: Apunt amos el siguient e de p al siguient e del siguient e de p.






Paso 3: Se dest r uye solit o el nodo (por el GC).






Veamos como se implement an est as líneas en lenguaj e J ava con el mismo ej emplo ant er ior . Hay
que t ener cuidado con los casos de bor de (pr imer o y últ imo element o):

Nodo p = cabeza;

while(p != null && p.sgte != null && CONDICIÓN PARA ENCONTRARLO) {
p = p.sgte;
}

if (p != null && p.sgte != null) {
p.sgte = p.sgte.sgte;
}
else if (p != null) {
// Es el primero o el último
if (p == cabeza) {
cabeza = p.sgte;
}
else {
p.sgte = null;
}
}
Ár boles
Ar bol: Est r uct ur a de dat os que per mit e almacenar inf or mación y or gani zar la de t al f or ma que
t engas sucesor es o element os siguient es como hij os en f or ma de r amas de un ár bol.

Est a def inición bast ant e r ar a es una f or ma genér ica con la cual se def inen los ár boles.

I nf o
I nf o I nf o
cabeza p
X
I nf o
cabeza
I nf o
I nf o I nf o
cabeza p
X
I nf o
I nf o
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

191
Algunas def iniciones út iles par a compr ender la nomenclat ur a es:

RAI Z es el pr imer nodo del ár bol y es por donde
se accede a él, es decir , la “cabeza” del ár bol
siempr e ser á la r aíz.

HOJ AS del ár bol son t odos aquellos nodos que
est én dent r o del ár bol per o que NO t engan
ningún hij o.

NODO I NTERNO son t odos aquellos nodos que
no son ni r aíz ni hoj as.

ALTURA es la cant idad de nodos que hay que
r ecor r er par a llegar desde la r aíz del ár bol
hast a la hoj a más alej ada de la r aíz. También se
def ine como la máxima dist ancia que hay ent r a
la r aíz y t odas las hoj as del ár bol.

Exist en var ios t ipos de ár boles, de ent r e los cuales mencionar emos los más comunes.

Ár boles Binar ios: Son ár boles que poseen 2 nodos hij os, uno izquier do y ot r o der echo. En
gener al se ut ilizan par a indicar or den dent r o de los element os del ár bol, es decir , los hij os
izquier do son siempr e MENORES que el nodo, y los hij os der echo son siempr e MAYORES que
el nodo que los cont iene.

Un ej emplo de ár bol puede ser aquél que va almacenando númer o ent er os dependiendo del
or den de ingr eso de los valor es (no r equier e se or denado como los ar r eglos o las list as):

class Nodo {
public int info;
public Nodo izq, der;
public Nodo(int o) {
this.info = o;
this.izq = null;
this.der = null;
}
}

Como podemos ver , la r epr esent ación del Nodo es igual a la r epr esent ación de una list a
doblement e enlazada. La dif er encia est á en el moment o de r ealizar el enlace, pues est e
“enlace” se hace a nodos que no son “cor r elat ivos”. I mplement emos el pr oblema de inser t ar
númer os or denadament e:

class Arbol {
protected Nodo raiz;

public Arbol() {
this.raiz = null;
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

192

// Versión iterativa del insertar
public void insertar(int x) {
Nodo p = new Nodo(x);
Nodo q = this.raiz;
Nodo f = null;
while (q != null) {
f = q;
if (q.info > x) q = q.izq;
else q = q.der;
}
if (f == null)
this.raiz = p;
else {
if (f.info > x) f.izq = p;
else f.der = p;
}
}
}

Si analizamos el inser t ar , lo que va haciendo en su f or ma gener al es:

1. Pr egunt ar si donde est oy va.
2. Si va, se inser t a.
3. Si no va, se busca por el lado en que deber ía ir

El inser t ar vist o aquí es solo un ej emplo par a ent ender cómo se va llenando el ár bol. Pues bien,
veamos gr áf icament e como quedar ía un ár bol si vamos leyendo los dat os en el siguient e or den:
5, 3, 9 y 8.











Vemos r ápidament e que TODO lo que est á a la der echa es mayor a 5 y lo que est á a la
izquier da es menor a 5. I nt ent a complet ar est o met iendo los númer o 2, 7, 6 y 4.

Ár boles Genér icos: Son ár boles que pueden t ener un númer o de hij os no def inidos, es decir ,
con 2, 3, 4... n hij os. El ár bol binar io es una clase especial de ár boles genér icos que solo posee 2
hij os, per o no es limit ant e.

Por ej emplo, usemos ár boles con númer o que cumplan la siguient e pr opiedad:

• Cada nodo almacenada la inf or mación de un int er valo de ent er os.
• Los hij os izquier dos son los nodos menor es al int er valo.
5 5
3
5
3 9
5
3 9
8
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

193
• Los hij os izquier do-cent r ales son nodos que int er sect an el int er valo por la izquier da.
• Los hij os cent r ales son los nodos que est án dent r o del int er valo.
• Los hij os der echo-cent r ales son nodos que int er sect an el int er valo por la der echa,
• Los hij os der echos son nodos mayor es al int er valo.

Ent onces, un ár bol como est e quedar ía así:

















Como podemos ver en el ej emplo, el númer o de hij os es var iable, per o ent r e 0 y 5.

Pr opuest o: I mplement e el t ipo Nodo que per mit a cr ear est e t ipo de ár boles.

Y ¿par a qué sir ven est os ár boles? En el f ondo, lo que hace un comput ador con un j uego de
aj edr ez es analizar una ser ie de movidas pr ef abr icadas dependiendo de la posición en la que se
encuent r e el t abler o. Est as posiciones pueden ser MI LLONES y ser ía bast ant e dif ícil r ealizar
una búsqueda en un ar r eglo o list as de millones de dat os par a encont r ar la mej or movida.

Así que los ár boles per mit en i r seleccionando un Nodo (un est ado) que indica la posición del
t abler o, y sus Hij os (que pueden ser muchos) que r epr esent an las posibles movidas que t iene el
comput ador en ese moment o. Además, las hoj as del ár bol de decisión son los posibles t ér minos
del j uego. ¡Hey!, ¿per o eso signif icar ía que el comput ador siempr e sabe cómo ganar ? Por
supuest o que no, ya que si analizar a el camino más cor t o par a llegar a una hoj a, est o le t omar ía
a la comput ador a más r ápida unos días, y es mucho en un j uego de aj edr ez. Es por eso que
ut ilizan pr of undidad y evalúan la mej or j ugada según un mini -ár bol de alt ur a n con el cual puede
j ugar .

2 5
-1 0
1 3
3 4
5 9
12 13
8 10 2 3
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

194
Es decir :












¿I nt er esant e no?. Per o est o ár boles ya son di f íciles de t r abaj ar , por lo que nos cent r ar emos en
los ár boles binar ios como nuest r a nueva est r uct ur a de dat os.

Def inir emos ent onces un Nodo par a un ár bol binar io de la siguient e f or ma:

class Nodo {
public Object info; // Recuerda que el tipo puede cambiar
public Nodo izq, der; // Los nodos hijos

public Nodo(int o) { // Constructor para crear un nodo
this.info = o;
this.izq = null;
this.der = null;
}
}

Est a f or ma básica cumple con lo mínimo que es necesar io par a t ener un nodo de ár bol, por lo
que se le puede agr egar cosas como que sean compar ables, o t al vez un cr it er io de decisión de
cuál va a la der echa o izquier da de ot r o.

Ent onces, par a inser t ar en el ár bol, en su f or ma genér ica, es:

// Creación del nuevo nodo
Nodo p = new Nodo(x);

// Inicio del recorrido del árbol hasta el lugar (f) donde va.
Nodo q = this.raiz;
Nodo f = null;
while (q != null) {
f = q;
if (q.info > p.info)// Criterio para que vaya por la izquierda
q = q.izq;
else // Criterio para que vaya por la derecha
q = q.der;
}

// Inserción
if (f == null) // Si es la raız del árbol (árbol vacıo)
this.raiz = p;
else { // Si en f tenemos una hoja
if (f.info > p.info) // Si va a la izquierda de la hoja (f)
Pr of undidad 2
Pr imer a Decisión
Posibles J ugadas
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

195
f.izq = p;
else // Si va a la derecha de la hoja (f)
f.der = p;
}

Est a ver sión it er at iva de la inser ción se basa en que los nodos son valor es compar ables como
los númer os. Per o es f ácil t r ansf or mar lo par a que f uncione con ot r os t ipos de dat os.

Ahor a bien, es bast ant e sencillo inser t ar , sin embar go, el pr oblema viene cuando hay que
eliminar , por que si eliminamos un nodo int er no ¿qué hacemos con sus hij os?. Veamos t odos los
casos:

// Recorrido para encontrar el valor x
Nodo q = raiz;
Nodo f = null; // Guardaremos el padre del que vamos a eliminar.
while(q != null && q.info <> x) {
f = q;
if (q.info > p.info)// Criterio para que vaya por la izquierda
q = q.izq;
else // Criterio para que vaya por la derecha
q = q.der;
}

// Eliminamos
if (q != null) { // Si fuera null, significa que no está.
// Se guardan los hijos del que vamos a eliminar
Nodo qi = q.izq;
Nodo qd = q.der;

// Se elige cuál de los dos va a colgar del padre de q
// En este caso elegiremos el árbol derecho pero
// Podrıa haber sido al revés.
f = qd;

// Luego se pone el lado derecho, en la hoja más a
// la izquierda de qd.
Nodo r = qd;
Nodo hi = null;
while(r != null) {
hi = r;
r = r.izq;
}

if (hi != null) // Si existe la rama izquierda
hi.izq = qi;
else
f = qi;
}

¡OJ O QUE QUEDA PENDI ENTE BORRAR LA RAI Z! (Pr opuest o).

Ár boles de Búsqueda Binar ia: Los ár boles de búsqueda binar ia (ABB) son aquellos que sus
hij os cumplen una condición de or den con sus padr es, que no per mit en duplicados y que sir ven
par a r ealizar búsquedas en un t iempo O(Log n) en un conj unt o de dat os “or denados”.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

196
Gr an par t e de la ut ilidad de los ár boles binar ios y en especial de los ABB es que los nodos que
se van inser t ando en el ár bol, siempr e van quedando en f or ma “or denada”.

Per o ¿a qué se r ef ier e con “or denado”?. La condición de que un ár bol sea ABB es que el sub-
ár bol hij o izquier do es siempr e MENOR que el nodo y el sub-ár bol hij o der echo es siempr e
MAYOR que el nodo.








Est o per mit e que las búsquedas se r eduzcan bast ant e, ya que en el caso pr omedio NO se debe
r ecor r er el ár bol complet o par a encont r ar el valor buscado.

Veamos un ej emplo: Dado el siguient e ár bol:

Buscar el númer o 7 cost ar ía solo pasar por 3 nodos:

1. Compar ar el 7 con la r aíz del ár bol (4). Como es
mayor , nos ir emos por la der echa.

2. Compar ar el 7 con el nodo de la der echa de la
r aíz (9). Como es menor , nos vamos por la
izquier da.

3. Compar ar el 7 con el nodo de la izquier da de
(9). Como es el 7... ¡BI NGO!


Si lo hubiésemos dispuest o en una list a enlazada, ést a quedar ía or denada de la siguient e f or ma:
2-4-7-8-9-11. Casualment e es la misma cant idad de nodos. Per o si vamos al caso del 11, en el
ár bol nos cuest a 3 nodos, y en la list a enlazada 6 nodos, es decir , el t amaño de la list a. Malo,
malo, malo.

Veamos como quedar ía el algor it mo de búsqueda de un nodo en un ár bol ABB:

// Suponemos x como valor para buscar

// Para recorrer
Nodo q = raiz

while (q != null && q.info <> x) {
if (q.info > x)
q = q.izq;
else
q = q.der;
Mayor que Menor que
4
2 9
7
11
8
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

197
}

if (q == null)
// NO LO ENCONTRAMOS
else
// LO ENCONTRAMOS y está en q

El pat r ón es bast ant e simple, ya que lo único que hace es ir decidiendo que r ama coger par a
cont inuar la búsqueda.

Con est e últ imo pat r ón de pr ogr amación hemos vist o los 3 básicos que son ut ilizados en los
ár boles binar ios y ABB: I nser ción, Eliminación y Búsqueda. Ahor a veamos pr áct icament e cómo
lo vemos est o dent r o de un pr ogr ama en J ava:

Declar emos pr imer o una clase que nos per mit a modelar el Nodo consider ando númer os r eales:

public class Nodo {
public double info;
public Nodo izq, der;

public Nodo (double x) {
this.info = x;
this.izq = null;
this.der = null;
}
}

Ya t enemos lo que es un nodo. Ahor a veamos una r epr esent ación de ár bol con las 3 oper aciones
básicas: I nser t ar un element o, Eliminar un element o y Buscar un element o:

public class ABB {
public Nodo raiz;

// Inicializa el árbol de búsqueda binaria.
public ABB() {
this.raiz = null;
}

// Para insertar el valor x.
public void insertar (double x) {
// Creación del nuevo nodo
Nodo p = new Nodo(x);

// Se busca donde va el nuevo nodo
Nodo q = this.raiz;
Nodo f = null;
while (q != null) {
f = q;
if (q.info > p.info)
q = q.izq;
else
q = q.der;
}

// Inserción del nuevo nodo
if (f == null)
this.raiz = p;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

198
else {
if (f.info > p.info)
f.izq = p;
else
f.der = p;
}
}

// Para eliminar un valor x del árbol.
// Retorna el nodo eliminado.
// En caso de no encontrarlo, retorna null.
public Nodo eliminar (double x) {
// PENDIENTE
}

// Para buscar un valor x en el árbol
// Será semi-recursivo
public Nodo buscar (double x) {
return buscar(x, this.raiz);
}

private Nodo buscar (double x, Nodo p) {
// Casos base
if (p == null) return null; // No está
if (p.info == x) return p; // Lo encontramos

// Paso recursivo
if (p.info > x)
return buscar(x, p.izq);
else
return buscar(x, p.der);
}
}

Solo f alt a ver una aplicación pr áct ica de est as component es. Se desea or ganizar un gr upo de
valor es t omados en el labor at or io. Par a ello debe imi t ar el diálogo:

Ingrese valor? 3.7
Ingrese valor? -1
Ingrese valor? 8.2
...

Ingrese valor?
(SOLO ENTER)

Listas las lecturas!.
Buscar Lectura? 5.7
No está la lectura!!

Buscar Lectura? -3.5
Lectura encontrada!!


...

La solución ser ía bast ant e senci lla (main):

public class Lecturas {
public static BufferedReader bf = new BufferedReader(
new InputStreamReader(System.in));

public static void main (String args[]) {
// Creamos el árbol
ABB arbol = new ABB();

// Ingresamos los valores
System.out.print(”Ingrese Lectura?¨);
while ( (String l = bf.readLine()).length() > 0) {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

199
double x = new Double(l).doubleValue();
arbol.insertar(x);
System.out.print(”Ingrese Lectura?¨);
}
System.out.println(”Listas las lecturas!¨);

// Ahora consultamos
while (true) {
System.out.print(”Buscar Lectura?¨);
String l = bf.readLine();
double x = new Double(l).doubleValue();

Nodo p = ABB.buscar(x);
if (p == null)
System.out.println(”No está la lectura!¨);
else
System.out.println(”Lectura encontrada!¨);
}
}
}

Y ahí est á un pr oblema con su ciclo complet o, desde def inir la est r uct ur a básica hast a un
pr oblema aplicado.
Solución a la Mot ivación
(a) Los auxiliar es de CC10A cor r igen las pr egunt as de un gr upo de mechones de t odas las
secciones por separ ado. Se les ha pedido que cada vez que cor r ij an const r uyan un ar chivo
llamado “pX- auxNN” en donde X indica el númer o de la pr egunt a y NN el númer o del
auxiliar (numer ado ent r e 01 y 18). Lo más simpát ico es la cor r espondencia de cor r ección, es
decir siempr e ocur r e que:

• Auxiliar 1 cor r ige Pr egunt a 1
• Auxiliar 2 cor r ige Pr egunt a 2
• Auxiliar 3 cor r ige Pr egunt a 3
• Auxiliar 4 cor r ige Pr egunt a 1
• Auxiliar 5 cor r ige Pr egunt a 2
• ...

Se pide const r uir un pr ogr ama que per mit a leer TODOS LOS ARCHI VOS de las 3
pr egunt as del cont r ol 2, almacenándolas en memor ia, par a luego que un alumno ingr ese
su númer o int er no muest r e las not as de las 3 pr egunt as, el pr omedio del cont r ol y el
código del auxiliar que le cor r igió. Suponga que hay un máximo de 1000 alumnos (de 000
a 999) y que la est r uct ur a de los ar chivos es:

• Código int er no del alumno (3 car act er es)
• Not a del alumno en la pr egunt a (3 car act er es con . en medio)
Sol ución
class Alumno implements Comparable {
public int codigo;
public double[] notas;
public int[] auxs;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

200

public Alumno(int codigo) {
this.codigo = codigo;
this.notas = new double[3];
this.auxs = new int[3];
}

public void ponerNota(int p, double nota, int aux) {
this.notas[p] = nota;
this.auxs.[p] = aux;
}

public int compareTo(Object obj) {
return this.codigo - ((Alumno) obj).codigo;
}
}

class NotasControl {
// Lector de la Entrada Estándar
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));

static public void main (String args[]) {
// Arreglo que almacenará las notas y
// el código del auxiliar que corrigió
Alumno[] als = new Alumno[1000];

// Se inician notas en 1 y auxiliaries en 0
for (int x=0; x<1000; x++) {
als[x] = new Alumno(x);
for (int y=0; y<3; y++) {
als[x].ponerNota(y, 1.0, 0);
}
}

// Ciclo lector de las preguntas
int nn = 1;
for (int x=0; x<3; x++) {
String nombre = ”p¨;
nombre += x;
nombre += ¨-aux¨;
if (nn < 10)
nombre += ”0¨;
nombre += nn;

BufferedReader bf = new BufferedReader(
New FileReader(nombre));
String linea;
while( (linea=bf.readLine()) != null ) {
int cod = Integer.parseInt(
linea.substring(0, 3));
double nota = new Double(
linea.substring(3, 3)
).doubleValue();

als[cod].ponerNota(x, nota, nn);
}
bf.close();

nn++;
}

// Ya tenemos leido todos los datos.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

201
// Veamos el ciclo de consulta de notas.
while(true) {
System.out.print(”Código de alumno?¨);
int codigo = Integer.parseInt(in.readLine());

System.out.println(”Tus notas son: ”);
double suma = 0;
for (int p=0; p<3; p++) {
System.out.println(”Pregunta ” + (p+1) +
” = ” + als[codigo].notas[p] +
” (Aux: ” + als[codigo].auxs[p] +
”)¨);
suma += als[codigo].notas[p];
}
double prom = suma / 3;
System.out.println(”Promedio = ” + prom);
}
}
}

Queda más elegant e que la ver sión ant er ior , por que además si quisiér amos or denar los de alguna
f or ma bast ar ía llamar a uno de los mét odos de or denación adecuados par a “compar ables” y
list o.

Solo r ecuer da:

Est r uct ur a \ TDA Ar r eglo List a Ar bol
Pilas
Colas
Diccionar ios

Según est a t abla, las pilas y las colas se pueden implement ar (es muy común) con Ar r eglos y
List as, en cambio exist en ot r as est r uct ur as como los diccionar ios que se implement an con
ár boles.
Pr oblemas
(a) I mplement e un Tipo de Dat o compar able que modele un plat illo volador venusino. Los
plat illo volador es en Venus posee las siguient es car act er íst icas:

• Pat ent e int er galáct ica (alf anumér ico)
• Nombr e del pilot o (alf anumér ico)
• Númer o de pasaj er os (ent er o)
• Velocidad expr esada con r espect o a la velocidad luz (r eal ent r o 0 y 1)

Además, per mit a que la compar ación sea f lexible, es decir , que posea un swit ch que
per mit a compar ar ent r e la Pat ent e, Númer o de Pasaj er os y la Velocidad del plat illo.
Sol ución
class Platillo extends Comparable {
public String patente;
public String piloto;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

202
public int pasajeros;
public double velocidad;
public int compareRule;

public Platillo (String patente, String piloto,
int pasajeros, double velocidad) {
this.patente = patente;
this.piloto = piloto;
this.pasajeros = pasajeros;
this.velocidad = velocidad;
this.compareRule = 1; // Patente
}

public int compareTo(Object obj) {
switch (compareRule) {
case 1: // Patente
return this.patente.compareTo(
((Platillo) obj).patente);
case 1: // Piloto
return this.piloto.compareTo(
((Platillo) obj).piloto);
case 1: // Pasajeros
return this.pasajeros -
((Platillo) obj).pasajeros;
case 1: // Velocidad
return Math.round(this.velocidad -
((Platillo) obj).velocidad);
default: // Otros Casos
return -1;
}
}
}

(b) I mplement e una est r uct ur a de dat o basada en Pilas y Colas que cont r ole la ent r ada y salida
de plat illos venusinos desde su espaciopuer t o ubicado det r ás de la Luna. Siga las siguient es
car act er íst icas:

• Exist en plat illos que pueden ent r ar al f inal de una list a (númer o de pasaj er os > 10) y
ot r os que ent r an al pr incipio de la list a (los de pocos pasaj er os).
• Todos salen en or den, es decir , siempr e sale el pr imer o que est á en la list a (que no
siempr e coincide con el pr imer o que ent r ó.
• El máximo de naves per mit idas en el espaciopuer t o son de 10.
Sol ución
class EspacioPuerto {
protected String nombre;:
protected Comparable[] esclusas;
protected int beg, end;
protected boolean full;

public EspacioPuerto (String nombre, int n) {
this.nombre = nombre;
this.esclusas = new Comparable[n];
this.beg = 0;
this.end = 0;
this.full = false;
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

203
// Entrada de Prioridad
protected void push(Comparable obj) {
if (full)
return;
this.esclusas[this.beg] = obj;
this.beg--;
full = (this.beg == this.end);
}

// Entrada Normal
protected void put(Comparable obj) {
if (full)
return;
this.esclusas[this.end] = obj;
this.end++;
full = (this.beg == this.end);
}

// Salida
protected Comparable get() {
if (this.beg == this.end)
return null;
this.beg++;
return this.esclusas[this.beg-1];
}

// Despegue encapsulado
public Platillo despegue() {
return (Platillo) this.get();
}

// Aterrizaje
// Se indica el número de pasajeros y retorna donde entró
// 0. Espaciopuerto Lleno
// 1. Prioridad
// 2. Normal
public int aterrizaje(Platillo obj, int nPasajeros) {
if ( obj.pasajeros > nPasajeros ) {
this.push(obj);
return 1;
}
else {
this.put(obj);
return 2;
}
}
}

(c) Simule el siguient e diálogo que ocur r e en la t or r e de mando del espaciopuer t o venusino.

Bienvenido al Espaciopuerto Lunia

Identifique el tipo de movimiento de naves? Salida
No hay naves para una salida

Identifique el tipo de movimiento de naves? Llegada
Indique la patente de la nave? XKL390
Nombre del piloto? KILTARO
Número de pasajeros? 16
Velocidad de acercamiento? 0.5
Que el vuelo XKL390 del sr KILTARO reduzca su velocidad en 0.2c
antes de aterrizar por la entrada ALFA del espaciopuerto.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

204

Identifique el tipo de movimiento de naves? Llegada
Indique la patente de la nave? FWO442
Nombre del piloto? GURTINYU
Número de pasajeros? 3
Velocidad de acercamiento? 0.7
Que el vuelo FWO442 del sr GURTINYU reduzca su velocidad en 0.6c
antes de aterrizar por la entrada BETA del espaciopuerto.

Identifique el tipo de movimiento de naves? Salida
El vuelo FWO442 tiene el espacio libre para su despliegue por la
salida GAMMA del espaciopuerto. Sr. GURTINYU se le agradece su
visita a Lunia.

Not a: Todos los plat illos deben ent r ar a 0.3c por la ent r ada BETA y a 0.1c por la
ent r ada ALFA. Los comandos válidos son: Salida (par a salida de una nave), Llegada (par a
ingr esar una nave), Fin (par a t er minar ). Si no hay espacio en el espaciopuer t o, el
sist ema debe r et or nar “Que el vuelo esper e en el cuadr ant e X58 mient r as se desocupa
una de las esclusas de at er r izaj e”.
Sol ución
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
System.out.println(”Bienvenido al Espaciopuerto Lunia¨);
EspacioPuerto ep = new EspacioPuerto(”Lunia¨, 10);

while(true) {
System.out.print(”Identifique el tipo de movimiento ”+
de naves?¨);
String acc = in.readLine();

switch (acc.toLowerCase()) {
case ”salida¨:
Platillo p = ep.despegue();
if (p == null)
System.out.println(”No hay naves para ”+
”una salida¨);
else
System.out.println(”El vuelo ”+ p.patente+
¨ tiene el espacio libre para ”+
”su despliegue por la salida ”+
”GAMMA del espaciopuerto. Sr. ” +
p.piloto + ¨ se le agradece su ¨+
”visita a Lunia.¨);
case ”llegada¨:
Platillo p = new Platillo(Ӭ, Ӭ, 0, 0.0);
System.out.print(”Indique patente de la nave?¨);
p.patente = in.readLine();
System.out.print(”Nombre del piloto?¨);
p.piloto = in.readLine();
System.out.print(”Número de pasajeros?¨);
p.pasajeros = Integer.parseInt(in.readLine());
System.out.print(”Velocidad de acercamiento?¨);
p.velocidad = new Double(
in.readLine()).doubleValue();
int entrada = ep.aterrizaje(p, 10);
if (entrada == 0)
System.out.println(”Que el vuelo espere ”+
”en el cuadrante X58 mientras ”+
”se desocupa una de las esclusas ”+
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

205
”de aterrizaje¨);
else {
if (entrada == 1)
String puerta = ”ALFA¨;
else
String puerta = ”BETA¨;
System.out.println(”Que el vuelo ” +
p.patente + ¨ del sr ” + p.piloto +
¨ reduzca su velocidad en ” +
(p.velocidad - 0.3) +
¨c antes de aterrizar por ” +
”la entrada ” + puerta +
¨ del espaciopuerto.¨);
case ”fin¨:
break;
default:
System.out.println(”Opción no válida¨);
}
}
in.close();

(d) Se desea implement ar un codif icador Mor se de t ext os ut ilizando un ABB en donde:

• Por la der echa de un Nodo cor r esponde a un punt o (.)
• Por la izquier da de un Nodo cor r esponde a una r aya (-)

Además, la cant idad de punt os y r ayas dependen a qué pr of undidad dent r o del ár bol se
encuent r a la let r a ubicada.

1) Def ina la clase nodo que almacena la let r a.

public class NodoMorse {
public String letra;
public NodoMorse punto, raya;

public NodoMorse(String letra) {
this.letra = letra;
this.punto = null;
this.raya = null;
}
}

2) I mplement e el mét odo aleat or io que const r uye el ár bol Mor se con las let r as del
alf abet o. Suponga que exist e un mét odo est át ico en la clase Mor se llamado St r ing
codigoMor se(St r ing let r a) que dada una let r a del alf abet o, r et or na la cadena de
punt os y r ayas que r epr esent an esa let r a en código mor se.

Not a: Recuer de que la r aíz del ár bol debe ser pasada por par ámet r o par a hacer lo
r ecur sivo.

private void insertarLetra (NodoMorse nodo,
String letra,
String cadenaMorse) {
// No se puede insertar
if (cadenaMorse.length <= 0)
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

206
return;

// Si se puede insertar
if (cadenaMorse.length() == 1) {
if (cadenaMorse.equals(”.¨))
nodo.izq = new NodoMorse(letra);
else
nodo.der = new NodoMorse(letra);
return;
}

// Si no, buscar donde
if (cadenaMorse.charAt(0).equals(”.¨))
insertarLetra (nodo.izq, letra,
cadenaMorse.substring(1));
else
insertarLetra (nodo.der, letra,
cadenaMorse.substring(1));
}

public void llenarArbol (NodoMorse nodoRaiz) {
String alfabeto = ”ABCDEFGHIJKLMNOPQRSTUVWXYZ¨;

// La raız del árbol no tiene letra
nodoRaiz = new NodoMorse(Ӭ);

// Insertar cada una
for (int i=0; i<alfabeto.length(); i++)
insertarLetra(nodoRaiz,
alfabeto.charAt(i),
Morse.codigoMorse(alfabeto.charAt(i));
}

3) Desar r olle el mét odo que le per mit a pasar escr ibir desde una codif icación mor se a
t ext o nor mal ut ilizando el pat r ón de búsqueda en ár boles binar ios.

Not a: Suponga que la r aíz del Ár bol est á en t his. r aiz. Recuer de que cada let r a de la
palabr a se separ a por 1 espacio y las palabr as por 2 espacios.

private String buscarLetra(NodoMorse p, String cadena) {
// No hay que transformar
if (p == null)
return Ӭ;

// Saca letra
String caracter = cadena.charAt(0);
if (cadena.length() == 1) {
if (caracter.equals(”.¨))
return p.izq.letra;
else
return p.der.letra;
}

// Buscamos recursivamente
cadena = cadena.substring(1);
if (caracter.equals(”.¨))
return buscarLetra(p.izq, cadena);
else
return buscarLetra(p.der, cadena);
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

207

public String convierteTexto (String textoMorse) {
NodoMorse p = this.raiz;
String morse = textoMorse;
String textoFinal = Ӭ;
int esp = morse.indexOf(” ”);
while (esp >= 0) {
String cadena = morse.substring(0, esp);
morse = morse.substring(esp + 1);

String letra = buscarLetra(raiz, morse);
if (letra.length() <= 0) // No hay letra, era espacio
textoFinal = textoFinal + ” ”;
else
textoFinal = textoFinal + letra;

esp = morse.indexOf(” ”);
}

return textoFinal;
}

4) Escr iba l a clase Mor se que cont iene los mét odo ant er ior ment e pedidos en (b) y (c) y
cr ee un const r uct or que per mit a llenar aut omát icament e el ár bol. Solo enuncie el
mét odo est át ico codigoMor se mediant e su f ir ma. Además agr egue un mét odo que
t r ansf or me (ut ilizando codigoMor se) un t ext o en codif icación mor se.

public class Morse {
private NodoMorse raiz;

// Constructor
public Morse() {
llenarArbol(this.raiz);
}

// Método Estático
public static String codigoMorse(String letra) {...}

// Métodos antes vistos
public void llenarArbol (NodoMorse nodoRaiz) {...}
private void insertarLetra (NodoMorse nodo,
String letra,
String cadenaMorse) {...}

private String buscarLetra(NodoMorse p, String cadena) {...}
public String convierteTexto (String textoMorse) {...}

// Transforma a morse
public String convierteMorse (String texto) {
String textoMorse = Ӭ;
for (int i=0; i<texto.length(); i++) {
if (texto.charAt(i).equals(” ”);
textoMorse = textoMorse + ” ”;
else
textoMorse = textoMorse +
Morse.codigoMorse(
texto.charAt(i));
}
return textoMorse;
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

208
}

5) Pr opuest o: Aplique t odo lo ant er ior al siguient e diálogo.

Codificador Morse
Creando Diccionario... Ok!

Ingrese una frase: Hola como estas
En morse se escribe: [TEXTO EN MORSE]

Ingrese un texto en morse: ... --- ...
El texto que escribió: SOS

(e) I mplement e la Est r uct ur a de Dat os List a que per mit a manipular una list a enlazada con los
siguient es mét odos:

Mét odo Descr ipción
List a() Cr ea una list a vacía
void poner (Nodo o, int i) Pone en la posición i -ésima (como en un ar r eglo)
Nodo sacar (int i) Saca el i-ésimo element o (como en un ar r eglo)
Sol ución
class Lista {
private Nodo cabeza;
public int largo; // Solo si es necesario

public Lista() {
this.cabeza = null;
this.largo = 0;
}

public void poner(Nodo o, int i) {
if (i > this.largo)
return; // No se pone más allá del largo

Nodo q = this.cabeza
for (int n=0; n<i; n++)
q = q.sgte;

o.sgte = q.sgte;
q.sgte = o

this.n++;
}

public Nodo sacar(int i) {
if (i >= this.largo)
return null; // No existe más allá del largo

Nodo q = this.cabeza
for (int n=0; n<i; n++)
q = q.sgte;

Nodo p = q.sgte;
q.sgte = p.sgte;
this.n--;

Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

209
return p;
}
}

(f ) Ut ilice la List a ant er ior par a implement ar una Pila de element os. Recuer de la
implement ación que se hizo par a los ar r eglos y podr á hacer el símil con las list as enlazadas.
Sol ución
class Pila {
private Lista pila;

public Pila() { // Ya no es necesario ponerle tope.
pila = new Lista();
}

public void poner(Object o) {
Nodo p = new Nodo(o);
pila.poner(Nodo, pila.largo);
}

public Object sacar() {
Nodo p = pila.sacar(pila.largo-1);
return p.info;
}
}

(g) Pr opuest o. Haga lo mismo que en (b) par a una Cola.

(h) En el caso de las list as doblement e enlazadas, se pueden dif er enciar 2 nodos apunt ados: el
siguient e y el ant er ior , sin embar go, el ant er ior t iene como siguient e el nodo que lo apunt a
(es decir , se puede r ecor r er t ant o de ida como de vuelt a).






Como podemos ver en la gr áf ica, est as list as quedan def inidas por un campo adicional
en la est r uct ur a. A modo de ej er cicio pr opuest o ser á int er esant e que implement en
est as list as cr eando una est r uct ur a Nodo apr opiada y una est r uct ur a List a que lo
manej e con la siguient e est r uct ur a:

Mét odo Descr ipción
List a() Cr ea una list a vacía
void poner (Nodo o, int i) Pone en la posición i -ésima (como en un ar r eglo)
Nodo sacar (int i) Saca el i-ésimo element o (como en un ar r eglo)
Nodo ant er ior (Nodo x) Devuelve un punt er o al ant er ior del nodo x
Nodo siguient e (Nodo x) Devuelve un punt er o al siguient e del nodo x

En los casos de ant er ior (Nodo x) y siguient e(Nodo x) debe pensar que:

cabeza
I nf o I nf o I nf o
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

210
• Debe buscar el nodo x.
• Si no encuent r a el nodo x, debe r et or nar NULL.
• Si encuent r a el nodo x, debe r et or nar su siguient e o ant er ior (según
cor r esponda).

(i) El pr oblema básico es inser t ar los nodos en el ár bol par a así ir const r uyendo est a
est r uct ur a. La r egla es una r egla mat emát ica que nos per mit ir á dif er enciar cuáles son los
dígit os de la r epr esent ación binar ia del númer o (base 2):

0 = 0
1 = 1
2 = 10
3 = 11
4 = 100
5 = 101
6 = 110
7 = 111
8 = 1000
9 = 1001
10 = 1010
11 = 1011
12 = 1100
13 = 1101
14 = 1110
15 = 1111
16 = 10000
etc.

Par a ello, sabemos que, par a conver t ir a binar io un númer o N, debemos descomponer lo
en una sumat or ia:
N = an * 2
n
+... + a2 * 2
2
+ a1 * 2 + a0 = Σ ai
* 2
i

Con ai = 1, 0

Ahor a, ¿cómo se const r uir ía el númer o binar io?

La r epr esent ación binar ia es la ser ie de coef icient es de la sumat or ia uno t r as ot r o (por
sus valor es que son 1 y 0, es decir , valor es binar ios).

Analizando un poco llegar emos a que la conver sión se t r ansf or ma al siguient e algor it mo:

int NUM = Número que buscamos descomponer;
String binario;

// Buscamos el mayor ındice que puede servir
int n = 0;
while (NUM > Math.pow(2, n)) n++;

// Ponemos el primer valor
binario = ”1¨;
NUM = NUM - Math.pow(2, n);

Se hace en base a pot encias de 2:

El n-ésimo t ér mino se aplica si el
númer o se puede descomponer como
2
n
+ ot r os t ér minos.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

211
// Iteramos desde n hasta 0 para ir encontrando los valores de
N
for (int i = n - 1; i >= 0; i--) {
if (NUM >= Math.pow(2, i)) {
binario = binario + ”1¨;
NUM = NUM - Math.pow(2, i);
}
else {
binario = binario + ”0¨;
}
}

Ahor a, deber emos hacer el pr ocedimient o que inser t a valor es en un ár bol que cumple
con est a car act er íst icas: Los de la izquier da poseen 1 y los de la der echa 0. Suponemos
que exist e la r aiz del ár bol en la var iable de inst ancia (t his.r aiz):

private String insertar (int numero) {
// Retorna la representación binaria
// Para recorrer el árbol
String q = this.raiz;

// Construimos su representación binaria
int num = numero;
String binario;

int n = 0;
while (num > Math.pow(2, n)) n++;

// Ponemos el primer valor
binario = ”1¨;
num = num - Math.pow(2, n);

// Iteramos para ir encontrando los valores de N
for (int i = n - 1; i >= 0; i--) {
if (NUM >= Math.pow(2, i)) {
binario = binario + ”1¨;
NUM = NUM - Math.pow(2, i);
}
else {
binario = binario + ”0¨;
}
}

// En orden inverso, comenzamos a recorrer el árbol
// hasta encontrar la hoja en donde insertaremos el
nodo.
Nodo p = new Nodo(numero);

for (int j = binario.length(); j > 0; j--) {
if (binario.charAt(j) == ”1¨)
q = q.izq;
else
q = q.der;
}
if (binario.charAt(0) == ”1¨)
q.izq = p;
else
q.der = p;

return binario;
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

212

Como caso base, el nodo RAI Z no debe t ener valor (suponemos –1). Per o ¿par a qué sir ve
est e mét odo?. Est e mét odo es út il al moment o de llenar el ár bol con númer o ent er os:

public void llenar(int maximo) {
this.raiz = new Nodo(-1);

for (int n = 0; n <= maximo; n++)
String x = insertar(n);
}

Con est o, llenamos un ár bol binar io con la r epr esent ación binar ia de un númer o maximo
de númer os ent er os. Hagamos un mét odo que consult e ahor a la r epr esent ación binar ia
de un númer o ut ilizando el ár bol. Est e mét odo consult ar (n) ser á semi -r ecur sivo:

public String consultar(int n) {
String binario = null;

// Buscamos a ambos lados y solo guardamos
// cuando lo encontremos
binario = ”1¨ + consultar(n, this.raiz.izq);
if (binario == null)
binario = ”0¨ + consultar(n, this.raiz.der);

// Borramos los 0 a la izquierda, porque no valen nada
while (binario.charAt(0) == 0)
binario = binario.substring(1);

return binario;
}

// El método que si es recursivo busca el valor n a
// partir desde el nodo p.
private String consultar(int n, Nodo p) {
// Si no está
if (p == null) return null

// Si lo encontramos
if (p.info = n) return Ӭ;

// Buscamos al lado correcto
String pre, bin;
if (n > p.info) {
pre = ”1¨;
bin = consultar(n, p.izq);
}
else {
pre = ”0¨;
bin = consultar(n, p.der);
}
if (bin = null) return null;

// Vamos componiendo paso a paso
return pre + bin;
}

List o. Es un poquit o dif icil de ver , per o solo i mpor t a analizar la ut ilización del ár bol
binar io par a almacenar est e t ipo de est r uct ur as.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XVIII: Tipos y Estructuras de Datos

213

(j ) Pr opuest o. Const r uir una clase Ar bolDeBinar ios que cumpla con las f uncionalidades:

• void llenar (int n) el ár bol.
• St r ing buscar (int n) una r epr esent ación dent r o del ár bol.
• Ar bolDeBinar ios() const r uye un ár bol vacío (const r uct or )

También debe escr ibir la implement ación de Nodo que sopor t e est a est r uct ur a. Sea
r igur oso.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIX: Archivos de Acceso Aleatorio

214
Capít ulo XI X: Ar chivos de Acceso Aleat or io
Mot ivaci ón
Hast a ahor a hemos vist o que exist en f or mas par a acceder ar chivos en J ava. Est os ar chivos por
lo gener al son ar chivos de t ext os que podemos escr ibir en el bloc de not as o en ot r o edit or de
t ext os cualquier a.

La desvent aj a de est os ar chivos además que solo son ar chivos de st r ings sin ningún f or mat o, es
que por lo gener al ocur r e es la secuencialidad de la lect ur a de ellos, es decir , al moment o de
leer una línea no se puede volver at r ás.

Par a ello exist en unos t ipos de ar chivos ”binar ios” que poseen las car act er íst icas:

• Guar dar t ext o con f or mat o
• Guar dar dat os binar ios como imágenes, música, et c.
• Avanzar y r et r oceder dent r o del ar chivo a discr eción.

En est a clase ver emos lo út il que puede ser aplicar est os ar chivos en algunos pr oblemas
22
.
Concept o
Byt e
Un byt e es un númer o ent er o ent r e 0 y 255 con el cuál se r epr esent an
dist int os t ipos de inf or mación.

Un byt e por lo gener al se asocia mucho a los siguient e t ipos de element os:

• Un númer o ent r e 0 y 255 (aunque par ezca obvio, no lo es t ant o)
• Un car áct er (let r a o símbolo de la t abla ASCI I )
• Una t onalidad de gr is
• Un númer o en el r ango [ -128, 127] (es desplazar el int er valo 0 y 255 en –128)

o cualquier pieza de inf or mación que posea a lo más 256 est ados dif er ent es.

Es int er esant e not ar que mient r as más byt es se ocupen par a r epr esent ar cier t a inf or mación,
más det alle se puede obt ener de ést a. Por ej emplo, las t ar j et as de video monocr omát ica usa 1
byt e par a r epr esent ar 8 punt os en pant alla; la t ar j et a EGA usaba en algunos caso 1 byt e par a
r epr esent ar 2 punt os en 16 color es; la t ar j et a VGA usaba 1 byt e por punt o, pues podía t ener

22
Desde que las Bases de Dat os se han conver t ido accesibles, los Ar chivos de Acceso
Aleat or io han per dido par t e de su aplicabilidad. Per o nunca est á demás ver br evement e como
ut ilizar los en pr oblemas más sencillos y de poca enver gadur a de dat os.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIX: Archivos de Acceso Aleatorio

215
hast a 256 color es; en cambio las t ar j et as de video act uales usan más de un byt e par a el
millones de color es que compar t e cada punt o.

El byt e es en el f ondo la component e pr incipal en comput ación. Los t ipos pr imit ivos de J ava que
hemos usado t ambién se r epr esent an en byt es:

• bolean usa 1 byt e
• int usa 4 byt es
• double usa 8 byt es
• et c...
Ar chivo de Acceso Aleat or io
Est r uct ur a de Dat o pr edef inida (modelada en una clase J ava) similar a
un ar r eglo que se almacena en disco. Los element os de est e ar r eglo son
byt es.

En est e caso, quedar ía def inido ent onces como un ar r eglo de byt es o let r as escr it as en disco.
Per o ¿qué dif er encia hay ent r e un ar chivo de t ext o plano (Buf f er edReader ) con est e t ipo de
element os?

Bueno, la dif er encia en que un Ar chivo de Acceso Aleat or io posee algunas car act er íst icas
pr opias como:

• No solo almacenar let r as
• Solo es necesar io abr ir una vez el ar chivo par a r ecor r er lo complet ament e
• No es necesar io leer lo en f or ma secuencial
• También se puede ut ilizar un mismo ar chivo par a leer , escr ibir y act ualizar dat os.
RandomAccessFil e
Es la clase J ava que def ine un Ar chivo de Acceso Aleat or io.

RandomAccessFile (RAF) es la clase J ava que r epr esent a uno de nuest r os ar chivos. Per o ¿qué
t iene de especial? ¿cómo se usa?. Fij emos nuest r os esf uer zos en r esponder est as pr egunt as.
Sint axis
Par a cr ear un RAF se debe usar la siguient e sint axis:


RandomAccessFile r = new RandomAccessFile(”<archivo>ó, ”<ops>ó);


En donde:

• <ar chivo>: nombr e del ar chi vo que se desea ut ilizar .
• <ops>: opciones del ar chivo como son lect ur a (“r ”) y/ o escr it ur a (“w”);
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIX: Archivos de Acceso Aleatorio

216

Ej emplos:

// Abrir archivo datos.txt para lectura
RandomAccessFile r = RandomAccessFile(”datos.txt¨, ”r¨);

// Abrir archivo datos.txt para escritura
RandomAccessFile r = RandomAccessFile(”datos.txt¨, ”w¨);

// Abrir archivo datos.txt para lectura/escritura
RandomAccessFile r = RandomAccessFile(”datos.txt¨, ”rw¨);

Ot r o punt o impor t ant e es saber el lar go de un RAF o lo mismo es saber ¿dónde t er mina el
ar chivo?. Pues par a eso se puede obt ener con r . lengt h(), mét odo que r et or nar á la cant idad de
byt es que posee el RAF en cuest ión.

Veamos algunos pat r ones de pr ogr amación aplicados a RAF.
Escr it ur a de un RAF
Par a escr ibir en un RAF se ut i lizan los siguient es mét odos:

• wr it eI nt (x) escr ibe en el RAF el ent er o x (4 byt es).
• wr it eDouble(x) escr ibe en el RAF el double x (8 byt es).
• wr it eUTF(x) escr ibe en el RAF el st r ing x (n+2 byt es).

Como podemos ver , se indica la cant idad de byt es que ut iliza escr ibir est os valor es en un RAF.
En el caso de los St r ings, la cant idad de byt es es siempr e igual al lar go del st r ing (1 byt e por
car áct er ) más 2 byt es al inicio de la cadena que indica la cant idad de byt es que cor r esponden
al St r ing (nuevament e el lar go). Algo como:

2 6 E s t e s t r i n g t i e n e 2 6 b y t e s

Largo
del
STRING
Bytes que representan los caracteres del STRING

Bytes que se escriben realmente en el RAF

Por lo t ant o calcular la cant idad de car act er es que se deben leer debe ser cuidadosament e
consider ado con los 2 byt es adicionales de cada St r ing.
Lect ur a de un RAF
Par a leer en un RAF se ut ilizan los siguient es mét odos:

• r eadI nt () lee un ent er o desde el RAF (4 byt es).
• r eadDouble(x) lee un double desde el RAF (8 byt es).
• r eadUTF(x) lee un st r ing desde el RAF (n+2 byt es).

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIX: Archivos de Acceso Aleatorio

217
Mover se dent r o de un RAF
Una de las vent aj as que poseen los ar chivos binar ios es su capacidad de mover el cabezal de
lect ur a/ escr it ur a hacia delant e o at r ás a gust o.

El mét odo que per mit e est o es seek(n) en donde se le especif ica como par ámet r o el númer o de
byt e al cual se desea desplazar , es decir , como el índice dent r o de est e gr an ar r eglo de byt es.

Como los RAF puedes ser muy gr andes, un ent er o no bast a par a indicar la posición, por lo que la
f ir ma del mét odo seek es:


public void seek(long n);


Es por eso que ant es de hacer un seek, se debe r ealizar un cast explícit o par a indicar que
est amos en pr esencia de un long como:

r.seek( (long) (3*4) ); // 3 enteros del comienzo (12 bytes)

Aunque hacer un seek es una vent aj a sobr e los ar chivos de t ext o, su ut ilización debe ser con
“mucho cuidado” pues es demasiado cost oso par a el pr ocesador . Como compar ación, un seek
cuest a lo mismo que leer 20.000 car act er es desde un ar chivo de t ext o plano.

También, es út il saber el lugar en el que se encuent r a det enido un RAF. Par a ello se usa el
mét odo get FilePoint er () que ent r ega el # de byt e en donde est á par ada la cabeza lect or a.
Ej emplo Pr áct ico
Per o ya bast a de cháchar a y veamos como usamos est o en la pr áct ica. Supongamos que
quer emos almacenar las not as de 100 alumnos en un ar chivo de t ext o plano:

BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(
new FileWriter(”notas.txt¨));
for (int n=0; n<100; n++) {
System.out.print(”Nombre? ”);
String nombre = in.readLine();
System.out.print(”Nota? ”);
double nota = new Double(
in.readLine()).doubleValue();
out.println(n + ” ” + nombre + ” ” + nota);
}
out.close();
in.close();

y si quisiér amos buscar el alumno 53 deber íamos hacer lo siguient e:

BufferedReader in = new BufferedReader(
new FileReader(”notas.txt¨));
for (int n=0; n<53; n++) {
String alumno = in.readLine();
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIX: Archivos de Acceso Aleatorio

218
}
in.close();
System.out.println(alumno);

Clar ament e est o se convier t e en algo cost oso, per o que con RAF es algo más sencillo. Pr imer o
que t odo si quer emos almacenar t odos esos dat os, debemos saber cuánt os byt es usar emos. En
gener al si los nombr es TODOS miden 30 car act er es, suponemos que el r egist r o complet o mide
4 byt es (ent er o) + 8 byt es (r eal) + 30 byt es (St r ing) + 2 byt es (lar go del St r ing) = 44 byt es.

BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
RandomAccessFile out = new RandomAccessFile(”notas.txtó, ”wó);
for (int n=0; n<100; n++) {
out.writeInt(n);
System.out.print(”Nombre? ”);
out.writeUTF(in.readLine());
System.out.print(”Nota? ”);
out.writeDouble(new Double(in.readLine()).doubleValue());
}
out.close();
in.close();

Per o además la búsqueda del alumno 53 ser ía:

RandomAccessFile arch = new RandomAccessFile(”notas.txtó, ”rwó);
arch.seek(44 * 53);
String alumno = arch.readInt() + ” ” +
arch.readUTF() + ” ” +
arch.readDouble();
System.out.println(alumno);
arch.close();

Es una maner a dist int a de ver el mundo, ¿no?
Lect ur a y Escr it ur a de St r ings
Uno de los pr oblemas más gr aves es que los st r ings no son t odos iguales, lo que nos impide
saber la cant idad de byt es r eales que t iene el ar chivo.

Los pr ogr amador es ast ut ament e por supuest o se dier on cuent a que podr ía ser un pr oblema
minimizado si ellos car gar an con el peso de cr ear est os UTF de maner a que par a un ar chivo
siempr e los st r ings t uvier an el mismo lar go. Es por eso que ant es de poder escr ibir un RAF es
necesar io escr ibir un mét odo que unif or me nuest r os st r ings de un lar go f ij o. ¿Cómo?.
Poniéndole espacios por supuest o, es decir :

public String convertUTF (String txt, int largo) {
String s = txt;

// Trunca el string si es más grande
if (s.length() > largo)
return s.substring(0, largo);

// Rellena con espacios si le faltan
for (int n=s.length(); n<largo; n++)
s = s + ” ”;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XIX: Archivos de Acceso Aleatorio

219
return s;
}

Con est e sencillo mét odo conver t imos los st r ings a un lar go def inido. Por lo t ant o, ant es de
escr ibir un st r ing, har emos:

arch.writeUTF(convertUTF(s, 30)); // Uniforma s a 30 bytes
Pr oblema
Veamos un pr oblema sencillo pr imer o. Se desea modelar un sist ema de acceso con claves y
per mi sos de usuar io a t r avés de ar chivos binar ios (por segur idad). Par a ello se sabe que cada
usuar io posee los siguient es campos (var iables de inst ancia):

• Nombr e de Usuar io (8 car act er es)
• Nombr e Complet o (40 car act er es)
• Clave de Acceso (11 car act er es)
• Per miso de Lect ur a (1 = SI / 2 = NO)
• Per miso de Escr it ur a (1 = SI / 2 = NO)

Par a ello se le pide que implement e el t ipo de dat o que per mit a modelar est o. La idea que debe
declar ar :

(a) Var iables de I nst ancia
(b) Const r uct or que per mit a el ingr eso de los dat os (TODOS)
(c) Mét odo que per mit a escr ibir en un RAF el r egist r o (debe r ecibir el nombr e del ar chivo
y escr ibir lo al f inal de ést e).
Sol ución
public class Usuario {
// Largo del registro
private final int largoRegistro = (8 + 2) + (40 + 2) +
(11 + 2) + 4 + 4;

// Variables de Instancia
public String username, password;
public String nombre;
public int lectura, escritura;

// Constructor
public Usuario (String p1, String p2, String p3,
int p4, int p5) {
this.username = p1;
this.password = p3;
this.nombre = p2;
this.lectura = p4;
this.escritura = p5;
}

// UTF para String
private String convertUTF (String txt, int largo) {
String s = txt;

Java: del Grano a su Mesa (Version 1.3)
Capitulo XIX: Archivos de Acceso Aleatorio

220
// Trunca el string si es más grande
if (s.length() > largo)
return s.substring(0, largo);
// Rellena con espacios si le faltan
for (int n=s.length(); n<largo; n++)
s = s + ” ”;
return s;
}

// Guarda en RAF
public void writeToRAF (String filename) {
// Abrir el archivo
RandomAccessFile a = new RandomAccessFile(
filename, ”rw¨);

// Ir al final del mismo
a.seek(a.length());

// Escribir registro
a.writeUTF(convertUTF(this.username, 8));
a.writeUTF(convertUTF(this.nombre, 40));
a.writeUTF(convertUTF(this.password, 11));
a.writeInt(this.lectura);
a.writeInt(this.escritura);

// Cerrar el archivo
a.close();
}
}
Pr oblema Pr opuest o
Est e es r ealment e un r et o. Suponga que t iene un RAF con t odos los RUT de los alumnos del
cur so con el f or mat o de un DOUBLE, es decir el númer o sin punt os y sin el dígit o ver if icador .
Por ej emplo:

13252311
4993023
...

El RAF se llama “RUTS.BI N” y se quier e buscar un RUT en par t icular .

(a) Modif ique un algor it mo de or denamient o par a que f uncione or denar en un RAF. Par a ello
r ecuer de que si se par a en una posición y hace un wr it e, ést e sobr escr ibe el valor que ha en
esa posición (en byt es), por ej emplo:

arch.seek(48);
arch.writeInt(57); // Sobrescribe en el byte 48 el entero 57.

(b) Ut ilice búsqueda binar ia (suponga que ya est á or denado el ar chivo) aplicada a un RAF par a
ver if icar la exist encia de un RUT dent r o de la list a, es decir , simule el siguient e diálogo:

Ingrese RUT: 12091128
No está ese RUT
Ingrese RUT: 13252311
Encontré el RUT en el byte x
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

221
Capít ulo XX: Bases de Dat os
Mot ivación con RAF’s
Desde algún t iempo at r ás hast a el día de hoy, el pr ocesamient o de inf or mación en pr oblemas
r eales ha sido una gr an pr eocupación de los pr ogr amador es.

I nicialment e, ut ilizaban est r uct ur as de dat os en memor ia par a almacenar la inf or mación: per o
la memor ia es poca y la inf or mación er a mucha. Luego se decidier on ut ilizar ar chivos par a
guar dar mayor es volúmenes de dat os: t ambién f ue insuf icient e, ya que el cr ecimient o de los
ar chivos de t ext o er a demasiado y las búsquedas se hacían cada vez más lent as.

Es así como la t endencia se ha ido hacia cr ear medios par a almacenar gr andes volúmenes de
dat os y opt imizar las consult as. A est os medios se les llamó Bases de Dat os.
Concept os
Base de Dat os
Conj unt o de t ablas o ar chivos r elacionados que per mit en el
almacenamient o est r uct ur ado y or denado de gr ande volúmenes de
inf or mación.

Como se ent iende en est a def inición, las Bases de Dat os son medios que per mit en almacenar
inf or mación. Est a inf or mación queda en est r uct ur as mas simples que son llamadas Tablas o
Ar chivos. Como ej emplo, veamos las t ablas par a una Base de Dat os de pr ést amos de libr os en
una bibliot eca:










Tablas (Ar chivos)
Secuencia de r egist r os (líneas) que almacenan inf or mación del mismo
t ipo or ganizados en f ilas o t uplas de dat os.

Las t ablas son las est r uct ur as básicas par a el almacenamient o de la inf or mación. Cada r egist r o
posee un gr upo de car act er íst icas (comunes dent r o de la misma t abla):
Libr os Lect or es
Pr ést amos
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

222

Libr os
Código Tít ulo Aut or Edit or ial Fecha


.
.
.


Lect or es
RUN Nombr e Dir ección Fono E-mail


.
.
.


Pr ést amos
Código Libr o RUN Lect or Fecha Devolucíon


.
.
.

Regist r os, Filas, Línea o Tuplas
Secuencia de campos o columnas que r epr esent an las car act er íst icas de
cada element o almacenable en la t abla.

Podemos ver que cada r egist r o almacena las car act er íst icas de un element o de la t abla. Todos
los element os de una misma t abla poseen los mismos t ipos de campos. Por ej emplo:

Un libr o posee Código, Tít ulo, Aut or , Edit or ial y Fecha.
Sint axis
Comenzar emos def iniendo una int er f ace par a los r egist r os la cual ut ilizar á una RAF par a
almacenar la t abla. Todos los r egist r os poseer án un set de f uncionalidades pr opias y son:

§ Lar go de un r egist r o.
§ Escr ibir r egist r o en la t abla.
§ Leer el r egist r o desde la t abla.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

223
Con est as 3 def iniciones, escr ibir emos la int er f ace Regist r o como sigue:

import java.io.*;

public interface Registro {
public long largo();
public void leer(RandomAccessFile raf) throws Exception ;
public void escribir(RandomAccessFile raf) throws Exception;
}

Nót ese que ut iliza un RandomAccessFile par a escr ibir y leer . Est o se debe r ealizar , por que
solo es el r egist r o quién conoce la def inición de los t ipos de dat os que guar da. La t abla solo
sabe que posee r egist r os.

Por ej emplo si quer emos hacer un r egist r o de alumnos con la t upla (RUT, Nombr e, y Cor r eo),
deber emos implement ar la int er f ace Regist r o según la siguient e def inición:

import java.io.*;

public class Alumno implements Registro {
// Definimos la estructura del registro
public long rut; // 8 bytes
public String nombre; // 100 bytes (+2)
public String correo; // 50 bytes (+2)

// La constante que nos indica de qué tamaño es el registro
private final int largo = 162;

public Alumno() { /* Constructor vacıo */ }

public long largo() {
return this.largo;
}

public void leer(RandomAccessFile raf) throws Exception {
this.rut = raf.readLong();
this.nombre = raf.readUTF();
this.correo = raf.readUTF();
}

public void escribir(RandomAccessFile raf) throws Exception {
raf.writeLong(this.rut);
raf.writeUTF(this.uniformar(this.nombre, 100));
raf.writeUTF(this.uniformar(this.correo, 50));
}

// Recordemos que los String se guardan uniformados
private String uniformar(String s, int l) {
String u = "";
for (int i=0; i<l; i++) {
if (i < s.length()) { u += s.charAt(i); }
else { u += " "; }
}
return u;
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

224
Con la def inición del r egist r o (en su f or ma genér ica) podr íamos def inir nuest r a t abla de dat os,
a la cual llamar emos TablaRAF como un ar chivo de r egist r os. Como la idea es almacenar los en
un RAF, deber emos manej ar las excepeciones de los ar chivos. Aquí se ut iliza el t r y . . . cat ch
par a manej ar las excepciones.

import java.io.*;

public class TablaRAF {
private RandomAccessFile raf;

public TablaRAF() {
}

public TablaRAF(String nombre) {
this.abrir(nombre);
}

public void abrir(String nombre) {
try {
raf = new RandomAccessFile(nombre, "rw");
raf.seek(0);
}
catch (Exception e) {
System.err.println("ERROR: al abrir!");
}
}

public void insertar(Registro r) {
try {
raf.seek(raf.length());
r.escribir(raf);
}
catch (Exception e) {
System.err.println("ERROR: al insertar!");
}
}

public void actualizar(int n, Registro r) {
try {
raf.seek((n-1) * r.largo());
r.escribir(raf);
}
catch (Exception e) {
System.err.println("ERROR: al actualizar ");
}
}

public void eliminar(int n) {
// Ooops... no sabemos eliminar aún
System.err.println("ERROR: al eliminar!");
}

public void ver(int n, Registro r) {
try {
raf.seek((n-1) * r.largo());
r.leer(raf);
}
catch (Exception e) {
System.err.println("ERROR: al ver!");
}
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

225

public boolean finDatos() {
boolean r = false;
try {
r = (raf.getFilePointer() >= raf.length());
}
catch (Exception e) {
System.err.println("ERROR: en la tabla!");
}
return r;
}

public void cerrar() {
try {
raf.close();
}
catch (Exception e) {
System.err.println("ERROR: al cerrar!");
}
}
}

(Oj o: que la mayor par t e de los mét odos son de una o dos líneas, per o ut ilizan t r y…cat ch par a
evit ar las excepciones
23
).

Por ej emplo, si t enemos un r egist r o de Cur so, nos gust ar ía obt ener su columna código:

...
TablaRAF t = new TablaRAF(”cursos¨);
int i=0;
while (!t.finDatos()) {
// Creamos un curso vacıo
Curso c = new Curso();

// Le metemos los datos desde la tabla
t.ver(i, c);

// Mostramos en pantalla el código
System.out.println(c.codigo);
}
t.close()
...

Veamos ahor a las oper aciones que se pueden hacer con est a r epr esent ación.

Exist en 3 t ipos de oper aciones que se pueden r ealizar ent r e las t ablas de una base de dat os:
Selección, Pr oyección y Par eo/ Cr uce.
Selección
Recuper a las f ilas de una t abla según algún cr it er io de búsqueda que
ut ilice los campos de la t abla.


23
Exist e un capít ulo no obligat or io con est e mat er ial de excepciones. Revísalo.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

226
Par a r ealizar una selección, es necesar io pr imer o saber baj o qué cr it er io. Por ej emplo, de la
t abla Libr os vist a ant er ior ment e, nos gust ar ía encont r ar aquellos libr os que sean de J ava (que
cont engan en su nombr e en alguna par t e esa palabr a)
24
:

TablaRAF libros = new TablaRAF();
libros.abrir(”libros¨);
Libro[] resultados = new Libro[MAXDATA];
int n = 0;
for (int i=0; !libros.finDatos(); i++) {
Libro r = new Libro();
libros.ver(i, r);
if (libros.titulo.indexOf(”Javaó) >= 0) {
libro[n] = r;
n++;
}
}
libros.cerrar();

Con est e código, en el ar r eglo r esult ados t enemos t odos los r egist r os que cont ienen la palabr a
“J ava” en el campo de Tít ulo.

Como se puede obser var en el ej emplo, las t ablas t ambién se pueden r epr esent ar como
ar r eglos de r egist r os en la memor ia del comput ador . Est o hace que cada uno de los r esult ados
obt eni dos en una selección t ambién sea una t abla. Ent onces si cont inuamos el pr ogr ama
ant er ior :

// ... continuación
TablaRAF librosJava = new TablaRAF();
librosJava.abrir(”LibrosJAVA¨);
for (int i=0; i<n; i++) {
librosJava.insertar(libro[i]);
}
librosJava.cerrar();

Hemos cr eado una t abla Libr osJ ava con t odos aquellos libr os que en su t ít ulo poseen la palabr a
J ava.

Per o la selección no es condicionada solo por un campo. También se puede r ealizar selección
según 2 o más cr it er ios. Por ej emplo, si los libr os son de I saac Asimov y además la edit or ial se
Univer sit ar ia:

TablaRAF libros = new TablaRAF();
libros.abrir(”Libros¨);
Libro[] resultados = new Libro[MAXDATA];
int n = 0;
for (int i=0; !libros.finDatos(); i++) {
Libro reg = new Libro();
libros.leerRegistro(i, reg);
if (reg.autor.equals(”Isaac Asimovó) &&
reg.editorial.equals(”Universitariaó)) {
resultados[n] = reg[i];
n++;

24
Suponemos que MAXDATA es un númer o suf icient ement e gr ande.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

227
}
}
libros.cerrar();

Como ven, solo nos bast a cambiar las condiciones de compar ación y est á list o.
Pr oyección
Recuper a solo algunas columnas de una t abla, es decir , solo selecciona
algunos dat os a desplegar .

La dif er encia que hay ent r e una Selección y una Pr oyección es que en el segundo caso se
seleccionan columnas específ icas de la t abla, cosa que no es así en la pr imer a.

Quer emos seleccionar solo los RUN’s de los lect or es que vivan en la comuna de Sant iago:

TablaRAF t = new TablaRAF();
t.abrir(”Lectores¨);
Lector[] resultados = new Lector[MAXDATA];
int n = 0;
for (int i=0; !t.finDatos(); i++) {
Lector reg = new Lector();
t.leerRegistro(i, reg);
if (reg.direccion.indexOf(”Santiago¨) >= 0) {
resultados[n].run = reg.run;
n++;
}
}
t.cerrar();

En est e caso, solo est amos guar dando los RUN. Veamos si quer emos t ambién los nombr es:

TablaRAF t = new TablaRAF();
t.abrir(”Lectores¨);
Lector[] resultados = new Lector[MAXDATA];
int n = 0;
for (int i=0; !t.finDatos(); i++) {
Lector reg = new Lector();
t.leerRegistro(i, reg);
if (reg.direccion.indexOf(”Santiago¨) >= 0) {
resultados[n].run = reg.run;
resultados[n].nombre = reg.nombre;
n++;
}
}
t.cerrar();

Y si quisier mos los nombr es y los cor r eos elect r ónicos:

TablaRAF t = new TablaRAF();
t.abrir(”Lectores¨);
Lector[] resultados = new Lector[MAXDATA];
int n = 0;
for (int i=0; !t.finDatos(); i++) {
Lector reg = new Lector();
t.leerRegistro(i, reg);
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

228
if (reg.direccion.indexOf(”Santiago¨) >= 0) {
resultados[n].nombre = reg.nombre;
resultados[n].correo = reg.correo;
n++;
}
}
t.cerrar();

Como pueden ver , la dif er encia ent r e la selección y pr oyección es mínima, y se puede llegar a
que una selección es un una pr oyección de t odos los campos de la t abla.
Par eo/ Cr uce (J oin)
El J oin se ut iliza par a r ecuper ar inf or mación de var ias t ablas, a t r avés
de una f unción ent r e ellas.

El j oin es similar a r ealizar un mer ge: se van mezclando los dat os de una t abla con los de la ot r a
por un cr it er io def inido. En el caso del mer gesor t se r ealizaba según un or den (or denamient o).
Sin embar go, en el caso de las bases de dat os, est e par eo ut iliza un cr it er io de compar ación
ent r e las columnas de una t abla y ot r a.

Por ej emplo: ¿Cómo saber los nombr es de los lect or es que poseen libr os pr est ados? Par a ello
se ut ilizan las t ablas Lect or es y Pr ést amos, una clase llamada Deudor par a almacenar los
r esult ados, que solo posee un St r ing y suponiendo que ambas t ablas est án or denadas por RUN
del lect or :

TablaRAF t1 = new TablaRAF();
t1.abrir(”Lectores¨);
TablaRAF t2 = new TablaRAF();
t2.abrir(”Prestamos¨);
Deudor[] resultados = new Deudor[MAXDATA]
int n = 0;
for (int i=0; !t2.finDatos(); i++) {
Prestamo regPrestamo = new Prestamo();
t2.leerRegistro(i, regPrestamo);
for (int j=0; !t1.finDatos(); j++) {
Lector regLector = new Lector();
regLector = t2.leerRegistro(j);
if (regLector.RUN.equals(regPrestamo.RUN)) {
resultados[n].nombre = regLector.nombre;
n++;
break;
}
}
}
t.cerrar();

En r esult ados se encuent r an t odos los nombr es que poseen libr os pr est ados, per o r epet idos en
caso de que t enga más de un libr os pr est ado.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

229
Pr oblemas
Una concesionar ia de aut omóviles quier e hacer un sist ema par a almacenar su inf or mación de
vent a y así pagar las comisiones a sus empleados. Par a ello diseñar on 2 t ablas r elacionadas que
modelan el sist ema de almacenamient o de dat os:

Vendedor
§ RUT
§ Nombr e
§ Sueldo (Base)

Aut omovil
§ Código
§ Mar ca
§ Modelo
§ Pr ecio
§ Comisión (f r acción de comisión)
§ Fecha (de Vent a)
§ RUN (vendedor )

(a) I mplement e un pr ogr ama que per mit a obt ener el sueldo del vendedor J uan Pér ez par a el
mes de sept iembr e (consider e que la f echa de vent a viene en f or mat o dd/ mm/ yyyy como
St r ing).

// Abrimos las tablas para el cruce
TablaRAF vend = new TablaRAF(”Vendedor¨);
TablaRAF auto = new TablaRAF(”Automovil¨);

// Declaramos el resultado. Como es solo 1...
Vendedor vendedor = new Vendedor();

// Ciclo de lectura de vendedores
for (int i=0; !vend.finDatos(); i++) {
// Buscamos al vendedor
vend.ver(i, vendedor);
if (vendedor.nombre.equals(”Juan Pérez¨)) {
// Ciclo de lectura de automoviles
for (int j=0; !auto.finDatos(); j++) {
// Calculamos el sueldo
Automovil vendido = new Automovil();
auto.ver(j, vendido);
if (vendido.RUN == vendedor.RUN &&
vendido.fecha.indexOf(”09¨) == 3) {
// Aumentamos la comisión al sueldo
vendedor.sueldo += vendido.precio *
vendido.comision;
}
}
}
}
auto.cerrar();
vend.cerrar();

Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

230
(b) Modif ique su pr ogr ama ant er ior par a que almacene en una t abla llamada Sueldo el RUT, el
nombr e y el sueldo (incluyendo comisión) par a el mes de sept iembr e.

// Abrimos las tablas para el cruce
TablaRAF vend = new TablaRAF(”Vendedor¨);
TablaRAF auto = new TablaRAF(”Automovil¨);
TablaRAF sueldo = new TablaRAF(”Sueldo¨);

// Declaramos el resultado. Ahora no es 1
Vendedor[] vendedor = new Vendedor[MAXDATA];

// Ciclo de lectura de vendedores
for (int i=0; !vend.finDatos(); i++) {
vendedor[i] = new Vendedor();
vend.ver(i, vendedor);

// Ciclo de lectura de automoviles
for (int j=0; !auto.finDatos(); j++) {
// Calculamos el sueldo del vendedor i
Automovil vendido = new Automovil();
auto.ver(j, vendido);
if (vendido.RUN == vendedor[i].RUN &&
vendido.fecha.indexOf(”09¨) == 3) {
// Aumentamos la comisión al sueldo
vendedor[i].sueldo += vendido.precio *
vendido.comision;
}
}

// Lo dejamos en la tabla Sueldo
sueldo.insertar(vendedor[i]);
}
sueldo.cerrar();
auto.cerrar();
vend.cerrar();

Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

231
Mot ivación con SQL
Par a r ealizar una comunicación ent r e J ava y Bases de Dat os de ver dad (SQL* Ser ver , mySQL,
Or acle, Sybase, DB2, et c), se necesit a ent ender pr eviament e lo que es llamado St andar d
Quer y Language (SQL).













Concept os
Base de Dat os Relacional
Una Base de Dat os r elacional es un espacio de almacenamient o de
gr andes volúmenes de dat os, or ganizados en t ablas, y que per mit e
especif icar r elaciones ent r e aquellas t ablas.
Mot or de Base de Dat os Relacional
25

El Mot or de una Base de Dat os Relacional (RDBMS o Sist ema
Administ r ador de Bases de Dat os Relacionales) es un sof t war e que
per mit e administ r ar un conj unt o de Bases de Dat os Relacionales.

Exist en un sin númer o de Bases de Dat os r elaciones. Por ej emplo, Or acle es una empr esa que
desar r olló un gr an sof t war e de bases de dat os r elacionales. En la act ualidad, Or acle, t iene en
el mer cado la ver sión 8 de su mot or de dat os (del mismo nombr e) y est á a punt o de sacar al
mundo la ver sión 9 mej or ada.
SQL
Lenguaj e est andar izado que ut ilizan los RDBMS par a int er pr et ar los
r equer imient os que los usuar ios hacen a sus modelos de dat os.


25
Si t e at r eves, un mot or liviano e inst alable en Wi ndows (y en Linux t ambién) de un RDBMS
puedes encont r ar lo en ht t p:/ / www.mysql.com/ downloads/ mysql -3.23.ht ml (MySQL).
P
r
o
g
r
a
m
a

e
n

J
A
V
A


J DBC
Base de
Dat os
Clases y
Obj et os
en J AVA
SQL
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

232
St andar d Quer y Language es un lenguaj e que per mit e a los pr ogr amador es r ealizar consult as
a las Bases de Dat os que desean ocupar . Su sint axis se basa en un set de pocos comandos o
inst r ucciones y en combinaciones de ellas.

Las consult as son enviadas al RDBMS a t r avés de un t ext o, el cual es int er pr et ado por él y
ej ecut ado sobr e el modelo en el cual se est á conect ado. Una vez que esa consult a es pr ocesada,
el RDBMS r et or na los dat os como si f uesen una nueva t abla.

Los dist int os RDBMS t ienen int er f aces de consult a que per mit en a los usuar ios escr ibir
dir ect ament e sus consult as en SQL y ver los r esult ados en pant alla. Por ej emplo, Or acle posee
una aplicación llamada SQL Plus (en t odas sus ver sionas ha mant enido est e pr ogr ama) y que
posee un diálogo t ipo:

> SELECT * FROM usuarios
NOMBRE CLAVE
--------------------- -----------------------
averuzzi kifd99.
djacintos a99sjjs
tchan karina1000

3 rows selected
> _

Est e sencillo ej emplo, lo que hace es una selección desde la t abla usuar ios, la cual solo posee 3
dat os.
J DBC
J DBC (J AVA Dat abase Connect ion) es un set de her r amient as que
per mit en conect ar se a un RDBMS y conver sar con él par a que las
consult as salgan de inst r ucciones J AVA y los r esult ados pr ocesar los en
una clase J AVA.

Par a r ealizar una conexión con J AVA y un RDBMS se ut iliza un dr iver el cual per mit e hacer una
conexión con ese t ipo de RDBMS. Por ej emplo, si quer emos conect ar nos con SQL* Ser ver ,
ut ilizar emos una clase que se baj a de la página de Micr osof t y se llama com.ms.J DBCDr iver .

Sin embar go, ant es de comenzar a conect ar nos ent r e una Base de Dat os y J AVA es
convenient e saber cómo f unciona SQL y su sint axis.
Sint axis
26

SQL posee un conj unt o de inst r ucciones cat egor izado en los siguient es t ipos:

• Consult a de Dat os
• Act ualización de Dat os
• Administ r ación de Base de Dat os

26
Si desean mayor inf or mación, visit en ht t p:/ / www.desar r olloweb.com/ manuales/ 9/
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

233
Consult a de Dat os
Par a r ealizar una consult a en SQL se necesit a saber la sint axis básica de un comando de est e
t ipo. Par a ello exist e solo una inst r ucción que es llamada SELECT:

SELECT columna1, columna2, . . . , columnaN
FROM t abla1, t abla2, . . . , t ablaM
WHERE condicion1
AND/ OR condicion2
AND/ OR ...
AND/ OR condicionO
ORDER BY cr it er io1, cr it er io2, ..., cr it er ioP

En donde (Las líneas en negr it as son obligat or ias):

columna1, . . . columnaN: Son las columnas a desplegar como r esult ado
t abla1, . . . , t ablaM: Son los nombr es de las t ablas que se desea consult ar
(selección/ pr oyección).
condicion1, . . . , condicionO: Son condiciones que se deben cumplir (j oin).
cr it er io1, . . . , cr it er ioP: Son las columnas por los cuales ser á or denado el
r esult ado.

Por ej emplo, r ecor dando la est r uct ur a de la Base de Dat os de unas clases at r ás, t enemos:











En est e modelo podemos ver que la t abla Libr os posee un ident if icador único
27
que es Código y
que es r elacionado con ot r o ident if icador único de la t abla Lect or es que es RUN, ambos en la
t abla Pr ést amos.

Veamos un set de consult as y su t r aducción en SQL:

SELECT *
FROM lectores

Obt iene el det alle de t odos los
lect or es que exist en.


SELECT *


27
En Base de Dat os, ese ident if icador es llamado Llave Pr imar ia.
Libr os
Código
Tít ulo
Aut or
Edit or ial
Fecha
Lect or es
RUN
Nombr e
Dir ección
Teléf ono
Email
Pr ést amos
Código
RUN
Fecha
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

234
FROM libros
WHERE editorial = ’Universitaria'
Obt iene t odos los libr os que sean de la
edit or ial Univer sit ar ia.


SELECT run, nombre
FROM lectores

Obt iene t odos los nombr es y r uns de
t odos los lect or es del sist ema.


SELECT lectores.nombre,
libros.titulo
FROM lectores, prestamos, libros
WHERE libros.codigo = prestamos.codigo
AND prestamos.run = lectores.run


Obt iene los nombr es de los lect or es y
los t ít ulos de los libr os que t ienen en
su poder .


SELECT *
FROM libros, prestamos
WHERE libros.codigo = prestamos.codigo
AND libros.nombre = ’JAVA'
ORDER BY prestamos.fecha


Obt iene t odos los det alles de los libr os
de J AVA que se encuent r en pr est ados
or denados por f echa de devolución.

El pr imer ej emplo, en mySQL, da por r esult ado:

mysql> select * from lectores;
+----------+----------------+-----------+----------+-------------------------+
| run | nombre | direccion | telefono | email |
+----------+----------------+-----------+----------+-------------------------+
| 13252311 | Andres Munoz O | | | andmunoz@entelchile.net |
+----------+----------------+-----------+----------+-------------------------+
1 row in set (0.00 sec)

mysql>

(Consider ando que solo exist e un lect or en la Base de Dat os).

Como se puede apr eciar , el f or mat o de salida es igual a una t abla con las columnas
especif icadas. En el caso de poner un * (ast er isco) como nombr e de columna, ést e nos indica
que se seleccionan t odas las columnas de la t abla.

Ot r o ej emplo en mySQL es con pr oyección:

mysql> select run, nombre
-> from lectores;
+----------+----------------+
| run | nombre |
+----------+----------------+
| 13252311 | Andres Munoz O |
+----------+----------------+
1 row in set (0.00 sec)

mysql>

Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

235
Nos podemos dar cuent a que, al especif icar las columnas, nos ent r ega exact ament e esos dat os
no más.

Un últ imo ej emplo es con un J OI N:

mysql> select libros.titulo, lectores.nombre
-> from libros, prestamos, lectores
-> where libros.codigo = prestamos.codigo
-> and prestamos.run = lectores.run
-> order by libros.codigo;
+---------------------+----------------+
| titulo | nombre |
+---------------------+----------------+
| Introducción a Java | Andres Munoz O |
+---------------------+----------------+
1 row in set (0.06 sec)

mysql>

Acá podemos ver las columnas de dist int as t ablas complet ament e mezcladas sin saber de qué
se t r at a cada una.
Act ualización de Dat os
SQL per mit e además r eal izar act ualización on-line de dat os a t r avés de 3 sent encias básicas
par a la administ r ación: I nser ción, Act ualización y Eliminación.

I NSERT: Est a cláusula per mi t e inser t ar valor es a una t abla específ i ca. Su sint axis es:

I NSERT I NTO t abla
(columna1, columna2, ..., columnaN)
VALUES (valor 1, valor 2, . . . , valor N)

Como se ve en la sint axis, solo es posible inser t ar valor es SOLO a 1 t abla. Además, uno puede
especif icar el or den y qué columnas llenar . En caso de no especif icar una columna de la t abla,
est a se inser t a con NULL (solo si no est á def inida como NOT NULL). Por últ imo, si no se
especif ican las columnas (ninguna), se supone que se inser t ar án TODAS las columnas.

Ej emplos:

INSERT INTO lectores
VALUES (’12688049-9',
’Juan Perez González',
’Alameda 1020',
’223 9023',
’jperez@hotmail.com')
I nser t a un lect or a la t abla de lect or es
(t odas las columnas).


INSERT INTO libros
(codigo, nombre, autor)
VALUES (’333443-23',
’La Fundación',
’Isaac Asimov')
Solo inser t a las columnas código, nombr e y
aut or a la t abla libr os (en ese or den).
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

236

UPDATE: Est a cláusula per mit e act ualizar valor es a una t abla específ ica y dependiendo de
condiciones. Su sint axis es:

UPDATE t abla
SET columna1 = valor 1,
columna2 = valor 2, . . .
columnaN = valor N
WHERE condición1 AND/ OR condición2 ... AND/ OR condiciónM

La sent encia UPDATE especif ica el nombr e de la t abla, las columnas con los valor es a
act ualizar y las condiciones par a seleccionar solo aquellos r egist r os que se desean act ualizar .
Más clar o lo podemos ver en los siguient es ej emplos:

UPDATE lectores
SET nombre = ’Alberto Fujimori',
run = ’9324423-8'
WHERE email = ’chino@yahoo.es'
Cambia solo un r egist r o (o t odos aquellos que
coincidan con el e-mail).


UPDATE libros
SET editorial = ’Universitaria'

Cambia t odos los r egist r os de la t abla libr os
y les pone la edit or ial = UNI VERSI TARI A


UPDATE libros
SET editorial = ’Universitaria'
WHERE codigo = ’3849232'

Cambia t odos los r egist r os de la t abla libr os
y les pone la edit or ial = UNI VERSI TARI A
solo si el codi go es 3849232.

DELETE: Est a cláusula per mit e bor r ar r egist r os de una t abl a específ ica y dependiendo de
condiciones. Su sint axis es:

DELETE FROM t abla
WHERE condición1 AND/ OR condición2 ... AND/ OR condiciónM

La sent encia más sencilla es est a, ya que solo se debe especif icar la t abla y las condiciones
par a eliminar las columnas (que calcen con la cláusula WHERE). Ej emplos:

DELETE FROM lectores
Elimina t odos los lect or es de la Base de
Dat os.


DELETE FROM libros
WHERE editorial = ’Alcántara'

Elimina t odos los libr os de la edit or ial
Alcánt ar a.

El cuidado al eliminar se debe t ener en las r elaciones de la Base de Dat os. Por ej emplo, al
eliminar con la sent encia DELETE FROM LECTORES, se eliminar án t odos los lect or es SOLO SI
no exist en r egist r os de lect or es (r un’s) en la t abla PRESTAMOS.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

237
Administ r ación de Tablas
Par a administ r ar las t ablas de una Base de Dat os exist en 2 comandos sencillos (per o no son los
únicos) que sir ven par a est a labor :

CREATE TABLE: Est a sent encia per mit e cr ear t ablas en una base de dat os. Su sint axis es:

CREATE TABLE nombr e
(columna1 t ipo1 NOT NULL,
columna2 t ipo2 NOT NULL,
...
columnaN t ipoN NOT NULL)

Est a ver sión bast ant e simplif icada de la sint axis indica que se cr ea una t abla con su nombr e y
se indican las columnas con su t ipo y se indican si son o no son NOT NULL.

Veamos algunos ej emplos:

CREATE TABLE revistas
(codigo varchar NOT NULL,
nombre varchar NOT NULL,
numero number,
valor number)
Cr ea la t abla r evist as en la Base de
Dat os.

Algunos de los t ipos más ut ilizados son:

• VARCHARy VARCHAR2: En vez de St r ing.
• NUMBER: Par a guar dar valor es numér icos

Not a: En gener al ut ilizar emos VARCHAR par a no complicar nos la vida :-).

DROP TABLE: La sent encia per mit e eliminar una t abla que est é vacía (sin r egist r os).

DROP TABLE t abla

Es bast ant e sencilla la sint axis y no t iene más ciencia que esa.

Como se ha vist o hast a ahor a, solo sabemos ut ilizar ambos lados de la moneda. Sin embar go nos
f alt a la capa int er media y es como y donde se unen los pr ogr amas J ava con la sint axis SQL de
los RDBMS.

Ahor a ver emos paso a paso como ut ilizamos J DBC par a r ealizar una consult a SQL y conect ar
un pr ogr ama J ava con una Base de Dat os r eal (con RAF, o un RDBMS).
Realizar la Conexión
El pr imer paso que se debe r ealizar es abr ir una conexión con el DBMS que se d esea ut i lizar .
Par a ello usar emos 2 punt os impor t ant es:
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

238

Car gar el Dr iver : Ant es de cualquier cosa, J ava debe saber cont r a qué se est á enf r ent ando
par a abr ir una conexión con una base de dat os. Par a ello ut iliza unas clases especiales que son
llamadas Dr iver s y que se baj an desde int er net r ápidament e.

Exist en Dr iver s par a un sin númer o de DBMS
28
como son MS Access, SQL Ser ver , Or acle,
DB2, et c. Par a car gar el dr iver se ut iliza un mét odo est át ico de la clase Class llamado
f or Name.


Class.forName("<nombre del driver>");


En gener al, se ut iliza est a línea indicando el nombr e del dr iver , que por lo gener al son de la
f or ma j dbc. Dr iver X. Est a especif icación siempr e viene en la document ación del dr iver . Por
ej emplo, par a conect ar a t r avés del dr iver más básico (ODBC) se ut iliza:


Class.forName(”sun.jdbc.odbc.JdbcOdbcDriver¨);


y list o.

Abr ir la Conexión: Par a abr ir la conexión, luego de haber car gado el dr iver , se debe cr ear un
obj et o de la clase Connect ion (del package j ava.sql.* ) de la siguient e f or ma:


Connection c =
DriverManager.getConnection (”<bd>¨, ”<login>¨, ”<password>¨);


quedando así en la var iable c una conexión a la base de dat os de nombr e (ur l) bd y que el
usuar io ut ilizado est á ident if icado por login y passwor d como clave.

Con est os dos casos, por ej emplo, par a conect ar a una base de dat os Access llamada alumnos y
que est á r egist r ada como ODBC en el comput ador t enemos que r ealizar los dos pasos
siguient es:


Class.forName(”sun.jdbc.odbc.JdbcOdbcDriver¨);

Connection c =
DriverManager.getConnection (”jdbc:odbc:alumnos¨, ”¨, ”¨);

...

c.close();



28
Ver la J ava Developer Connect ion del sit io ht t p:/ / j ava.sun.com
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

239
Casualment e, las Bases de Dat os Access no ut ilizan ni nombr e de usuar io ni clave par a la
conexión, así que esos par ámet r os se dej an vacíos.
Cr eando Sent encias J DBC
Con la conexión hecha (consider e c como la var iable de conexión), es necesar io cr ear una
sent encia par a r ealizar una acción sobr e la base de dat os. Las sent encias son t r anspor t adas al
DBMS a t r avés de un obj et o de t ipo St at ement :


Statement stmt = c.createStatement();


Con est a sent encia (que es la única f or ma posible), se cr ea un obj et o st mt que se conect ar á con
la conexión c par a enviar un comando SQL al DBMS.

Exist en 2 t ipos de comandos en SQL que enviar :

Consult a: Un comando de consult a es aquél que r et or na r esult ados (SELECT). Par a ello se
ut iliza un mét odo de la clase St at ement llamado execut eQuer y:


ResultSet rs = stmt.executeQuery(”<SQL de SELECT>¨);


Los r esult ados son guar dados dent r o de un obj et o Result Set par a luego obt ener los a t r avés de
un it er ador :

while (rs.next()) {
// Se obtienen los valores por cada registro
...
}

Con est e ciclo, que lee en cada it er ación 1 r egist r o del Result Set , se pueden ir obt eniendo los
valor es par a cada columna de los r egist r os. Par a obt ener los valor es se usan:

r s.get St r ing("<colname o numcol>"); Obt iene una columna VARCHAR o CHAR
r s.get Float ("<colname o numcol>"); Obt iene una columna FLOAT o NUMERI C
r s.get I nt (“<colname o numcol>”); Obt iene una columna I NTEGER o NUMERI C
r s.get Obj ect (“<colname o numcol>”); Obt iene cualquier t ipo de dat o.

Por ej emplo:

Statement stmt = c.createStatement();
Resultset rs = stmt.executeQuery(”SELECT * FROM LECTORES¨ +
”WHERE RUN = ’13252311-8'¨);
while(rs.next()) {
System.out.print (” Nombre = ” + rs.getString(”NOMBRE¨));
System.out.print (” Email = ” + rs.getString(”EMAIL¨));
System.out.print (”Teléfono = ” + rs.getString(”FONO¨));
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

240

Ot r a cosa que es int er esant e es que se puede obt ener el nombr e de las columnas y t ambién la
cant idad de columnas de un Result Set . Est o se puede usar ut ilizando ot r a clase llamada
Result Met aDat a:

ResultSetMetaData rsmd = rs.getMetaData();
int n = rsmd.getColumnCount();
for (int i=1; i<=n; i++) {
System.out.println(rsmd.getColumnLabel(i));
}

Est e pequeño código impr ime en cada línea los nombr es de las columnas de la t abla de
r esult ados. Est o es muy út il al moment o de desplegar la inf or mación en pant alla. Por ej emplo:

Statement stmt = c.createStatement();
Resultset rs = stmt.executeQuery(”SELECT * FROM LECTORES¨ +
”WHERE RUN = ’13252311-8'¨);
ResultMetaData rsmd = rs.getMetaData();
int n = rsmd.getColumnCount();
while(rs.next()) {
for (int i=1; i<=n; i++) {
System.out.print(rsmd.getColumnLabel(i) + ” = ”);
System.out.println(rs.getObject(i));
}
System.out.println();
}

I mpr imiendo t odos los dat os de r esult ados sin saber los nombr es de los campos de cada
r egist r o. Nót ese que los índices par t en desde 1 y no de 0 como es or iginalment e en t odo en
J ava.

Act ualización: Las sent encias de act ualización son t odos esos comandos que per mit en r ealizar
algún cambio en la est r uct ur a o en los dat os de la Base de Dat os (CREATE, DROP, I NSERT,
UPDATE o DELETE). Par a ello se ut iliza un mét odo execut eUpdat e (que no r et or na nada [ void] )
con el comando como par ámet r o:


stmt.executeUpdate(”<SQL de Create/Drop o Insert/Update/Delete>¨);


Por ej emplo:

stmt.executeUpdate(”DELETE * FROM LIBROS¨);
Ut ilizando Tr ansacciones
Las t r ansacciones son t r ozos de ej ecución de comandos SQL que no son r ef lej ados
dir ect ament e en la Base de Dat os. Es como si se ar mar a un conj unt o de comandos en un
paquet e y luego se enviar a t odo es set complet o par a ser ej ecut ado por el DBMS.

Ant es de hacer una t r ansacción, es impor t ant e saber cómo f unciona en SQL. Las t r ansacciones
son limit adas por un COMMI T o un ROLLBACK. Todo el SQL que se va ej ecut ando, no se hace
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

241
ef ect ivo sin un COMMI T al f inal. Si ocur r e un er r or o simplement e par a volver at r ás uno ut iliza
el comando ROLLBACK.

En J ava, la idea es la misma. Par a r ealizar una t r ansacción, pr imer o se desact iva el aut o commit
(f in de t r ansacción aut omát ico) que t iene por def ect o la conexión. Luego van las inst r ucciones
que en gener al son de act ualización y se r ealiza un commit explícit o (igual que en SQL). Al f inal
se act iva nuevament e el aut o commit :

c.setAutoCommit(false);
// Instrucciones dentro de la Transacción
c.commit();
c.setAutoCommit(true);
Manej ando Excepciones y War nings
El pr oblema que hay con las Bases de Dat os es muy similar al ocur r ido con los ar chivos: hay
excepciones que se deben manej ar par a que f uncionen bien.

La excepción más impor t ant e es SQLExcept ion que es la que guar da y obt iene t odos los
er r or es que vienen del DBMS y los pone como una excepción en J ava. En gener al est os er r or es
vienen con la codif icación usada por el mismo DBMS par a ident if icar los. Por ej emplo con el
dr iver ent r e cor chet es y/ o como ORA-xxxx par a indicar el código del er r or de Or acle.

Es r ecomendable inser t ar el código de conexión y/ o ej ecución dent r o de ár eas cr ít icas par a
at r apar la excepción (t r y. . . cat ch) o simplement e pasar la a un mét odo mayor (t hr ows).

También, y solo en el caso de poner Class. f or Name(. . . ), puede ocur r ir la excepción
ClassNot FoundExcept ion. Est a excepción ocur r e cuando no se encuent r a el dr iver que se pone
ent r e par ént esis.

Por últ imo, las conexiones con Bases de Dat os pueden enviar algunas adver t encias o war nings
en caso de exist ir . Par a ello se ut iliza el mét odo get War nings() de la clase St at ement y de la
clase Result Set .

Par a obt ener los war nings (en ambos casos) se ut iliza, por ej emplo:

SQLWarning warn = stmt.getWarnings();
while (warn != null) {
System.err.println(” Mensaje = ” + warn.getMessage());
System.err.println(” SQLState = ” + warn.getSQLState());
System.err.println(” Código = ” + warn.getVendorCode());
warn = warn.getNextWarning();
}
Ej emplo Pr áct ico
El siguient e ej emplo per mit e abr ir una conexión con una Base de Dat os Access, enviar un
I NSERT y consult ar dat os most r ándolos en la salida est ándar . La base de dat os se llama cc10a
y est á r egist r ada apunt ando al ar chivo cc10a. mdb a t r avés de ODBC.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

242
Ver sión 1: En est a ver sión l as excepciones son lanzadas f uer as del mét odo main par a que la
J VM t ome el cont r ol de ellas

// Debemos importar algunos package
import java.sql.*;
import java.lang.*;

public class SQLConsulta {
public void main (String[] args)
throws SQLException, ClassNotFoundException {
Console w = new Console();

// Cargar Driver
Class.forName(”sun.jdbc.odbc.JdbcOdbcDriver¨);

// Abrir conexión
Connection c =
DriverManager.getConnection(”jdbc:odbc:cc10a¨,
”scott¨, ”tiger¨);

// Crear el paquete
Statement stmt = c.createStatement();

String sql = w.readLine();
if (sql.toUpperCase().indexOf(”SELECT¨) == 0) {
// Consulta SQL
ResultSet rs = stmt.executeQuery(sql);

// Trabajar con los resultados
while(rs.next()) {
w.println(”Valor = ” + rs.getObject());
}
}
else {
// Ejecuta SQL
stmt.executeUpdate(sql);
}

// Cierra conexión
c.close();
}
}

Ver sión 2: En est a ver sión capt ur a las excepciones dent r o del mét odo main cont r olando sus
r esult ados

// Debemos importar algunos package
import java.sql.*;
import java.lang.*;

public class SQLConsulta {
public void main (String[] args) {
Console w = new Console();

try {
// Cargar Driver
Class.forName(”sun.jdbc.odbc.JdbcOdbcDriver¨);
}
catch (ClassNotFoundException e) {
w.println(e.getMessage());
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

243
System.exit(0);
}

try {
// Abrir conexión
Connection c =
DriverManager.getConnection(
”jdbc:odbc:cc10a¨,
”scott¨, ”tiger¨);

// Crear el paquete
Statement stmt = c.createStatement();

String sql = w.readLine();
if (sql.toUpperCase().indexOf(”SELECT¨) == 0) {
// Consulta SQL
ResultSet rs = stmt.executeQuery(sql);

// Trabajar con los resultados
while(rs.next()) {
w.println(”Valor = ” +
rs.getObject());
}
}
else {
// Ejecuta SQL
stmt.executeUpdate(sql);
}

// Cierra conexión
c.close();
}
catch (SQLException e) {
w.println(e.getMessage());
System.exit(0);
}
}
}
Pr oblemas
Supongamos el siguient e modelo de dat os:











En él podemos ident if icar que un club est á compuest o por muchos j ugador es y un j ugador solo
per t enece a un club (1), y que los clubes pueden est ar par t icipando en más de una f echa, y que
en una f echa par t icipan 2 equipos (2).

J ugador
Código_Equipo
RUN
Nombr e
Tipo
Club
Código
Nombr e
DT
Fecha
Código_Local
Código_Visit a
Fecha
Result ado
Est adio
(2)
(1)
Java: del Grano a su Mesa (Version 1.3)
Capitulo XX: Bases de Datos

244
Escr iba en SQL las siguient es consult as:

(a) List a de j ugador es (t odos sus det alles) que per t enecen al club de la “ Univer sidad de
Chile”.

SELECT jugador.run, jugador.nombre, jugador.tipo
FROM jugador, club
WHERE jugador.codigo_equipo = club.codigo
AND club.nombre = ’Universidad de Chile'

(b) List a de los par t idos y su r esult ado que se j ugar on el “ 10/ 08/ 2001”.

SELECT local.nombre, visita.nombre, fecha.resultado, fecha.estadio
FROM club local, club visita, fecha
WHERE local.codigo = fecha.codigo_local
AND visita.codigo = fecha.codigo_visita
AND fecha.fecha = ’10/08/2001'

En est e caso est amos incluyendo un nuevo concept o de sinónimos par a t ablas, en las
cuales ocur r e que, en la sent encia FROM indicamos un nombr e alt er nat ivo par a una t abla
(en el caso de t ablas r epet idas es muy út il). Es decir :

SELECT ...
FROM tabla sinon, ...

Y t odas las columnas son llamadas como sinon. nombr e_columna.

(c) Nombr e de los j ugador es que par t icipar on en el encuent r o en que la “ Univer sidad
Cat ólica” j ugó de local el “23/ 06/ 2001”.

SELECT jugador.nombre
FROM jugador, club, fecha
WHERE jugador.codigo_equipo = club.codigo
AND club.nombre = ’Universidad CAtólica'
AND club.codigo = fecha.codigo_local
AND fecha.fecha = ’23/06/2001'

(d) List ar t odos los par t idos en donde haya j ugado “Colo-Colo” y sus r esult ados.

SELECT local.nombre, visita.nombre,
fecha.fecha, fecha.resultado, fecha.estadio
FROM club local, club visita, fecha
WHERE local.codigo = fecha.codigo_local
AND visita.codigo = fecha.codigo_visita
AND ( local.nombre = ’Colo-Colo'
OR visita.nombre = ’Colo-Colo' )

Lo nuevo de est e caso es que ingr esamos una sent encia OR dent r o del WHERE de la
consult a.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

245
Capít ulo XXI : Concur r encia
Mot ivaci ón
Hast a ahor a hemos vist o que los pr ogr amas cor r en y ej ecut an en f or ma li neal algo. Por ej emplo,
si est ás ej ecut ando un pr oblema mat emát ico de int egr ación, la solución es bast ant e paut ada:

• Dibuj ar los r ect ángulos baj o la cubr a
• Calcular el ár ea de cada uno de los r ect ángulos
• Sumar las ár eas
• Devolver como apr oximación la suma

¿Qué signif ica est o? Pues que ant es de poder cont inuar con el siguient e paso debes complet ar
el paso act ual. Una ver dader a r ecet a.

Pensemos un moment o en el pr oblema de un j uego de damas.

• Cada pieza en el t abler o posee un ár bol de decisión (a veces 2 movidas, en caso de las
piezas nor males y más de 2 movidas en caso de las damas).
• El j ugador posee ent onces un ár bol de decisión con al menos N subár boles, uno par a
cada pieza que t enga el t abler o.

¿Cr een que en f or ma lineal est o se r esolver ía r ápidament e?

La r espuest a a est a pr egunt a es que por supuest o que no. Si t enemos 10 piezas y solo
analizamos un nivel, debemos consider ar t ant as movidas que ni siquier a podr íamos ment alment e
visualizar las t odas par a elegir la mej or . Complicado ser ía par a el comput ador hacer lo en
t iempos r azonablement e cor t os.

Pensemos ahor a en ot r o t ipo de j uegos. I magínense que ust edes son los def ensor es de la t ier r a
y vienen unos mar cianos a at acar la con naves (¿Space I nvader s?).

¿Cómo el comput ador va a manej ar los movimient os de t u nave y los movimient os de los malos al
mismo t iempo sin quedar se pegado?

I magínat e que se t ar da 0.5 segundos en r ecoger un movimient o y r ealizar lo en pant alla.
Además t enemos 25 naves en la pant alla dibuj adas y que deben t ener movimient o pr opio. Por lo
t ant o de maner a secuencial, dibuj ar la pant alla cost ar ía una esper a de 0.5 x 25 segundos, es
decir , 12.5 segundos. Ahor a llevamos nuest r o j uego al pr ocesador más r ápido del mundo que
t ar da solo 0.1 segundos en r ecoger y dibuj ar . Tomar ía exact ament e 2.5 segundos en t oda la
pant alla. Todo est o sin consider ar que t ambién se deben mover los pr oyect iles dispar ados de
cada nave…¡Uf f f !... Me abur r í muy r ápido de j ugar .

Per o en r ealidad no hay t ant o pr oblema, por que la solución exist e y se llama Concur r encia.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

246
Concept os
La Concur r encia es la capacidad de ej ecut ar dist int os pr ocesos de
maner a síncr ona y de f or ma independient e.

Hast a ahor a nuest r os pr ogr amas no han t enido concur r encia, por supuest o. Con est e concept o
se acabar on los pr ocesos bat ch y las lar gas esper as de pr ocesamient o mient r as se ej ecut a el
pr ogr ama. Per o sin embar go, la concur r encia necesit a de algo que se llama Pr oceso.

Un Pr oceso es un t r ozo de pr ogr ama que se ej ecut a en un espacio
separ ado de memor ia, aislado del pr ogr ama pr incipal .

Básicament e un pr oceso es un pr ogr ama en ej ecución, per o que no depende de nadie. Est e t an
independient e pr ogr ama ej ecut a sus f unciones y al t er minar solo desapar ece. El ej emplo más
clar o de est as cosas es el MSN Messenger . Si t ienes t u Messenger ej ecut ándose como un
Pr oceso, t e per mit ir á navegar en int er net , j ugar Quake, hacer t u t ar ea de comput a, per o sin
int er r umpir t u t r abaj o el cont inúa su ej ecución.

¿Par a qué sir ven?

I magínat e nuevament e el Space I nvader s que debe r ealizar muchas cosas:

• Mover naves enemigas
• Recibir movimient os de la nave hér oe
• Mover pr oyect iles
• Calcular punt uación y manej ar vidas

Si t odo est o lo r ealiza en f or ma lineal, ser ía muy lent o. Veamos cómo ser ía en f or ma par alela:





Cont r olar Nave
Hér oe
Cont r olar
Naves
Enemigas
Cont r olar
Pr oyect iles
Administ r ar
Punt uación
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

247
Las bur buj as del di agr ama r epr esent an los pr oceso que r ealiza y cómo se comunican (a gr andes
r asgos). Ent onces, ¿cómo leer el diagr ama?: “Mient r as se cont r ola a la nave hér oe y a las naves
enemigas, se ver if ica que los dispar os lleguen a sus obj et ivos y si es así hay que sumar punt os o
r est ar vidas.

Suena sencillo, per o en la pr áct ica ¿cómo se hace?, con obj et os especiales que ver emos ahor a:
Sint axis
En concur r encia se ut iliza una clase especial llamada Thr ead. Est a clase est á const r uida de la
siguient e f or ma:

public class java.lang.Thread
extends java.lang.Object
implements java.lang.Runnable {
java.util.Map threadLocals;
java.util.Map inheritableThreadLocals;
public static final int MIN_PRIORITY;
public static final int NORM_PRIORITY;
public static final int MAX_PRIORITY;
public static native java.lang.Thread currentThread();
public static native void yield();
public static native void sleep(long)
throws java.lang.InterruptedException;
public static void sleep(long, int)
throws java.lang.InterruptedException;
public java.lang.Thread();
public java.lang.Thread(java.lang.Runnable);
public java.lang.Thread(java.lang.ThreadGroup,
java.lang.Runnable);
public java.lang.Thread(java.lang.String);
public java.lang.Thread(java.lang.ThreadGroup,java.lang.String);
public java.lang.Thread(java.lang.Runnable,java.lang.String);
public java.lang.Thread(java.lang.ThreadGroup,
java.lang.Runnable,java.lang.String);
public native synchronized void start();
public void run();
public final void stop();
public final synchronized void stop(java.lang.Throwable);
public void interrupt();
public static boolean interrupted();
public boolean isInterrupted();
public void destroy();
public final native boolean isAlive();
public final void suspend();
public final void resume();
public final void setPriority(int);
public final int getPriority();
public final void setName(java.lang.String);
public final java.lang.String getName();
public final java.lang.ThreadGroup getThreadGroup();
public static int activeCount();
public static int enumerate(java.lang.Thread[]);
public native int countStackFrames();
public final synchronized void join(long)
throws java.lang.InterruptedException;
public final synchronized void join(long, int)
throws java.lang.InterruptedException;
public final void join() throws java.lang.InterruptedException;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

248
public static void dumpStack();
public final void setDaemon(boolean);
public final boolean isDaemon();
public final void checkAccess();
public java.lang.String toString();
public java.lang.ClassLoader getContextClassLoader();
public void setContextClassLoader(java.lang.ClassLoader);
static {};
}

¿Qué signif ica est o? Bueno, en r ealidad son muchos mét odos que se pueden ut ilizar con
t hr eads, per o que solo ut ilizar emos una pequeña par t e en las clases que her edar emos de ella.

Par a cr ear un pr oceso independient e, se debe cr ear una clase que ext ienda de Thr ead:

public class MiThread extends Thread {
public void run() {
for (int i=1; i<=10; i++) {
System.out.println(i);
}
System.out.println("FIN DEL THREAD");
}
}

Est e t hr ead como pueden ver lo posee solo un mét odo pr opio (t odos los demás los t r ae l a clase
Thr ead) y ese se llama r un(). Est e mét odo es OBLI GATORI O (al igual que el main en el caso de
los pr ogr amas nor males) y es el encar gado de ej ecut ar el t hr ead, es decir , allí se pr ogr ama lo
que el t hr ead hace. En est e caso, solo impr ime los númer os del 1 al 10 en pant alla, uno por línea.

Si nosot r os compilamos est a clase y la ej ecut amos no pasar ía nada, de hecho echar ía de menos
el main el compilador y r eclamar ía. ¿Por qué?, bueno, por que no se puede ej ecut ar un t hr ead
como si f uese un pr ogr ama pr incipal, si no que se ut iliza lanzándolo desde ot r o pr ogr ama:

public class programa {
static public void main (String[] args) {
Thread t = new MiThread();
t.start();
System.out.println("FIN DEL PROGRAMA PRINCIPAL");
}
}

Not emos clar ament e que est e pr ogr ama cr ea un t hr ead del t ipo per sonalizado que cuent a de 1
a 10 en pant alla (clase MiThr ead), lo echa a cor r er ut ilizando el mét odo st ar t () nat ivo de la
clase Thr ead y luego pone en pant alla el t ext o “FI N DEL PROGRAMA PRI NCI PAL”. Con lo que
sabemos ahor a, esper ar íamos la siguient e salida:

1
2
...
9
10
FIN DEL THREAD
FIN DEL PROGRAMA PRINCIPAL

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

249
Sin embar go est o no es r ealment e lo que pasa, y la salida r eal es la siguient e:

FIN DEL PROGRAMA PRINCIPAL
1
2
...
9
10
FIN DEL THREAD

¿Que di ablos?

Bueno, est e t ema es sencillo. Veamos con un diagr ama de pr oceso lo que ocur r e (oj o que se
par ece a un diagr ama de int er acción de UML):
















Si se dan cuent a, el obj et o Pr ogr ama t er mina mucho ant es que el obj et o MiThr ead, es decir el
pr ogr ama puede t er minar sin que el t hr ead haya t er minado su labor . Línea a línea pasar ía lo
siguient e:

public class programa {
static public void main (String[] args) {

Thread t = new MiThread();

t.start();

System.out.println("...");

}
}




public class MiThread extends Thread {

public void run() {

System.out.println(”1¨);

System.out.println(”2¨);
...
System.out.println(”9¨);
System.out.println(”10¨);

System.out.println("...¨);

}
}


Ent onces, el t hr ead comienza j ust o al hacer el st ar t ().
Pr ogr ama
MiThr ead
new
st ar t ()
X
X
Aquí se ej ecut a la
par t e del pr ogr ama
pr incipal y t er mina
Pr imer o se cr ea el
obj et o que apunt ar a
a MiThr ead
Se ej ecut a el t hr ead
hast a que t er mina,
per o no depende del
pr ogr ama
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

250

Compliquemos el ej emplo. Supongamos que nuest r o pr ogr ama pr incipal sea:

public class programa {
static public void main (String[] args) {
Thread t1 = new MiThread();
Thread t2 = new MiThread();
t1.start();
t2.start();
System.out.println("FIN DEL PROGRAMA PRINCIPAL");
}
}

¿Qué deber ía salir ?

En est e caso no es f acil adivinar lo, por que la ej ecución de 2 t hr ead se t or na complej a. Así que
la salida al ej ecut ar el pr ogr ama es:

FIN DEL PROGRAMA PRINCIPAL
1
2
3
4
5
6
7
8
9
10
FIN DEL THREAD
1
2
3
4
5
6
7
8
9
10
FIN DEL THREAD

¡Hey, eso sí que es ext r año!

Si lo pensamos de cómo f unciona J ava, pues no es t an ext r año. Recuer da que el t hr ead posee el
mét odo st ar t () def inido como synchr onized, es decir , se ej ecut a un mét odo r un() a la vez. Per o
ent onces, ¿dónde est á el par alelismo? ¡est o es secuencial!. Veamos si cambiamos algo en
MiThr ead:

public class MiThread extends Thread {
public void run() {
for (int i=1; i<=10; i++) {
System.out.println(i);
try {
super.sleep(10);
}
catch (InterruptedException e) {
Pr incipal
Thr ead 1
Thr ead 2
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

251
}
}
System.out.println("FIN DEL THREAD");
}
}

Y la nueva salida ser ía:

FIN DEL PROGRAMA PRINCIPAL
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
FIN DEL THREAD
FIN DEL THREAD

¡Ahor a si que quedamos mal!....

Si t ampoco es t an complicado el t ema si explicamos pr imer o cuál f ue la modif icación que le
hicimos al t hr ead par a que hicier a est o. sleep(long) es un mét odo de la clase Thr ead que
per mit e hacer "dor mir " el pr oceso dur ant e una cant idad de milisegundos (¡si!, una pequeña
siest a) que se le pasan por par ámet r os, es decir , que se queda "esper ando" dur ant e un
moment o ant es de cont inuar con la ej ecución.

Como en est e caso est amos esper an 10 milisengundos, podemos decir que se int er cala la
ej ecución de cada t hr ead, most r ando que quedan pr áct icament e en par alelo (los dos al mismo
t iempo).

Además, si sumamos el hecho que el st ar t () est aba sincr onizado, signif ica que cada pr oceso
har á un ciclo por vez en el pr ocesador , y cada vez que el pr oceso haga sleep() est ar emos
avisando par a que ot r o t ome el cont r ol del pr ocesador por un ciclo más o hast a que ést e haga
ot r o sleep. Cuando el sleep se acaba, el pr oceso que despier t a t oma el cont r ol y comienza de
nuevo a ej ecut ar desde donde se dur mió.
Manej ando las Excepciones del Thr ead
Como lo dice su def inición, algunos mét odos deben manipular excepciones. ¿Cuáles son esas
excepciones?, bueno, eso depende del mét odo.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

252

En el caso del mét odo r un() est amos obligados a capt ur ar la excepción I nt er r upt edExcept ion
que nos per mit e cont r olar cuando el t hr ead es int er r umpido en su ej ecución. Est a int er r upción
puede pasar por dist int as r azones: f alt a de memor ia, llamada del pr oceso, et c.
Ej empl o
Veamos ahor a un pr ogr ama "r eal". Quer emos hacer la gr áf ica de un r eloj , per o que se mueva
segundo a segundo un i ndicador . Ser ía sencillo hacer pr imer o la gr áf ica:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Reloj {
private Frame programa;
private Canvas area;

public Reloj() {
programa = new Frame("JReloj");
programa.setLayout(new FlowLayout());

area = new Canvas();
area.setSize(600, 600);
programa.add(area);

programa.pack();
programa.show();

Graphics pincel = area.getGraphics();
pincel.setColor(Color.blue);
pincel.drawOval(10, 10, 590, 590);

Thread seg = new Timer(pincel, 300, 200);
seg.start();
}

public static void main(String[] args) {
Reloj r = new Reloj();
}
}

Fij émonos que la lógica de la int er f az es nula y que solo est amos pasándole el cont r ol del r eloj
a un pr oceso Timer llamado seg. La lógica ent onces est ar ía acá:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

class Timer extends Thread {
Graphics segundero;
int pos_x, pos_y;
long seg = 180;
public Timer (Graphics g, int x, int y) {
this.segundero = g;
this.pos_x = x;
this.pos_y = y;
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXI: Concurrencia

253
public void run() {
int ang = 6, x, y;
while(true) {
x = (int) Math.round(250 *
Math.sin(Math.toRadians(seg)));
y = (int) Math.round(250 *
Math.cos(Math.toRadians(seg)));

segundero.setColor(Color.blue);
segundero.drawLine(pos_x, pox_y,
pos_x + x, pos_y + y);

try {
super.sleep(1000);
}
catch(Exception e) {
}

segundero.setColor(Color.white);
segundero.drawLine(pos_x, pox_y,
pos_x + x, pos_y + y);

seg -= ang;
if (seg == 360) {
seg = 0;
}
}
}
}

En el const r uct or hacemos almacenar la posición inicial del segunder o y además el pincel que
nos per mit ir á dibuj ar sobr e el canvas de la int er f az cr eada ant es. El mét odo r un() en est e caso
t iene la misma est r uct ur a que cualquier a y se duer me el pr oceso cada cier t o t iempo por un
lapso de 1 segundo. Mient r as el pr oceso se despier t a, bor r a el segunder o desde donde est aba,
le aument a el ángulo al segunder o (en est e caso el ángulo es 6, por que si divi dimos 360 / 60
par t es nos queda que cada 6º deber ía cor r er el segunder o) y luego calculamos las nuevos
valor es par a la pr oyección sobr e el ej e x e y del segunder o y así dibuj ar lo. Luego de est o, a
dor mir de nuevo.

La lógica es super simple, per o el pr ogr ama ya se ve más complicado. Sin embar go la par t e de
par alelismo o concur r encia es siempr e igual.

Sin embar go, la gr acia del ej emplo r adica en la sencilla pr emisa de que el pr ocesador se
mant iene más t iempo desocupado que si lo hubiésemos hecho dent r o de la clase de la int er f az.
Est o implica:

• Ahor r o de memor ia
• Ahor r o de t iempo de esper a
• Apr ovechamient o del t iempo ocioso del pr ocesador

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

254
Capít ulo XXI I : I nt er net Wor king
29

Mot ivaci ón
















La r ed de r edes de comput ador es más gr ande del mundo es la que conocemos en est e moment o
como I nt er net . Tant o en las esf er as univer sit ar ias, per sonales y en Hollywood siempr e ha sido
un mundo at r ayent e, ya que el mundo vir t ual y la magia de est ar conect ados desde la
comodidad de su hogar con ot r os usuar ios a t r avés del mundo en solo segundos es r ealment e
algo que a nuest r a ment e le agr ada mucho.

¿Cómo es posible que podamos enviar un mensaj e a esa nebulosa, que conocemos como I nt er net
y que le llegue a nuest r o dest inat ar io sin ningún pr oblema? ¿Cómo es que con la diver sidad de
lenguas, los comput ador es de la China nos ent iendan? ¿Cómo es posible que un Hacker pueda
pinchar la línea int er net y capt ur ar inf or mación y cómo las empr esas se pr ot egen cont r a ellos?

Pues esas pr egunt as no son t an complej as y podr emos ent ender las un poco en est e capít ulo.
Concept os
Una Red de Comput ador es es una agr upación de una ser ie de est aciones
y ser vidor es que se conect an a t r avés de cables y que pueden
comunicar se ent r e sí ut ilizando una f or ma est ándar que ent ienden ent r e
sí.

I nt er net no es más que una gr an r ed de comput ador es que abar ca t odo el mundo, un concept o
bast ant e simple si pensamos que en el día de hoy lo est amos ut ilizando dur ant e al menos 4
hor as al día en pr omedio, y que par a muchos es r ealment e su pr opia f uent e de t r abaj o.

29
Basado en el mat er ial ent r egado por el pr of esor Nelson Baloian

I NTERNET




Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

255
Ent onces ¿de qué f or ma se comunican los comput ador es a t r avés de la r ed?. La def inición
f or mal habla de una f or ma común. A eso le llaman Pr ot ocolo.

Un Pr ot ocolo es un f or mat o con el cual se envía la inf or mación y que es
compar t ida t ant o por el gener ador como por el r ecept or .

En ef ect o, t odos los comput ador es ut ilizan pr ot ocolos de r ed par a comunicar se. Es así como se
usaban ant es pr ot ocolos Novell, UDP, Net BI OS y TCP. I nt er net usa el pr ot ocolo TCP/ I P par a
comunicar se y act ualment e es el pr ot ocolo más usado por los dist int os t ipos de comput ador es.

¿Cómo f unciona?

Veamos ahor a algunas def iniciones más t écnicas del pr ot ocolo:
Sint axis
30

El pr ot ocolo TCP/ I P se car act er iza por t r anspor t as los paquet es de inf or mación a t r avés de
una r ed hacia ot r o comput ador que est á dir eccionado según un númer o I P con el siguient e
f or mat o:

x x x . x x x . x x x . x x x

Por ej emplo:

164.182.219.12
10.10.10.1
255.255.0.1

Fíj at e que cada númer o ent r e los punt os est á ent r e 0 y 255, por lo que es posible guar dar un
númer o I Pen 4 byt es.

El númer o I P es un númer o único que ident if ica a cada t er minal dent r o de la r ed. No pueden
haber dos númer o iguales, pues ent r an en conf lict o. Físicament e podemos decir que es como el
r ut de cada comput ador . Es la f or ma en que la r ed se da cuent a dónde est á cada t er minal
f ísicament e (no geogr áf icament e, sino que en qué f inal del cable est á).

La clase I net Addr ess en J ava ident if ica un t er minal dent r o de la r ed. De est a f or ma, un
obj et o de t ipo I net Addr ess per f ect ament e puede r epr esent ar a t u comput ador :

...
InetAddress miTerminal = InetAddress.getLocalHost();
System.out.println(miTerminal.getHostAddress());
...


30
Todas las clases de est e capít ulo est án en el package j ava. net
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

256
Est e pequeño código muest r a el númer o I P de t u comput ador dent r o de la r ed donde est és
conect ado (est o inclusive puede indicar en qué númer o I Pest ás dent r o de I nt er net ).

Ot r a f or ma de logr ar llegar a un t er minal dent r o de la r ed es usando el host name. Est e nombr e
es el nombr e que enmascar a la I P y gener alment e debe pasar a t r avés de un DNS (Domain
Name Ser ver ) par a ident if icar se. Es así como par a encont r ar un t er minal usando su host name
se puede hacer de la siguient e f or ma:

...
InetAddress terminal = InetAddress.getByname(hostname);
System.out.println(terminal.getHostName());
System.out.println(terminal.getHostAddress());
...

Veamos un ej emplo que f uncione:

import java.io.*;
import java.net.*;

public class InetExample {
public static void main(String[] args) throws IOException {

try {
InetAddress yo = InetAddress.getLocalHost();
System.out.println("Mi nombre : " +
yo.getHostName());
System.out.println("Mi IP : " +
yo.getHostAddress());
System.out.println("Mi clase : " +
iPClass(yo.getAddress()));
}
catch (UnknownHostException e) {
System.out.println("No me encontre");
}
BufferedReader kbd = new BufferedReader(
new InputStreamReader(System.in));
String nombre;
while (true) {
try {
System.out.print("Ingrese un host :");
System.out.flush();
nombre = kbd.readLine();
if (nombre.equals("Fin"))
break;
System.out.println("Lookup DNS: " +
nombre);
InetAddress remoto =
InetAddress.getByName(nombre);
System.out.println("El IP : " +
remoto.getHostAddress());
System.out.println("El Nombre : " +
remoto.getHostName());
System.out.println("La clase : " +
iPClass(remoto.getAddress()));
}
catch (UnknownHostException e) {
System.out.println("No lo encontre");
}
catch (Exception e) {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

257
System.out.println("Problemas "+e);
}
}

}

public static char iPClass(byte[] ip) {
int byteMayor = 0xff & ip[0];
if (byteMayor < 128 ) return 'A';
if (byteMayor < 192 ) return 'B';
if (byteMayor < 224 ) return 'C';
if (byteMayor < 240 ) return 'D';
return 'E';
}
}

Cor r iendo est e ej emplo en un t er minal local aislado de int er net , la salida es:

Mi nombre : nb_portal01
Mi IP : 127.0.0.1
Mi clase : A
Ingrese un host :www.dcc.uchile.cl
Lookup DNS: www.dcc.uchile.cl
No lo encontre
Ingrese un host :Fin

En cambio que si conect amos ese mismo t er minal a una r ed de ár ea local con conexión a
int er net t enemos que:

Mi nombre : nb_portal01
Mi IP : 192.168.0.172
Mi clase : C
Ingrese un host :www.dcc.uchile.cl
Lookup DNS: www.dcc.uchile.cl
El IP : 192.80.24.4
El Nombre : www.dcc.uchile.cl
La clase : C
Ingrese un host :Fin

Vemos que hay una gr an dif er encia en los r esult ados, pues por que en un caso, la dir ección I P
del t er minal no exist e (est á desconect ado) y por def ect o asigna una dir ección “nula” que es
127.0.0.1. En el segundo caso, la r ed asigna una dir ección en f or ma dinámica (si, igual como lo
hacen con t u comput ador cuando t e conect as a int er net en t u casa) per o t iene salida y va a
buscar la I Pa t r avés del DNS del sit io www.dcc.uchile.cl. Es muy simple.

Exist en ot r as clases y f or mas de comunicar se a t r avés de la r ed. Es por eso que vamos a ver
ot r os concept os que nos ser vir án par a ent ender más las maner as que J ava t iene par a ut ilizar
TCP/ I P.

Ot r os mét odos de la clase I net Addr ess
31
:

Mét odo Descr ipción
boolean equals(Obj ect obj ) Compar es t his obj ect against t he specif ied obj ect .

31
Sacado desde la API del J DK 1.3.1 ubicada en ht t p:/ / j ava.sun.com/ j 2se/ 1.3/ docs/ api/
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

258
Mét odo Descr ipción
byt e[ ] get Addr ess() Ret ur ns t he r aw I Paddr ess of t his I net Addr ess obj ect .
st at ic I net Addr ess[ ] get AllByName(St r ing host ) Det er mines all t he I Paddr esses of a host , given t he host ' s name.
st at ic I net Addr ess get ByName(St r ing host ) Det er mines t he I Paddr ess of a host , given t he host ' s name.
St r ing get Host Addr ess() Ret ur ns t he I Paddr ess st r ing "%d.%d.%d.%d".
St r ing get Host Name() Get s t he host name f or t his I Paddr ess.
st at ic I net Addr ess get LocalHost () Ret ur ns t he local host .
int hashCode() Ret ur ns a hashcode f or t his I Paddr ess.
boolean isMult icast Addr ess() Ut ilit y r out ine t o check if t he I net Addr ess is an I P mult icast
addr ess.
St r ing t oSt r ing() Conver t s t his I Paddr ess t o a St r ing.
Concept os
Unif or m Resour ce Locat or (URL) consist e en l a dir ección de un r ecur so
que un ser vidor en la int er net publica par a que pueda ser leído por
dist int os usuar ios de la int er net .

Est e concept o sencillo, per o muchas veces usado, nos per mit e acceder a muchos lugar es de la
int er net en f or ma sencilla. La URL se compone de var ias par t es:

ht t p : / / www. dcc. uchile. cl : 80 / home. ht ml
P
r
o
t
o
c
o
l
o

H
o
s
t
n
a
m
e

P
u
e
r
t
o

R
e
c
u
r
s
o


Pr ot ocolo: Est ándar de más alt o nivel (sobr e TCP/ I P) que indica con qué f or mat o se est á
t r ansf ir iendo la inf or mación. Por ej emplo: Hyper Text Tr ansf er Pr ot ocol (ht t p), File Tr ansf er
Pr ot ocol (f t p), Gopher o News.

Host name: Es el nombr e del ser vidor al cuál nos est amos conect ando.

Puer t o: Es el númer o del puer t o en donde el ser vidor r ecibe el r equer imient o. Cada uno de los
pr ot ocolos t iene un númer o de puer t o est ándar , así es par a ht t p es el 80 y par a f t p el 21, per o
el ser vidor puede r ecibir r equer imient os en ot r os puer t os def inidos por él.

Recur so: Es el ar chivo, dir ect or io o inf or mación que el ser vidor t iene publicada y que el client e
desea leer .

Con est as def iniciones t enemos que t ambién son URL la siguient e list a:

• ht t p:/ / www.google.cl
• f t p:/ / j azzf or t una.syt es.net / Mult imedia
• ht t p:/ / www.por t al.cl:8080/ mypage.j sp
• ht t ps:/ / secur e.net wor k.com/ var / spool/ cgi?a=3

De est a misma f or mas, algo que no sabíamos ant es es el t ema del puer t o:
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

259

Un Socket es un link act ivo que per mit e comunicar dos punt os de una
r ed. Un Puer t o es un lugar donde se inst aur a el Socket par a mant ener la
conexión.

Con est a def inición podemos decir que un ser vidor puede t ener muchos puer t os abier t os en
esper a de una conexión dir ect a y por supuest o el socket es el que per mit e la comunicación
ent r e el ser vidor y el client e.

El ser vidor est á esper ando con un socket abier t o en el puer t o x. Es así que el client e r ealiza
una pet ición de conexión al puer t o, el cual si est á act ivo, acept a la conexión:







Una vez que la conexión es acept ada, en el ser vidor se cr ea ot r o socket asociado a un por t que
nor malment e ni siquier a lo conoce el client e, liber ando el “escuchador ” par a nuevos
r equer imient os.







Allí comienza la comunicación de lect ur a y/ o escr it ur a en el nuevo socket .

Ahor a veamos como se hace est o en J ava.
Sint axis
Pr imer o que t odo, veamos como se usan las URL en J ava. En est e caso, exist e una clase URL
que nos per mit e t r abaj ar con el dest ino de una URL:

...
URL miURL = new URL(”http://www.dcc.uchile.cl:80/index.html¨);
...

Con est a sent encia, lo que hacemos es cr ear una r ef er encia act iva a la ur l
ht t p:/ / www.dcc.uchile.cl:80. Ot r as f or mas de hacer lo mismo es:

...
URL miURL2 = new URL(”http¨, ”www.dcc.uchile.cl:80¨, ”index.html¨);
URL miURL3 = new URL(”http¨, ”www.dcc.uchile.cl¨, 80,
”index.html¨);
Ser vidor
Client e
Por t X
Pet ición de
Conexión
Ser vidor
Client e
Por t X Conexión
Bidir eccional
??
??
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

260
...

Est os obj et os hacen r ef er encia al mismo ur l, per o usan los ot r os const r uct or es de la clase
URL. Ot r o punt o impor t ant e es que al moment o de cr ear un URL es que ést a puede lanzar una
excepción Malf or medURLExcept ion y debe ser at r apada. De est a f or ma quedar ía mej or :

...
try {
URL miURL = new URL(”http://www.dcc.uchile.cl¨);
}
catch (MalformedURLException) {
System.out.println(”La URL es inválida¨);
}
...

Veamos ent onces un ej emplo más complet o que se conect a a Yahoo y obt iene el cont enido de
esa dir ección a la salida est ándar de J ava:

import java.net.*;
import java.io.*;

public class PURL {
public static void main(String[] args) throws Exception {
URL yahoo = new URL(”http://www.yahoo.com¨);
URLConnection yc = yahoo.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
String inputLine;

while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}

Al ej ecut ar est e pr ogr ama obt enemos (most r amos solo par t e de):

<html><head>

<title>Yahoo!</title>
<meta http-equiv="PICS-Label" content='(PICS-1.1
"http://www.icra.org/ratingsv02.html" l r (cz 1 lz 1 nz 1 oz 1 vz 1)
gen true for "http://www.yahoo.com" r (cz 1 lz 1 nz 1 oz 1 vz 1)
"http://www.rsac.org/ratingsv01.html" l r (n 0 s 0 v 0 l 0) gen true
for "http://www.yahoo.com" r (n 0 s 0 v 0 l 0))'>
<base href=http://www.yahoo.com/ target=_top>
<style type="text/css"><!--
.yhmpabd{border-left:solid #4d99e5 1px;border-right:solid #4d99e5
1px;border-bottom:solid #4d99e5 1px;}
.yhmnwbd{border-left:solid #9b72cf 1px;border-right:solid #9b72cf
1px;}
.yhmnwbm{border-left:solid #9b72cf 1px;border-right:solid #9b72cf
1px;border-bottom:solid #9b72cf 1px;}
//--></style>
.
.
.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

261

Como podemos ver obt enemos dir ect ament e el HTML que muest r a la int er f az de inicio del sit io
de Yahoo. ¿Par a qué ent onces sir ve?. Piensa si quisier as hacer búsquedas o hacer t u pr opio
br owser . Pr obemos ahor a cambiando la dir ección de Yahoo por la de un FTPvacío:

<html>
<head>
<title>Directory: /@nb_portal01</title>
</head>
<body>
<h2>Directory: /@nb_portal01</h2>
<pre>
<a href="ftp://nb_portal01/../"><img align="middle"
src="doc:/lib/images/ftp/directory.gif" border=0 width=24 height=26>
&lt;Parent Directory&gt;/</a>
</pre></body>
</html>

La salida es similar (t ambién es HTML) per o ¿qué de especial t iene?, pues que si pones lo mismo
en un br owser , puedes ver el cont enido del ser vidor FTP:
















Ot r os mét odos de la clase URL
32
:

Mét odo Descr ipción
URL(St r ing spec) Cr eat es a URL obj ect f r om t he St r ing r epr esent at ion.
URL(St r ing pr ot ocol, St r ing host , int por t ,
St r ing f ile)
Cr eat es a URL obj ect f r om t he specif ied pr ot ocol, host , por t
number , and f ile.
URL(St r ing pr ot ocol, St r ing host , int por t ,
St r ing f ile, URLSt r eamHandler handler )
Cr eat es a URL obj ect f r om t he specif ied pr ot ocol, host , por t
number , f ile, and handler .
URL(St r ing pr ot ocol, St r ing host , St r ing f ile) Cr eat es a URL f r om t he specif ied pr ot ocol name, host name, and
f ile name.
URL(URL cont ext , St r ing spec) Cr eat es a URL by par sing t he given spec wit hin a specif ied
cont ext .
URL(URL cont ext , St r ing spec,
URLSt r eamHandler handler )
Cr eat es a URL by par sing t he given spec wit h t he specif ied
handler wit hin a specif ied cont ext .

32
Sacado desde la API del J DK 1.3.1 desde ht t p:/ / j ava.sun.com/ j 2se/ 1.3/ docs/ api/
Aquí apar ecen los
ar chivos disponibles
par a descar ga
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

262
Mét odo Descr ipción
boolean equals(Obj ect obj ) Compar es t wo URLs.
St r ing get Aut hor it y() Ret ur ns t he aut hor it y par t of t his URL.
Obj ect get Cont ent () Ret ur ns t he cont ent s of t his URL.
Obj ect get Cont ent (Class[ ] classes) Ret ur ns t he cont ent s of t his URL.
St r ing get File() Ret ur ns t he f ile name of t his URL.
St r ing get Host () Ret ur ns t he host name of t his URL, if applicable.
St r ing get Pat h() Ret ur ns t he pat h par t of t his URL.
int get Por t () Ret ur ns t he por t number of t his URL.
St r ing get Pr ot ocol() Ret ur ns t he pr ot ocol name of t his URL.
St r ing get Quer y() Ret ur ns t he quer y par t of t his URL.
St r ing get Ref () Ret ur ns t he anchor (also known as t he "r ef er ence") of t his URL.
St r ing get User I nf o() Ret ur ns t he user I nf o par t of t his URL.
int hashCode() Cr eat es an int eger suit able f or hash t able indexing.
URLConnect ion openConnect ion() Ret ur ns a URLConnect ion obj ect t hat r epr esent s a connect ion t o
t he r emot e obj ect r ef er r ed t o by t he URL.
I nput St r eam openSt r eam() Opens a connect ion t o t his URL and r et ur ns an I nput St r eam f or
r eading f r om t hat connect ion.
boolean sameFile(URL ot her ) Compar es t wo URLs, excluding t he "r ef " f ields.
pr ot ect ed void set (St r ing pr ot ocol, St r ing host ,
int por t , St r ing f ile, St r ing r ef )
Set s t he f ields of t he URL.
pr ot ect ed void set (St r ing pr ot ocol, St r ing host ,
int por t , St r ing aut hor it y,
St r ing user I nf o, St r ing pat h,
St r ing quer y, St r ing r ef )
Set s t he specif ied 8 f ields of t he URL.
st at ic void set URLSt r eamHandler Fact or y(
URLSt r eamHandler Fact or y f ac)
Set s an applicat ion' s URLSt r eamHandler Fact or y.
St r ing t oExt er nalFor m() Const r uct s a st r ing r epr esent at ion of t his URL.
St r ing t oSt r ing() Const r uct s a st r ing r epr esent at ion of t his URL.

Con URL ent onces se t iene acceso de lect ur a par a t odos aquellos ser vicios que pueden ser
alcanzados usando un URL. Sin embar go cuando se desea mayor cont r ol sobr e la comunicación,
es necesar io usar socket s.

Par a conect ar se con un socket , solo bast a conocer la dir ección de ést e y el puer t o en el cual
r eside el socket , el r est o del t r abaj o lo hace el mismo socket .

...
Socket llamada = new Socket(host, port);
...

De est a f or ma est amos conect ándonos con el Socket ubicado en el host y por t indicados.
Después de la llamada, el client e se queda en esper a a que el ser vidor cont est e y le per mit a
conect ar se a t r avés del nuevo socket dedicado a la conexión.

En el caso del socket , ést e puede r et or nar un pr oblema y es r ecomendado at r apar la excepción
UnknownHost Except ion. De est a f or ma quedar ía el pr ogr ama:

...
try {
Socket s = new Socket(”anakena.dcc.uchile.cl¨, ”25¨);
}
catch (UnknownHostException e) {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

263
System.out.println(”Error: Host desconocido¨);
}
...

Así si el ser vidor no r esponde, o no exist e, el pr ogr ama enviar ía un mensaj e de Host
desconocido.

Veamos un ej emplo pr áct ico de Socket s

import java.net.*;
import java.io.*;

public class Sockets {
public static void main(String args[]) {
String host = ”anakena.dcc.uchile.cl¨;
int port = 25;
try {
Socket s = new Socket(host, port);
System.out.println("The local host : " +
s.getLocalAddress());
System.out.println("The local port : " +
s.getLocalPort());
System.out.println("The remote host : " +
s.getInetAddress());
System.out.println("The remote port : " +
s.getPort());
System.out.println("The SoTimeout is : " +
s.getSoTimeout());
System.out.println("The SoLinger is : " +
s.getSoLinger());
}
catch (Exception e) {
System.out.println("Error: "+e);
}
}
}

Est e pr ogr ama se t r at ar á de conect ar se al puer t o 25 del ser vidor anakena.dcc.uchile.cl y la
salida, después de un r at o que el pr ogr ama esper a la r espuest a, se ve como la que sigue:

The local host : nb_portal01.stgo.codelco.cl/165.182.190.22
The local port : 2420
The remote host : anakena.dcc.uchile.cl/192.80.24.3
The remote port : 25
The SoTimeout is : 0
The SoLinger is : -1

Local Host y Por t nos muest r an el comput ador donde est á cor r iendo el pr ogr ama y el puer t o en
donde cr ea el socket local. En Remot e Host y Por t nos muest r a el dest ino al cual quer emos
llegar , incluyendo I P. Por últ imo el t imeout del socket y de mant ención de conexión ( -1 es
inf init o).

Veamos ahor a un ej emplo en donde escr ibimos en el Socket par a que el ser vidor nos devuelva
inf or mación: Un client e de cor r eos:

import java.io.*;
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

264
import java.util.StringTokenizer;
import java.net.*;

public class cliente_pop {

public static void main(String[] args){
Socket s;
String cmd;
InetAddress a;
BufferedReader in;
PrintWriter out;

if (args.length!=3){
System.out.println("Uso: cliente_pop <host>
<username> <password>\n\n");
System.exit(0);
}

try {
s=new Socket(args[0], 110);
System.out.println("Creado socket: "+s);

in=new BufferedReader(new
InputStreamReader(s.getInputStream()));
out=new PrintWriter(s.getOutputStream(), true);

System.out.println("Creado buffered in=" +
in.toString());
System.out.println(in.readLine());

//Envio login
out.println("user "+ args[1]);
System.out.println(in.readLine());

//Envio password
out.println("pass "+ args[2]);
System.out.println(in.readLine());

out.println("stat");

System.out.println(in.readLine());

out.println("list");

String line;
while ( !(line = in.readLine()).equals("."))
System.out.println(line);

} catch (IOException e) {
System.out.println("Imposible Crear socket\n");
}
}
}

Si ej ecut amos con una cuent a válida en el ser vidor de pop3.t er r a.cl, t enemos la salida:

Creado socket:
Socket[addr=pop3.terra.cl/200.28.216.13,port=110,localport=2447]
Creado buffered in=java.io.BufferedReader@113750
+OK POP3 server ready (6.5.034)
<77C193C192304628EA6DA4763A1C196922931EC3@genesis.terra.cl>
+OK Password required
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

265
+OK 27 messages
+OK 27 1081620
+OK
1 1241
2 35581
3 2705
4 361330
5 332819
6 2701
7 5211
8 21391
9 8989
10 15639
11 12506
12 21773
13 2997
14 14366
15 33907
16 21454
17 21716
18 21583
19 3631
20 21178
21 4066
22 20871
23 41523
24 29331
25 8563
26 12476
27 2072

¡¡Tengo 27 cor r eos en mi inbox!! ¡¡I ncr eíble!!

Veamos los mét odos adicionales de la clase Socket
33
:

Mét odo Descr ipción
Socket (I net Addr ess addr ess, int por t ) Cr eat es a st r eam socket and connect s it t o t he specif ied por t
number at t he specif ied I Paddr ess.
Socket (I net Addr ess addr ess, int por t ,
I net Addr ess localAddr , int localPor t )
Cr eat es a socket and connect s it t o t he specif ied r emot e addr ess
on t he specif ied r emot e por t .
Socket (St r ing host , int por t ) Cr eat es a st r eam socket and connect s it t o t he specif ied por t
number on t he named host .
Socket (St r ing host , int por t , I net Addr ess
localAddr , int localPor t )
Cr eat es a socket and connect s it t o t he specif ied r emot e host on
t he specif ied r emot e por t .
void close() Closes t his socket .
I net Addr ess get I net Addr ess() Ret ur ns t he addr ess t o which t he socket is connect ed.
I nput St r eam get I nput St r eam() Ret ur ns an input st r eam f or t his socket .
boolean get KeepAlive() Test s if SO_KEEPALI VE is enabled.
I net Addr ess get LocalAddr ess() Get s t he local addr ess t o which t he socket is bound.
int get LocalPor t () Ret ur ns t he local por t t o which t his socket is bound.
Out put St r eam get Out put St r eam() Ret ur ns an out put st r eam f or t his socket .
int get Por t () Ret ur ns t he r emot e por t t o which t his socket is connect ed.
int get ReceiveBuf f er Size() Get s t he value of t he SO_RCVBUF opt ion f or t his Socket , t hat is
t he buf f er size used by t he plat f or m f or input on t his Socket .
int get SendBuf f er Size() Get value of t he SO_SNDBUF opt ion f or t his Socket , t hat is t he
buf f er size used by t he plat f or m f or out put on t his Socket .

33
Sacado desde la API del J DK 1.3.1 ubicada en ht t p:/ / j ava.sun.com/ j 2se/ 1.3/ docs/ api/
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

266
Mét odo Descr ipción
int get SoLinger () Ret ur ns set t ing f or SO_LI NGER.
int get SoTimeout () Ret ur ns set t ing f or SO_TI MEOUT.
boolean get TcpNoDelay() Test s if TCP_NODELAY is enabled.
void set KeepAlive(boolean on) Enable/ disable SO_KEEPALI VE.
void set ReceiveBuf f er Size(int size) Set s t he SO_RCVBUF opt ion t o t he specif ied value f or t his
Socket .
void set SendBuf f er Size(int size) Set s t he SO_SNDBUF opt ion t o t he specif ied value f or t his
Socket .
st at ic void set Socket I mplFact or y(
Socket I mplFact or y f ac)
Set s t he client socket implement at ion f act or y f or t he applicat ion.
void set SoLinger (boolean on, int linger ) Enable/ disable SO_LI NGER wit h t he specif ied linger t ime in
seconds.
void set SoTimeout (int t imeout ) Enable/ disable SO_TI MEOUT wit h t he specif ied t imeout , in
milliseconds.
void set TcpNoDel ay(boolean on) Enable/ disable TCP_NODELAY (disable/ enable Nagle' s
algor it hm).
void shut downI nput () Places t he input st r eam f or t his socket at "end of st r eam".
void shut downOut put () Disables t he out put st r eam f or t his socket .
St r ing t oSt r ing() Conver t s t his socket t o a St r ing.

Ahor a que vemos como el client e se conect a con un ser vidor , veamos como est o se ve por par t e
del ser vidor .
Concept os
Un Ser vidor es un t er minal en la r ed que per mit e compar t ir r ecur sos
con ot r os t er minales, a los que se le llama Client es.

En ef ect o, hemos vist o como un t er minal llama a ot r o par a obt ener r ecur sos usando las URLs y
las I P’s, per o no hemos vist o aún como est os t er minales “ser vidor es” pueden r esponder a los
r equer imient os de los client es. Veamos la sint axis de est o.
Sint axis
Recor dando como se comunican los client es con los ser vidor es y analizando paso a paso
podemos ver como f unciona.

El ser vidor esper a con un socket abier t o en el puer t o x.







...
ServerSocket s = new ServerSocket(X);
Socket c = s.accept();
...

Ser vidor
Client e
Por t X
Se abr e el
puer t o X
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

267







El ser vidor se queda esper ando el r equer imient o del client e en la línea del s.accept () y cuando
ést e hace la llamada, es capt ur ada por la var iable c que r epr esent a la conexión con el socket
del client e.







Desde est e moment o comienza la conexión. Cualquier r equer imient o se puede obt ener y enviar
usando la var iable c del client e.

Veamos un ej emplo si mple: Un ser vidor Echo. Est e pr ogr ama lo que hace es r epet ir lo que el
client e le envíe, y se lo envía a la salida del client e. Ahor a ver emos el pr ogr ama Ser vidor :

import java.net.*;
import java.io.*;
import java.util.*;

public class EchoServer {

public static void main(String args[]) throws Exception {
ServerSocket server = new ServerSocket(4445);

System.out.println("Waiting for client...");
Socket client = server.accept();
System.out.println("Accepted from " +
client.getInetAddress());
PrintWriter out =
new PrintWriter(client.getOutputStream(),true);
BufferedReader in = new BufferedReader(new
InputStreamReader(client.getInputStream()));

while (true) {
String line = in.readLine();
if (line.equals("**"))
break;
out.println(line);
}

client.close();
}
}

Ser vidor
Client e
Por t X Conexión usando
el obj et o c
??
??
Ser vidor
Client e
Por t X
Pet ición r ecibida
por accept ()
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

268
El ser vidor abr e un socket escuchador en el por t 4445 y se queda con el mensaj e “Wait ing f or
client ...” hast a que un client e se conect a. Al moment o de que se conect a un usuar io solo
muest r a un mensaj e del client e que se conect ó. Ahor a veamos el pr ogr ama client e:

import java.io.*;
import java.net.*;

public class EchoClient {
public static void main(String[] args) throws Exception {

Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;

echoSocket = new Socket(args[0], 4445);
out = new PrintWriter(echoSocket.getOutputStream(),
true);
in = new BufferedReader(new
InputStreamReader(echoSocket.getInputStream()));

BufferedReader stdIn = new BufferedReader(new
InputStreamReader(System.in));
String userInput;
System.out.println("echo starts...");

while (true) {
userInput = stdIn.readLine();
out.println(userInput);
if (userInput.equals("**"))
break;
System.out.println("echo: " + in.readLine());
}

echoSocket.close();
}
}

Como se puede ver , el client e lo único que hace es r ecibir un t ext o y enviar lo al socket . Luego
de que se ha enviado, es leído desde allá mismo par a saber qué hay en el socket . Simple.

Ot r o ej emplo que t ambién es muy simpát ico es el Talk, que envía mensaj es de un lado a ot r o:

import java.net.*;
import java.io.*;
public class TalkServer {
public static void main(String args[]) throws Exception {
ServerSocket ss = null;
PrintWriter out=null;
BufferedReader in=null;
Socket s;
ss = new ServerSocket(4446);
while(true) {
System.out.println("Waiting for a client ");
s = ss.accept();
System.out.println("Someone is calling: " +
s.getInetAddress());
in = new BufferedReader(new InputStreamReader(
s.getInputStream()));
while (true) {
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

269
String line = in.readLine();
if (line.equals("**"))
break;
else
System.out.println("Msg: "+line);
}
in.close();
s.close();
System.out.println("Call ended ");
}
}
}

import java.io.*;
import java.net.*;
class TalkClient {
public static void main(String args[] ) throws Exception {
PrintWriter outSocket = null;
BufferedReader usin = new BufferedReader(
new InputStreamReader(System.in));
Socket s;
while (true) {
System.out.print("Type hostname to call to: ");
String line = usin.readLine();
if (line.equals("end"))
break;
s = new Socket(line, 4446);
outSocket = new
PrintWriter(s.getOutputStream(),true);
System.out.println("Connected, start talking
(** for ending)");
while (true) {
System.out.print("? > ");
line = usin.readLine();
outSocket.println(line);
if (line.equals("**"))
break;
}
s.close();
outSocket.close();
System.out.println("call is over");
}
}
}

Échalo a cor r er y ve qué pasa cuando lo ej ecut as.

Veamos los mét odos que posee la clase Ser ver Socket
34
:

Mét odo Descr ipción
Ser ver Socket (int por t ) Cr eat es a ser ver socket on a specif ied por t .
Ser ver Socket (int por t , int backlog) Cr eat es a ser ver socket and binds it t o t he specif ied local por t
number , wit h t he specif ied backlog.
Ser ver Socket (int por t , int backlog,
I net Addr ess bindAddr )
Cr eat e a ser ver wit h t he specif ied por t , list en backlog, and local
I Paddr ess t o bind t o.
Socket accept () List ens f or a connect ion t o be made t o t his socket and accept s it .
void close() Closes t his socket .

34
Sacado desde la API del J DK 1.3.1 ubicada en ht t p:/ / j ava.sun.com/ j 2se/ 1.3/ docs/ api/
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

270
Mét odo Descr ipción
I net Addr ess get I net Addr ess() Ret ur ns t he local addr ess of t his ser ver socket .
int get LocalPor t () Ret ur ns t he por t on which t his socket is list ening.
int get SoTimeout () Ret r ive set t ing f or SO_TI MEOUT.
pr ot ect ed void implAccept (Socket s) Subclasses of Ser ver Socket use t his met hod t o over r ide accept ()
t o r et ur n t heir own subclass of socket .
st at ic void set Socket Fact or y(
Socket I mplFact or y f ac)
Set s t he ser ver socket implement at ion f act or y f or t he
applicat ion.
void set SoTimeout (int t imeout ) Enable/ disable SO_TI MEOUT wit h t he specif ied t imeout , in
milliseconds.
St r ing t oSt r ing() Ret ur ns t he implement at ion addr ess and implement at ion por t of
t his socket as a St r ing.

¿Qué pasa si abr es 2 client es al mismo ser vi dor ? Los r equer imient os del segundo client e
quedan “encolados” hast a que el pr imer o t er mine y luego puede cont inuar . Est o no es en la
r ealidad de los ser vidor es, por que ellos pueden r ecibir muchos client es en f or ma concur r ent e.
Es por eso que podemos ver est e nuevo concept o.

Los ser vidor es concur r ent es, ent onces pueden at ender a más de un client e a la vez. Est o se
puede hacer de var ias f or mas, per o veamos una f or ma en que usar emos Thr eads.

Los Ser vidor es en la r ed per mit en muchas conexiones en f or ma
simult ánea, por lo que el pr ogr ama que per mit e r ecibir las conexiones de
los client es debe ser “concur r ent e”.

Est a es la t ípica pr oblemát ica que hay en el día a día sobr e int er net . Un ser vi dor web, un
ser vidor de ar chivos, un ser vidor de chat , et c, que per mit en que múlt iples usuar ios accedan a
sus r ecur sos compar t idos.





El client e solicit a conexión y se conect a con el pr oceso r ecibidor del ser vidor .









El r ecibidor gener a un nuevo pr oceso (Thr ead) con el pr ogr ama que solo comunica ambos punt os
(client e y ser vidor ) de est a f or ma haciendo que el r ecibidor quede libr e y a la esper a de un
nuevo client e.

Recibidor
Client e
Por t X
Pet ición r ecibida
por accept ()
Recibidor
Client e
Por t X
Comunicación
Bidir eccional
At endedor Por t Y
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

271











De est a f or ma, cuando llega ot r o client e, el r ecibidor lo puede at ender y der ivar lo a ot r o
at endedor cr eado especialment e par a la comunicación, sin int er f er ir en el t r abaj o que t iene el
pr imer at endedor y el pr imer client e.

¿Cómo hacemos est o en f or mat o J ava?

Pues no es t an dif ícil como par ece. Cómo la lógica de r ecibimient o y at ención est á por par t e del
ser vidor y no del client e, los pr ogr amas que hast a ahor a vimos como “client es” no se ven
af ect ado en lo absolut o. En cambio el ser vidor suf r e una pequeña alt er ación:

El pr ogr ama pr incipal es el Recibidor : Con est a declar ación, y gener alizando la f or ma de
t r abaj o de los ser vidor es, podemos llegar a que la par t e r ecibidor a del ser vidor quedar ía con la
siguient e sint axis:

import java.net.* ;
import java.io.* ;

public class Recibidor {
public static void main(String[] args) throws Exception {
// Creación del puerto de escucha y recibimiento
ServerSocket servidor = new ServerSocket(<port>);

// Ciclo de espera por clientes
while(true) {
// Obtenemos el socket del cliente
Socket cliente = servidor.accept();

// Creamos nuevo ”atendedor¨ entregándole Socket
Thread atiende = new Atendedor(cliente);

// Atendemos al cliente
atiende.start();
}
}
}

Est a ver sión por supuest o no es la única que puedes usar y solo debe ser consider ada como un
ej emplo genér ico dent r o del cont ext o del pr oblema.

Recibidor
Client e
Por t X
At endedor Por t Z
Client e
At endedor Por t Y
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

272
Si analizamos un poquit o el pr ogr ama, podemos ver que el ser vidor siempr e est á escuchando
por un client e. Si no le llega un client e, el pr ogr ama suelt a el pr ocesador y sigue esper ando
hast a que alguien se conect e.

La Clase de Thr ead es el At endedor : Tal como dice el nombr e, la clase que ext iende de
Thr ead ent onces ser ía el at endedor y es at endido usando el mét odo r un que Thr ead obliga a
implement ar :

import java.net.* ;
import java.io.* ;

public class Atendedor extends Thread {
private Socket cliente;

public Atendedor(Socket c) {
this.cliente = c;
}

public void run() {
// AQUI va la lógica de proceso entre el servidor y
// el cliente.
}
}

Tal como se ve, y si compar amos un poco con los ser vidor es no concur r ent es, lo único que
hacemos es pasar la par t e de pr oceso de la comunicación a un Thr ead. No es dif icil, per o al
pr incipio cuest a compr ender bien.
Ej emplos Pr áct icos
Exist e en linux un pr ogr ama que se llama For t une. La idea de est e pr ogr ama es enviar mensaj es
de índole de f or t una al usuar io que lo solicit a. Veamos como se ve implement ado con J ava:

import java.io.*;
import java.net.*;

public class FortuneServer extends Thread {
private ServerSocket myServer;

public FortuneServer(int port) {
System.out.print("Trying to opening port: " + port + "... ");
try {
this.myServer = new ServerSocket(port);
}
catch (IOException e) {
System.out.println("ERROR: " + e.getMessage());
System.exit(0);
}
System.out.println("Ok");
}

public void run() {
System.out.println("Waiting for connections...");
while (true) {
Socket client = null;
try {
client = this.myServer.accept();
}
catch (IOException e) {
System.out.println("ERROR: " + e.getMessage());
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

273
System.exit(0);
}
System.out.println("-> Incoming from " +
client.getInetAddress() + " on port " +
client.getPort());
FortuneConnection fc = new FortuneConnection(client);
fc.start();
}
}

static public void main(String[] args) {
FortuneServer fs = new FortuneServer(4446);
fs.run();
}
}

class FortuneConnection extends Thread {
private Socket client;

public FortuneConnection(Socket client) {
this.client = client;
}

public void run() {
try {
PrintWriter send = new PrintWriter(
this.client.getOutputStream(), true);
BufferedReader receive = new BufferedReader(
new InputStreamReader(
this.client.getInputStream()));
send.println("% Hello!... What do you want?");
while(true) {
try {
super.sleep(1);
}
catch(InterruptedException e) {
System.out.println("ERROR: " +
e.getMessage());
System.exit(0);
}
String line = receive.readLine();
if (".".equals(line))
break;
if ("cookie".equals(line)) {
BufferedReader file =
new BufferedReader(
new FileReader("fortune.txt"));
int x_max = Integer.parseInt(
file.readLine());
int x = (int) Math.round(Math.random() *
x_max) + 1;
System.out.println("(" + x + "/" +
x_max + ")");
String txt = "";
for (int i=0; i<x; i++) {
String l = file.readLine();
if (l == null) break;
txt = l;
}
file.close();
send.println("% " + txt);
}
else {
send.println("% I don't understand " +
line);
}
}
send.close();
receive.close();
System.out.println("<- Closing connection!");
this.client.close();
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

274
}
catch (Exception e) {
System.out.println("ERROR: " + e.getMessage());
}
}
}

El concept o es bien simple. El Ser vidor r ecibe la llamada, esper a el comando cookie, y r esponde
con el mensaj e que desea. Fíj at e que en est a ver sión podemos int er act uar con él dir ect ament e
desde el client e (consola, ent r ada est ándar ). Veamos como quedar ía un pr ogr ama con eso:

import java.net.*;
import java.io.*;

public class FortuneClient {
public static void main(String[] args) throws Exception {
Console c = new Console();
InetAddress local = InetAddress.getLocalHost();
c.print("Creating connection to " +
local.getHostAddress());
Socket server = new Socket(local.getHostAddress(), 4446);
c.print("port " + server.getPort() + "... ");
PrintWriter send = new PrintWriter(server.getOutputStream(),
true);
BufferedReader receive = new BufferedReader(
new InputStreamReader(server.getInputStream()));
String line = receive.readLine();
c.println("Ok!");
c.println(line);
while(true) {
c.print("> ");
String cmd = c.readLine();
send.println(cmd);
if (".".equals(cmd))
break;
line = receive.readLine();
c.println(line);
}
send.close();
receive.close();
c.print("Closing connection... ");
server.close();
c.println("Ok!");
}
}

En est e caso es una consola con la cual int er act uamos al Ser vidor . Per o ¿y si hacemos una
ver sión simple de línea de comando aut omát ica?:

import java.net.*;
import java.io.*;

public class Fortune {
public static void main(String[] args) throws Exception {
InetAddress local = InetAddress.getByName("nb_portal01");
Socket server = new Socket(local.getHostAddre ss(), 4446);
PrintWriter send = new PrintWriter(server.getOutputStream(),
true);
BufferedReader receive = new BufferedReader(
new InputStreamReader(server.getInputStream()));
String line = receive.readLine();
send.println("cookie");
line = receive.readLine();
System.out.println(line);
send.println(".");
send.close();
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

275
receive.close();
server.close();
}
}

Muy similar per o se ej ecut a solo una vez.

Ahor a, t odos conocemos lo que son los Chat s. Pues bien, imaginemos que quer emos const r uir
uno con est a t ecnología. ¿Cómo lo hacemos?. Pues pr ef ier o que lo veas con t us pr opios oj os:

import java.net.*;
import java.io.*;
import java.util.*;

public class ChatServer {
public ServerSocket server;
public List clients;

public ChatServer(int port) {
try {
this.server = new ServerSocket(port);
this.clients = new ArrayList();
}
catch (Exception e) {
System.err.println("ERROR: " + e.getMessage());
System.exit(0);
}
}

public void startServer() {
System.err.println("Esperando conexiones...");
while (true) {
try {
Socket client = this.server.accept();
clients.add(new PrintWriter(
client.getOutputStream(), true));
System.err.println("[" +
client.getInetAddress().getHostAddress()
+ "] Cliente conectado");
ChatConnection cc = new ChatConnection(client);
cc.start();
}
catch (Exception e) {
System.err.println("ERROR: " + e.getMessage());
System.exit(0);
}
}
}

class ChatConnection extends Thread {
private Socket client;
private int n;

public ChatConnection(Socket client) {
this.client = client;
this.n = clients.indexOf(client);
}

public void run() {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(
this.client.getInputStream()));
while (true) {
String line = in.readLine();
if (line == null) {
System.err.println("[" +
this.client.getInetAddress().
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

276
getHostAddress()
+ "] Client disconnected");
break;
}
for (int i=0; i<clients.size(); i++) {
PrintWriter out = (PrintWriter)
clients.get(i);
out.println(line);
}
}
in.close();
client.close();
clients.remove(n);
}
catch (Exception e) {
System.err.println("ERROR: " + e.get Message());
}
}
}

public static void main(String[] args) {
if (args.length <= 0) {
System.err.println("Uso: ChatServer <port>");
System.exit(0);
}
ChatServer cs = new ChatServer(Integer.parseInt(args[0]));
cs.startServer();
}
}

En est e caso la clase Chat Ser ver es el “Recibidor ” y es cr eada a par t ir de un pr ogr ama
pr incipal que r eside en la misma clase Chat Ser ver . De est a f or ma es cr eado un obj et o en el
ser vidor de t ipo Chat Ser ver que lo único que se pr eocupa es de escuchar .

Por ot r o lado, exist e una clase int er na que se llama Chat Connect ion que es quien se pr eocupa de
conect ar el client e con el ser vidor par a r ecibir los mensaj es de él.

Per o ¿cuál es la dif er encia con el pr oblema del For t une?.

Simple. En est e caso cuando el ser vidor r ecibe el mensaj e de un client e, debe enviar a t odos
los demás client es conect ados un mensaj e. A est o se le conoce como Br oadcast ing.

Adj unt amos un posible client e de est e chat par a que puedan ej ecut ar lo.

import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;

public class ChatClient {
private Socket server;
private String nick;

private Frame ventana;
private TextArea texto;
private TextField mensaje;
private Button salir;

private PrintWriter out = null;

public ChatClient(String server, int port, String nick) {
ventana = new Frame("Java Chat v2.0");
ventana.setLayout(new BorderLayout());
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

277

mensaje = new TextField(100);
mensaje.addActionListener(new MensajeListener());
ventana.add(mensaje, "North");

texto = new TextArea(25, 100);
texto.setEnabled(true);
texto.setBackground(Color.white);
texto.setForeground(Color.black);
ventana.add(texto, "Center");

Panel opciones = new Panel();
opciones.setLayout(new FlowLayout());
salir = new Button("Salir");
salir.addActionListener(new SalirListener());
opciones.add(salir);
ventana.add(opciones, "South");

ventana.pack();
ventana.show();

try {
this.nick = nick;
this.server = new Socket(server, port);
ChatClientReader ccr = new ChatClient Reader();
ccr.start();
out = new PrintWriter(
this.server.getOutputStream(), true);
out.println("*** " + nick + " se ha conectado ***");
}
catch(Exception e) {
System.err.println("ERROR: " + e.getMessage());
System.exit(0);
}
}

class ChatClientReader extends Thread {

public void run() {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(
server.getInputStream()));
while(true) {
String line = in.readLine();
if (line == null)
break;
texto.append(line + "\n");
}
in.close();
server.close();
System.exit(0);
}
catch(Exception e) {
System.err.println("ERROR: " + e.getMessage());
System.exit(0);
}
}

}

class MensajeListener implements Actio nListener {

public void actionPerformed(ActionEvent x) {
try {
out.println("[" + nick + "] " +
mensaje.getText());
mensaje.setText("");
}
catch(Exception e) {
System.err.println("ERROR: " + e.getMessage());
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

278
System.exit(0);
}
}

}

class SalirListener implements ActionListener {

public void actionPerformed(ActionEvent x) {
System.exit(0);
}

}

static public void main(String[] args) throws Exception {
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
System.out.print(" Nick > ");
String nick = stdin.readLine();
System.out.print(" Server > ");
String server = stdin.readLine();
System.out.print(" Port > ");
String port = stdin.readLine();
ChatClient cc = new ChatClient(server,
Integer.parseInt(port),
nick);
}
}

Est a ver sión est á hecha con int er f az gr áf ica par a que puedan pr obar la.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

279
Ser vlet s
Mot i vaci ón
Sobr e la int er net , exist e el pr ot ocolo HTTP(Hyper Text Tr ansf er Pr ot ocol) que per mit e enviar
paquet es de t ext os a t r avés del TCP/ I P escr it os en lenguaj e HTML (Hyper Text Mar kup
Language).






La f igur a muest r a el pr oceso de cómo f unciona la per t ición o llamada de una URL desde t u
br owser (Micr osof t I nt er net Explor er , Net scape Navigat or , Oper a, Mosaic, et c). Est o se
puede explicar de la siguient e f or ma:

• El Client e r ealiza una llamada al Ser vicio de Publicación Web o HTTP que se encuent r a
r esident e en el Ser vidor escuchando en el puer t o 80 (nor malment e).

• El Ser vicio de Publ icación (t ambién llamado Web Ser ver y que no es más que un
pr ogr ama escuchador que gener a un nuevo socket par a r esponder al client e) det ect a la
dir ección y va a buscar el ar chivo que cont iene el pr ogr ama HTML que est á pidiendo el
usuar io. Nor malment e est e pr ogr ama es un ar chivo de t ext o plano con códigos HTML.

• El Web Ser ver envía a t r avés de la r ed ent onces el cont enido del ar chivo HTML al
client e dir ect ament e.

• El socket del Navegador r ecibe el ar chivo plano y lo int er pr et a par a most r ar
gr áf icament e lo que viene escr it o en HTML.

¡¡Clar o!!. El pr ogr ama Navegador que est á en el client e es el pr ogr ama “client e” de nuest r o
ser vidor de publicación web. Ent onces, él se pr eocupa de abr ir el Socket con el web ser ver .

¿Cuál es la gr acia del HTML?

Algunas car act er íst icas es que se puede usar est ilos, color es, imágenes, videos y muchos
medios que hacen las páginas at r act ivas. De hecho si navegas en int er net encont r ar ás que t odo
lo que ves es HTML (o casi t odo).

La desvent aj a es que lo que el ser vicio de publicación envía es exact ament e lo que cont iene el
ar chivo, el cuál es “est át ico”, es decir , no cambia su cont enido por nada del mundo. Per o ¿cómo
ent onces hacer cosas más “dinámicas”?.

Ser vidor Client e
Pag
HTML Pag
HTML
Navegador
de
I nt er net
Ser vicio de
Publicación
HTTP
Solicit ud de Página Web
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

280
Como r espuest a a esa pr egunt a, exist e algo que se llama DHTML (Dynamic HTML) que
básicament e mezcla lo que es HTML est át ico y algo de J avascr ipt (¡¡hey, no es J ava!!). Si ves
en una página bot ones que cambian de color es, algunas sor pr esas, vent anas y cosas más
llamat ivas aún, ést as se pueden hacer con DHTML.

Sin embar go, el DHTML, al igual que el HTML, son int er pr et ados en el lado del client e. ¿Qué
pasa si en el ser vidor t uvier a una Base de Dat os y quier o leer su inf or mación?. Pues, debemos
r ecor dar que el web ser ver es un f loj o y solo envía t ext o, por lo que nunca vamos a saber cómo
leer la base de dat os o qué inf or mación posea. A menos que...
Concept o
Un Ser vlet es un pr ogr ama que r eside en el ser vidor y que r esponde a
llamadas usando URL (igual que las páginas web) en lenguaj e HTML,
per o cuya r espuest a est á dada por la lógica del pr ogr ama.

Los Ser vlet s son pr ogr amas básicament e hechos en J ava. La dif er encia con los pr ogr amas
est ándar que hast a ahor a conocemos es que se impr ime dir ect ament e en el Socket par a que el
navegador capt ur e el HTML que nosot r os enviamos.

De est a f or ma el compor t amient o se ve algo dist int o ahor a:











El Ser vlet t ambién r eside en un ser vicio de publicación, per o la ej ecución gener a HTML
dependiendo del llamado que se haga del Ser vlet y la comunicación que mant enga el client e con
él.

Veamos r ealment e cómo f unciona est o:
Sint axi s
La anat omía de un Ser vlet no se alej a mucho de los pr ogr amas t r adicionales. Solo es necesar io
conocer algunos element os que se usan ella:

La Clase Ht t pSer vlet es la super clase de los Ser vlet s de t ipo HTTP (que r esponden usando
est e pr ot ocolo) y su def inición es la siguient e
35
:

35
Sacado de la API de Ser vlet s en ht t p:/ / j ava.sun.com/ pr oduct s/ ser vlet / 2.2/ j avadoc/
Ser vidor
Client e
Ot r os
Ar chivos
HTML
Generado
Navegador
de
I nt er net
Ser vicio de
Publicación
HTTP
Llamada al Ser vlet
BD
Pag o
Doc
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

281

Mét odo Descr ipción
Ht t pSer vlet () Does not hing, because t his is an abst r act class.
pr ot ect ed void doDelet e(Ht t pSer vlet Request r eq,
Ht t pSer vlet Response r esp)
Called by t he ser ver (via t he ser vice met hod) t o allow a ser vlet
t o handle a DELETE r equest .
pr ot ect ed void doGet (Ht t pSer vlet Request r eq,
Ht t pSer vlet Response r esp)
Called by t he ser ver (via t he ser vice met hod) t o allow a ser vlet
t o handle a GET r equest .
pr ot ect ed void doOpt ions(Ht t pSer vlet Request r eq,
Ht t pSer vlet Response r esp)
Called by t he ser ver (via t he ser vice met hod) t o allow a ser vlet
t o handle a OPTI ONS r equest .
pr ot ect ed void doPost (Ht t pSer vlet Request r eq,
Ht t pSer vlet Response r esp)
Called by t he ser ver (via t he ser vice met hod) t o allow a ser vlet
t o handle a POST r equest .
pr ot ect ed void doPut (Ht t pSer vlet Request r eq,
Ht t pSer vlet Response r esp)
Called by t he ser ver (via t he ser vice met hod) t o allow a ser vlet
t o handle a PUT r equest .
pr ot ect ed void doTr ace(Ht t pSer vlet Request r eq,
Ht t pSer vlet Response r esp)
Called by t he ser ver (via t he ser vice met hod) t o allow a ser vlet
t o handle a TRACE r equest .
pr ot ect ed long get Last Modif ied(
Ht t pSer vlet Request r eq)
Ret ur ns t he t ime t he Ht t pSer vlet Request obj ect was last
modif ied, in milliseconds since midnight J anuar y 1, 1970 GMT.
pr ot ect ed void ser vice(Ht t pSer vlet Request r eq,
Ht t pSer vlet Response r esp)
Receives st andar d HTTP r equest s f r om t he public ser vice
met hod and dispat ches t hem t o t he doXXX met hods def ined in
t his class.
void ser vice(Ser vlet Request r eq,
Ser vlet Response r es)
Dispat ches client r equest s t o t he pr ot ect ed ser vice met hod.

Est a clase no sir ve de mucho t al cuál est á, ya que es una clase abst r act a y debe ser ext endida
por el ser vlet que uno quier e const r uir . Según est a def inición, podemos mir ar un ser vlet
sencillo par a analizar lo:

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class MiPrimerServlet extends HttpServlet {
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
res.setContentType(”text/html¨);
PrintWriter out = res.getWriter();
out.println(”Hola Mundo¨);
out.close();
}
}

Est e ser vlet pone en la vent ana del br owser la si guient e salida:


Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

282
Per o ¿cómo lo hace?. Bueno, veamos cómo est e código queda “publicado”, ya que podemos ver la
par t e de pr ogr amación per o no la par t e más “administ r at iva”.

Pr imer o que t odo, par a publicar un ser vlet es necesar io t ener un ser vidor de publicación
t ambién conocido como Ser vidor de Aplicaciones que sopor t e Ser vlet s por supuest o. Uno
simple y que pueden descar gar en f or ma gr at uít a es el Tomcat (ht t p:/ / j akar t a.t omcat .or g) y
es bast ant e bueno par a hacer pr uebas.

El Tomcat posee una est r uct ur a de dir ect or ios bast ant e amplia, sin embar go lo impor t ant e se
encuent r a en la car pet a webapps. Dent r o de est a car pet a se encuent r an los “pr oyect os” en los
cuales uno puede t r abaj ar . Ent onces, una vez inst alado, podemos poner nuest r o ar chivo .class
en el dir ect or io webapps/ examples/ WEB-I NF/ classes.

Con est o, ya est ar ía publicado, por lo que solo debemos llamar a la dir ección:

ht t p:/ / localhost :8080/ examples/ ser vlet / MiPr imer Ser vlet

¡Y list o! ¡Funciona!

Ahor a analicemos nuest r o ser vlet par a que ent endamos más cómo est á const r uído.

• Es necesar io usar clases de los packages j avax. ser vlet y j avax. ser vlet . ht t p: Las
clases que se ut ilizan par a usar ser vlet s est án en uno paquet es de clases especiales,
que son descar gables de ht t p:/ / j ava.sun.com/ pr oduct s/ ser vlet / . En est a di r ección se
encuent r a t ant o las clases como la document ación de la misma.

• Par a const r uir un ser vlet es necesar io ext ender de la clase Ht t pSer vlet : Est a clase
per mit e el f uncionamient o de los ser vlet en un ser vidor de aplicaciones.

• El Ser vlet r ecibe desde el Client e inf or mación: Par a ello ut iliza las int er f ace
Ht t pSer vlet Request . Est a clase posee los siguient es mét odos:

Mét odo Descr ipción
St r ing get Aut hType() Ret ur ns t he name of t he aut hent icat ion scheme used t o pr ot ect t he
ser vlet , f or example, "BASI C" or "SSL," or null if t he ser vlet was not
pr ot ect ed.
St r ing get Cont ext Pat h() Ret ur ns t he por t ion of t he r equest URI t hat indicat es t he cont ext of
t he r equest .
Cookie[ ] get Cookies() Ret ur ns an ar r ay cont aining all of t he Cookie obj ect s t he client sent
wit h t his r equest .
long get Dat eHeader (St r ing name) Ret ur ns t he value of t he specif ied r equest header as a long value t hat
r epr esent s a Dat e obj ect .
St r ing get Header (St r ing name) Ret ur ns t he value of t he specif ied r equest header as a St r ing.
Enumer at ion get Header Names() Ret ur ns an enumer at ion of all t he header names t his r equest cont ains.
Enumer at ion get Header s(St r ing name) Ret ur ns all t he values of t he specif ied r equest header as an
Enumer at ion of St r ing obj ect s.
int get I nt Header (St r ing name) Ret ur ns t he value of t he specif ied r equest header as an int .
St r ing get Met hod() Ret ur ns t he name of t he HTTP met hod wit h which t his r equest was
made, f or example, GET, POST, or PUT.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

283
Mét odo Descr ipción
St r ing get Pat hI nf o() Ret ur ns any ext r a pat h inf or mat ion associat ed wit h t he URL t he client
sent when it made t his r equest .
St r ing get Pat hTr anslat ed() Ret ur ns any ext r a pat h inf or mat ion af t er t he ser vlet name but bef or e
t he quer y st r ing, and t r anslat es it t o a r eal pat h.
St r ing get Quer ySt r ing() Ret ur ns t he quer y st r ing t hat is cont ained in t he r equest URL af t er t he
pat h.
St r ing get Remot eUser () Ret ur ns t he login of t he user making t his r equest , if t he user has been
aut hent icat ed, or null if t he user has not been aut hent icat ed.
St r ing get Request edSessionI d() Ret ur ns t he session I D specif ied by t he client .
St r ing get Request URI () Ret ur ns t he par t of t his r equest ' s URL f r om t he pr ot ocol name up t o
t he quer y st r ing in t he f ir st line of t he HTTPr equest .
St r ing get Ser vlet Pat h() Ret ur ns t he par t of t his r equest ' s URL t hat calls t he ser vlet .
Ht t pSession get Session() Ret ur ns t he cur r ent session associat ed wit h t his r equest , or if t he
r equest does not have a session, cr eat es one.
Ht t pSession get Session(boolean cr eat e) Ret ur ns t he cur r ent Ht t pSession associat ed wit h t his r equest or , if if
t her e is no cur r ent session and cr eat e is t r ue, r et ur ns a new session.
j ava.secur it y.Pr incipal get User Pr incipal() Ret ur ns a j ava.secur it y.Pr incipal obj ect cont aining t he name of t he
cur r ent aut hent icat ed user .
boolean isRequest edSessionI dFr omCookie() Checks whet her t he r equest ed session I D came in as a cookie.
boolean isRequest edSessionI dFr omURL() Checks whet her t he r equest ed session I D came in as par t of t he
r equest URL.
boolean isRequest edSessionI dValid() Checks whet her t he r equest ed session I D is st ill valid.
boolean isUser I nRole(St r ing r ole) Ret ur ns a boolean indicat ing whet her t he aut hent icat ed user is included
in t he specif ied logical "r ole".

Y los mét odos que her eda desde la int er f ace Ser vlet Request :

Mét odo Descr ipción
Obj ect get At t r ibut e(St r ing name) Ret ur ns t he value of t he named at t r ibut e as an Obj ect , or null if no
at t r ibut e of t he given name exist s.
Enumer at ion get At t r ibut eNames() Ret ur ns an Enumer at ion cont aining t he names of t he at t r ibut es
available t o t his r equest .
St r ing get Char act er Encoding() Ret ur ns t he name of t he char act er encoding used in t he body of t his
r equest .
int get Cont ent Lengt h() Ret ur ns t he lengt h, in byt es, of t he r equest body and made available by
t he input st r eam, or -1 if t he lengt h is not known.
St r ing get Cont ent Type() Ret ur ns t he MI ME t ype of t he body of t he r equest , or null if t he t ype
is not known.
Ser vlet I nput St r eam get I nput St r eam() Ret r ieves t he body of t he r equest as binar y dat a using a
Ser vlet I nput St r eam.
Locale get Locale() Ret ur ns t he pr ef er r ed Locale t hat t he client will accept cont ent in,
based on t he Accept -Language header .
Enumer at ion get Locales() Ret ur ns an Enumer at ion of Locale obj ect s indicat ing, in decr easing
or der st ar t ing wit h t he pr ef er r ed locale, t he locales t hat ar e
accept able t o t he client based on t he Accept -Language header .
St r ing get Par amet er (St r ing name) Ret ur ns t he value of a r equest par amet er as a St r ing, or null if t he
par amet er does not exist .
Enumer at ion get Par amet er Names() Ret ur ns an Enumer at ion of St r ing obj ect s cont aining t he names of t he
par amet er s cont ained in t his r equest .
St r ing[ ] get Par amet er Values(St r ing name) Ret ur ns an ar r ay of St r ing obj ect s cont aining all of t he values t he given
r equest par amet er has, or null if t he par amet er does not exist .
St r ing get Pr ot ocol() Ret ur ns t he name and ver sion of t he pr ot ocol t he r equest uses in t he
f or m pr ot ocol/ maj or Ver sion.minor Ver sion, f or example, HTTP/ 1.1.
Buf f er edReader get Reader () Ret r ieves t he body of t he r equest as char act er dat a using a
Buf f er edReader .
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

284
Mét odo Descr ipción
St r ing get Remot eAddr () Ret ur ns t he I nt er net Pr ot ocol (I P) addr ess of t he client t hat sent t he
r equest .
St r ing get Remot eHost () Ret ur ns t he f ully qualif ied name of t he client t hat sent t he r equest , or
t he I Paddr ess of t he client if t he name cannot be det er mined.
Request Dispat cher get Request Dispat cher (
St r ing pat h)
Ret ur ns a Request Dispat cher obj ect t hat act s as a wr apper f or t he
r esour ce locat ed at t he given pat h.
St r ing get Scheme() Ret ur ns t he name of t he scheme used t o make t his r equest , f or
example, ht t p, ht t ps, or f t p.
St r ing get Ser ver Name() Ret ur ns t he host name of t he ser ver t hat r eceived t he r equest .
int get Ser ver Por t () Ret ur ns t he por t number on which t his r equest was r eceived.
boolean isSecur e() Ret ur ns a boolean indicat ing whet her t his r equest was made using a
secur e channel, such as HTTPS.
void r emoveAt t r ibut e(St r ing name) Removes an at t r ibut e f r om t his r equest .
void set At t r ibut e(St r ing name, Obj ect o) St or es an at t r ibut e in t his r equest .

De est a f or ma, se pueden obt ener muchas cosas del cl ient e y que puedan ser vir al
Ser vlet . Además, si se desea obt ener una par t e del Header , se t ienen algunas
var iables:

Accept :
Accept -Char set :
Accept -Encoding:
Accept -Language:
Aut hor izat ion:
Host :
Ref er er :
Cookie:
Connect ion:

• El Ser vlet envía al Client e i nf or mación: Par a ello ut iliza las int er f ace
Ht t pSer vlet Response como canal de comunicación. Est a clase posee los siguient es
mét odos:

Mét odo Descr ipción
void addCookie(Cookie cookie) Adds t he specif ied cookie t o t he r esponse.
void addDat eHeader (St r ing name, long dat e) Adds a r esponse header wit h t he given name and dat e-value.
void addHeader (St r ing name, St r ing value) Adds a r esponse header wit h t he given name and value.
void addI nt Header (St r ing name, int value) Adds a r esponse header wit h t he given name and int eger value.
boolean cont ainsHeader (St r ing name) Ret ur ns a boolean indicat ing whet her t he named r esponse header has
alr eady been set .
St r ing encodeRedir ect URL(St r ing ur l) Encodes t he specif ied URL f or use in t he sendRedir ect met hod or , if
encoding is not needed, r et ur ns t he URL unchanged.
St r ing encodeURL(St r ing ur l) Encodes t he specif ied URL by including t he session I D in it , or , if
encoding is not needed, r et ur ns t he URL unchanged.
void sendEr r or (int sc) Sends an er r or r esponse t o t he client using t he specif ied st at us.
void sendEr r or (int sc, St r ing msg) Sends an er r or r esponse t o t he client using t he specif ied st at us code
and descr ipt ive message.
void sendRedir ect (St r ing locat ion) Sends a t empor ar y r edir ect r esponse t o t he client using t he specif ied
r edir ect locat ion URL.
void set Dat eHeader (St r ing name, long dat e) Set s a r esponse header wit h t he given name and dat e-value.
void set Header (St r ing name, St r ing value) Set s a r esponse header wit h t he given name and value.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

285
Mét odo Descr ipción
void set I nt Header (St r ing name, int value) Set s a r esponse header wit h t he given name and int eger value.
void set St at us(int sc) Set s t he st at us code f or t his r esponse.

Y los mét odos que her eda desde la int er f ace Ser vlet Response:

Mét odo Descr ipción
void f lushBuf f er () For ces any cont ent in t he buf f er t o be wr it t en t o t he client .
int get Buf f er Size() Ret ur ns t he act ual buf f er size used f or t he r esponse.
St r ing get Char act er Encoding() Ret ur ns t he name of t he char set used f or t he MI ME body sent in t his
r esponse.
Locale get Locale() Ret ur ns t he locale assigned t o t he r esponse.
Ser vlet Out put St r eam get Out put St r eam() Ret ur ns a Ser vlet Out put St r eam suit able f or wr it ing binar y dat a in t he
r esponse.
Pr int Wr it er get Wr it er () Ret ur ns a Pr int Wr it er obj ect t hat can send char act er t ext t o t he
client .
boolean isCommit t ed() Ret ur ns a boolean indicat ing if t he r esponse has been commit t ed.
void r eset () Clear s any dat a t hat exist s in t he buf f er as well as t he st at us code and
header s.
void set Buf f er Size(int size) Set s t he pr ef er r ed buf f er size f or t he body of t he r esponse.
void set Cont ent Lengt h(int len) Set s t he lengt h of t he cont ent body in t he r esponse I n HTTPser vlet s,
t his met hod set s t he HTTPCont ent -Lengt h header .
void set Cont ent Type(j St r ing t ype) Set s t he cont ent t ype of t he r esponse being sent t o t he client .
void set Locale(Locale loc) Set s t he locale of t he r esponse, set t ing t he header s (including t he
Cont ent -Type' s char set ) as appr opr iat e.

De est a f or ma, se pueden enviar muchas cosas del client e y que puedan ser vi r . Además,
si se desea enviar algo en el Header , se t ienen algunas var iables:

Cont ent -Type:
Cont ent -Lengt h:
Cont ent -Encoding:
Cont ent -Language:
Connect ion:
Cache:
Ref r esh:
www-Aut hent icat e:

• El Ser vlet Responde a los Mét odos GET y POST: Dependiendo del mét odo de
llamada (r equest ), el ser vlet lo discr imina con dos mét odos doGet y doPost , los cuales
r eciben el canal de comunicación de lect ur a (Request ) del client e y de escr it ur a
(Response) al mismo.

• Es necesar io decir le el t ipo de salida: Al moment o de pr epar ar la salida, es necesar io
indicar le qué t ipo de salida es. En est e caso usar emos “t ext / ht ml” en el
r esp.set Cont ent Type().

• La salida debe ser escr it a en un St r eam: Par a poder enviar inf or mación al client e se
usa un St r eam de salida, que se obt iene con el r esponse y el mét odo get Wr it er de ese
obj et o. La escr it ur a es como en cualquier ot r o st r eam.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

286

De est a f or ma, podemos coment ar nuest r o ser vlet “hola mundo” explicando qué hace cada línea
e inst r ucción:

// Importación de los paquetes de clases de Servlets
import javax.servlet.*;
import javax.servlet.http.*;

// Importación del paquete de entrada y salida
import java.io.*;

// Clase extendiendo de HttpServlet
public class MiPrimerServlet extends HttpServlet {

// Método de retorno de información a un método GET
// Recibe ambos parámetros de entrada y salida
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {

// Se setea el tipo de contenido de salida a HTML
res.setContentType(”text/html¨);

// Se obtiene el dispositivo de salida
PrintWriter out = res.getWriter();

// Se escribe en el dispositivo de salida (cliente)
out.println(”Hola Mundo¨);

// Se cierra el dispositivo de salida
out.close();
}
}
Concept o
Una Cookie es un obj et o que se almacena en el t er minal del client e y que
nos per mit e guar dar cier t a inf or mación par t icular .

La inf or mación de una cookie nor malment e es solo t ext o y se almacena en un dir ect or io en el
comput ador client e. Las cookies son manej adas nor malment e por el br owser del client e, por lo
que si el client e decide eliminar las cookies puede hacer lo, y el ser vlet no t iene cont r ol dir ect o
sobr e ellas.

Aún cuando las cookies ent onces son un medio t an volát il, es una muy buena f or ma de hacer le
seguimient o al client e, de hecho cada vez que un sit io es cont act ado por el client e, ést e le
envía aut omát icament e t odas sus cookies.

Las cookies son simples par es de st r ings que se guar dan. Por ej emplo, la cookie “f echa” puede
almacenar “15 de Noviembr e de 2003”.
Sint axi s
Las cookies son simples par es de St r ings. De t odas f or mas, en J ava t ienen una r epr esent ación
clar a ut ilizando la clase Cookie:
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

287

Mét odo Descr ipción
Cookie(St r ing name, St r ing value) Const r uct s a cookie wit h a specif ied name and value.
Obj ect clone() Over r ides t he st andar d j ava.lang.Obj ect .clone met hod t o r et ur n a copy
of t his cookie.
St r ing get Comment () Ret ur ns t he comment descr ibing t he pur pose of t his cookie, or null if
t he cookie has no comment .
St r ing get Domain() Ret ur ns t he domain name set f or t his cookie.
int get MaxAge() Ret ur ns t he maximum age of t he cookie, specif ied in seconds, By
def ault , -1 indicat ing t he cookie will per sist unt il br owser shut down.
St r ing get Name() Ret ur ns t he name of t he cookie.
St r ing get Pat h() Ret urns t he pat h on t he ser ver t o which t he br owser r et ur ns t his
cookie.
boolean get Secur e() Ret ur ns t r ue if t he br owser is sending cookies only over a secur e
pr ot ocol, or f alse if t he br owser can send cookies using any pr ot ocol.
St r ing get Value() Ret ur ns t he value of t he cookie.
int get Ver sion() Ret ur ns t he ver sion of t he pr ot ocol t his cookie complies wit h.
void set Comment (St r ing pur pose) Specif ies a comment t hat descr ibes a cookie' s pur pose.
void set Domain(St r ing pat t er n) Specif ies t he domain wit hin which t his cookie should be pr esent ed.
void set MaxAge(int expir y) Set s t he maximum age of t he cookie in seconds.
void set Pat h(St r ing ur i) Specif ies a pat h f or t he cookie t o which t he client should r et ur n t he
cookie.
void set Secur e(boolean f lag) I ndicat es t o t he br owser whet her t he cookie should only be sent using
a secur e pr ot ocol, such as HTTPS or SSL.
void set Value(St r ing newValue) Assigns a new value t o a cookie af t er t he cookie is cr eat ed.
void set Ver sion(int v) Set s t he ver sion of t he cookie pr ot ocol t his cookie complies wit h.

De est a f or ma, cr ear una Cookie es muy sencillo. La cr eación de ella se r ealiza cr eando un
obj et o cookie:


Cookie c = new Cookie(”miPrimeraCookie¨, ”Esta es una cookie¨);


Y luego es necesar io enviar la al client e par a que se r egist r e:


res.addCookie(c); // Recuerda: res es de tipo HttpServletResponse


Y ahor a el client e posee una cookie llamada miPr imer aCookie.

Al obt ener la se nos hace solo un poquit o más dif icil, ya que las cookies vienen t odas j unt as. De
est a f or ma, si quer emos obt ener la misma cookie desde el ser vidor , deber emos hacer lo
siguient e:

Cookie[] cs = req.getCookies(); // req es un HttpServletRequest
for (int i=0; i<cs.length; i++) {
if (cs[i].getName().equals(”miPrimeraCookie¨)) {
System.out.println(cs[i].getValue());
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

288
Est e código, ent onces, r et or na el cont enido de la cookie “miPr imer aCookie” en la salida
est ándar .

Veamos ahor a un par de ej emplos de cookies.

Pr imer o que nada, veamos un ser vlet que solo se pr eocupe de most r ar t odas las cooki es que
posee el usuar io en su comput ador , par a “espiar ” lo que posee:

import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;

public class MisCookies extends HttpServlet {
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
Cookie[] cs = req.getCookies();
for (int i=0; i<cs.length; i++) {
out.print("<LI><B>");
out.print(cs[i].getName());
out.print("</B>: ");
out.print(cs[i].getValue());
out.print("</LI>");
out.println();
}
out.close();
}
}

Est e ser vlet lo que hace es impr imir t odas las cookies que envía el client e en el r eques r eq y las
pones con el f or mat o:

• Nombr e: Valor

Por lo que logr amos ver , es simple ut ilizar las, per o nuevament e debemos r ecor dar que las
cookies son un espacio volát il de inf or mación que el usuar io puede bor r ar o impedir en su
conf igur ación per sonalizada.
Concept o
La Session es un obj et o que se almacena en el ser vidor y que guar da
inf or mación que exist e dur ant e el int er cambio que hay ent r e un client e
y un ser vidor .

A dif er encia de una cookie, la sesión solo dur a desde el moment o en que el client e se cont act a
una vez con el ser vidor , hast a que ha pasado un t iempo de inact ividad. Gener alment e el t iempo
de inact ividad se ext iende dur ant e los siguient es 30 minut os desde que el client e no se ha
vuelt o a comunicar con el ser vidor de ninguna f or ma. Una vez que ha pasado est e t iempo de
t imeout , la sesión dej a de exist ir en el ser vidor .

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

289
La sesión no es manej ada ni por el client e ni t ampoco por el ser vlet , si no que exist e SI EMPRE
en el ser vidor web, y el ser vlet puede ut ilizar la par a almacenar y obt ener inf or mación de ella.
Sint axi s
Al igual que las cookies, la sesión se obt iene del r equest del usuar io (o en r ealidad, se obt iene a
par t ir de la inf or mación que t r ae el r equest ). De est a f or ma, y usando la int er f az Ht t pSession
podemos obt ener la sesión act ual del usuar io con:


HttpSession sesion = request.getSession(true);


Con est a línea, cr eamos un obj et o sesion que r epr esent a la sesión del client e en el ser vidor
web. Veamos más mét odos que podemos ut ilizar con Ht t pSession:

Mét odo Descr ipción
Obj ect get At t r ibut e(St r ing name) Ret ur ns t he obj ect bound wit h t he specif ied name in t his session, or
null if no obj ect is bound under t he name.
Enumer at ion get At t r ibut eNames() Ret ur ns an Enumer at ion of St r ing obj ect s cont aining t he names of all
t he obj ect s bound t o t his session.
long get Cr eat ionTime() Ret ur ns t he t ime when t his session was cr eat ed, measur ed in
milliseconds since midnight J anuar y 1, 1970 GMT.
St r ing get I d() Ret ur ns a st r ing cont aining t he unique ident if ier assigned t o t his
session.
long get Last AccessedTime() Ret ur ns t he last t ime t he client sent a r equest associat ed wit h t his
session, as t he number of milliseconds since midnight J anuar y 1, 1970
GMT.
int get MaxI nact iveI nt er val() Ret ur ns t he maximum t ime int er val, in seconds, t hat t he ser vlet
cont ainer will keep t his session open bet ween client accesses.
void invalidat e() I nvalidat es t his session and unbinds any obj ect s bound t o it .
boolean isNew() Ret ur ns t r ue if t he client does not yet know about t he session or if t he
client chooses not t o j oin t he session.
void r emoveAt t r ibut e(St r ing name) Removes t he obj ect bound wit h t he specif ied name f r om t his session.
void set At t r ibut e(St r ing name,
Obj ect value)
Binds an obj ect t o t his session, using t he name specif ied.
void set MaxI nact iveI nt er val(int int er val) Specif ies t he t ime, in seconds, bet ween client r equest s bef or e t he
ser vlet cont ainer will invalidat e t his session.

La vent aj a que t iene una sesión con r espect o a una cookie salt a a la vist a al ver los mét odos de
la int er f az Ht t pSession, pues se pueden almacenar obj et os en vez de solo st r ings. De est a
f or ma podemos pasar inf or mación dur ant e la conexión que nos puede ser vir de muchas f or mas.

Veamos un ej emplo simple que obt iene inf or mación dir ect ament e de la Session que el usuar io
cr ea y que se mant iene dur ant e la conexión:

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SessionExample extends HttpServlet {

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXII: InternetWorking

290
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();

HttpSession session = request.getSession(true);

// print session info

Date created = new Date(session.getCreationTime());
Date accessed =
new Date(session.getLastAccessedTime());
out.println("ID " + session.getId());
out.println("Created: " + created);
out.println("Last Accessed: " + accessed);

// set session info if needed

String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue =
request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}

// print session contents

Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value =
session.getAttribute(name).toString();
out.println(name + " = " + value);
}
}
}

Una salida válida de est e ser vlet ser ía:

ID 7D09C750A21350C64A6D388D44048A90
Created: Sun Nov 16 05:22:16 GMT 2003
Last Accessed: Sun Nov 16 05:22:16 GMT 2003

¿Cuándo usar Cookies o Sessions?

La r espuest a es complej a, per o simple a la vez, ya que se pueden ut ilizar ambas a gust o, per o
siempr e t eniendo en cuent a l as siguient es consider aciones gener ales:

• Una Session se cr ea en el ser vidor . Una cookie se cr ea en el caché del usuar io.
• Una Session exist e mient r as se mant ena una conexión del usuar io. Una Cookie exist e
mient r as el usuar io no la bor r e de su caché.
• Una Session se mant iene local al ser vlet en ej ecución. Una cookie viaj a a t r avés de la
r ed cada vez que es cont act ado el client e.
• Una Session puede guar dar un Obj ect . Una cookie solo guar da St r ing.
• Una Session siempr e se cr ea. Una Cookie puede ser bloqueada par a impedir su cr eación.

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIII: Paquetes de Clases

291
Capít ulo XXI I I : Paquet es de Clases
Mot ivaci ón
¿Alguna vez t e pr egunt as qué er a esos j ava.awt .* o j ava.io.* que el pr of e ponía en los impor t s
de las clases? Pues siempr e se decía que los impor t lo que hacían er a impor t ar bibliot ecas de
clases que per t enecían a J ava pr opiament e t al.

Descubr ir emos en velo de la duda ahor a indicando cómo se cr ean esas bibliot ecas y cómo se
usan.
Concept os
Bilbiot eca o Paquet e
Conj unt o de clases agr upadas por una t emát ica def inida y que pueden
ser r eut ilizadas en cualquier pr ogr ama.

Est a def inición t an sencilla puede ser una her r amient a pot ent ísima si conocemos cuál es la
est r uct ur a que per mit e cr ear bilbiot ecas o paquet es. Vamos a la par t e sint áct ica r ápidament e
par a que podamos apr ender est o de una vez por t odas.
Sint axis
Un paquet e de clases en j ava es llamado Package. Est as est r uct ur as son simples dir ect or ios, a
par t ir del CLASSPATH, que cont ienen las clases.

Por ej emplo, si t enemos las clases mat emát icas en el dir ect or io C: \ Bibl\ cc10a\ mat emat ica y
nuest r o CLASSPATH est á def inido como C: \ Bibl, ent onces, las clases mat emát icas que
est amos ut ilizando se encuent r an en el package cc10a. mat emat ica.

A pesar de est o, no es t an sencillo llegar y ut ilizar est o como un pr et ext o de or den, sino que se
debe indicar dent r o de la clase a cuál bibliot eca cor r esponde.

Veamos ahor a cada uno de los t emas r elevant es de los packages.
Def inir un Package
Ant es de comenzar a ut ilizar un package, es necesar io def inir lo, es decir , especif icar donde va
a est ar ese package almacenado. Tenemos var ias alt er nat ivas:

(a) Def inir el package en el dir ect or io lib de mi J DK, es decir , por ej emplo en el dir ect or io
C: \ j dk1. 2\ lib.

La vent aj a de est a opción es que no t enemos que incluir ningún dir ect or io adicional en el
CLASSPATH, ni t ampoco t ener def inido un dir ect or io home par a ej ecut ar mis clases.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIII: Paquetes de Clases

292
Además de est a f or ma, dej amos la bibliot eca disponible par a cualquier desar r ollo que se
nos ocur r a (más genér ico).

Por ej emplo, def inamos la bibliot eca mat emát ica:

C:\> cd \jdk1.2\lib
C:\jdk1.2\lib\> cd cc10a // HOME de bibliotecas
CC10A
36

C:\jdk1.2\lib\cc10a\> mkdir matematica // Biblioteca matemática
C:\jdk1.2\lib\cc10a\> cd matematica
C:\jdk1.2\lib\cc10a\matematica\> _

(b) Def inir el package en un dir ect or io que si est é en el CLASSPATH o que agr eguemos al
CLASSPATH como home de mis bibliot ecas, por ej emplo, C: \ j avaBibl.

Al igual que en el ant er ior caso, la vent aj a que t iene de separ ar las es que cuando quer emos
r eut ilizar las, las podemos t ener accesibles siempr e, sin f ij ar nuest r o dir ect or io de
ej ecución de clases, sin embar go, posee la f acult ad de que si cambiamos o r einst alamos el
J DK, no es necesar io r espaldar la bilbiot eca.

Por ej emplo, def inamos las bibliot ecas en nuest r o PC:

C:\> cd javaBibl // HOME de bibliotecas CC10A
C:\javaBibl\> mkdir matematica // Biblioteca matemática
C:\javaBibl\> cd matematica
C:\javaBibl\matematica\> _

¡Se par ece a lo ant er ior ! Per o como decíamos, est o no depende del j dk como lo ant er ior .
Est o nos llevar ía a def inir adicionalment e algo en nuest r o CLASSPATH. Veamos:

C:\> set CLASSPATH // Verificamos qué tiene el CLASSPATH
CLASSPATH=.;C:\jdk1.2\lib
C:\> set CLASSPATH=%CLASSPATH%;C:\javaBibl

Como nos podemos dar cuent a, lo que est amos haciendo es simplement e agr egar al
CLASSPATH que ya exist e, la r ut a base de l a bibliot eca. Así usar emos t oooooda la
bilbiot eca ent er a y no es necesar io hacer lo por cada una de las bilbiot ecas que exist an.

(c) Def inir el package desde el dir ect or io home en el cual comienzo a ej ecut ar mis clases, por
ej emplo, C: \ CC10A.

A modo de or den, per sonalment e pienso que es la mej or opción. De est a f or ma t enemos un
dir ect or io de desar r ollo y desde allí mont amos t odos los pr ogr amas que quer amos. De est a
f or ma t r abaj amos sobr e un dir ect or io no más sin necesidad de set ar el CLASSPATH ni
pr eocupar nos del J DK que est emos ut ilizando.

36
Recuer da que si no exist e la bilbiot eca cc10a, es necesar io cr ear la ant es poniendo:

C:\jdk1.2\lib\> mkdir cc10a
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIII: Paquetes de Clases

293
Cr ear una Clase en un Package
Una vez def inido dónde guar dar emos la bilbiot eca, es necesar io empezar a desar r ollar clases
dent r o de ella. Par a ello se usa una sent encia que va al pr incipio de la clase (ant es que cualquier
cosa) y que indica a qué bibliot eca per t enece:

package <nombr e_bilbiot eca>

En donde el nombr e de la bilbiot eca es igual a los dir ect or ios desde la r aíz de la bilbiot eca en
donde se encont r ar á la clase, separ ados por punt os (".").

Supongamos como ej emplo l a bibliot eca mat emát ica, y def inamos la clase Complej o de la clase
mat emát ica.

package matematica;
public class Complejo {
public double parte_real;
public double parte_img;
public class Complejo (double r, double i) {
this.parte_real = r;
this.parte_img = i;
}
...
}

Fíj at e que la única dif er encia en la que incur r i mos es que pusimos el package al pr incipio. Si
quier es guar dar est a clase, debes hacer lo en un ar chivo complej o.j ava dent r o del dir ect or io
mat emat ica en el home de bibliot ecas.

Supongamos que quer emos guar da la bibliot eca ahor a como cc10a\ mat (es decir bibliot eca
mat emát ica de cc10a). Escr ibamos la clase:

package cc10a.mat;
public class Complejo {
public double parte_real;
public double parte_img;
public class Complejo (double r, double i) {
this.parte_real = r;
this.parte_img = i;
}
...
}

Y lo guar damos en el dir ect or io cc10a\ mat del home de bibliot ecas. ¿Sencillo?
Usar un Package
Par a ut ilizar un package o bibliot eca exist e algo que hemos vist o más de una vez y es el
comando impor t :

impor t <nombr e_package>. * ;

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIII: Paquetes de Clases

294
Est a es la f or ma genér ica y signif ica que impor t a TODAS las clases que est án def inidas como
públicas en el package, es decir , t enemos acceso a t odas las clases que est án def inidas dent r o
de la bibliot eca. Ot r o ej emplo de impor t es:

impor t <nombr e_package>. <nombr e_clase>;

En donde impor t a solo una clase específ ica del package, es decir , solo t endr emos acceso a ESA
clase de la bibliot eca.

Hagamos un pr ogr ama que sume 2 complej os:

import matematica.*; // importamos la biblioteca donde
// está la clase complejo
public class Programa {
public static void main(String[] args) {
Complejo a = new Complejo (1, 2);
Complejo b = new Complejo (2, 3);
Complejo ab = new Comlejo (a.parte_real + b.parte_real,
a.parte_img + b.parte_img);
}
}

En est e caso supusimos que la clase Complej o la guar damos en la bibliot eca mat emat ica.
Supongamos ahor a el segundo ej emplo, en la bibliot eca cc10a.mat :

import cc10a.mat.*; // importamos la biblioteca donde
// está la clase complejo
public class Programa {
public static void main(String[] args) {
Complejo a = new Complejo (1, 2);
Complejo b = new Complejo (2, 3);
Complejo ab = new Comlejo (a.parte_real + b.parte_real,
a.parte_img + b.parte_img);
}
}

Ambos casos son iguales, la dif er encia r adica en la bibliot eca. Per o ¿qué pasa si la bibliot eca
(cc10a.mat o mat emat ica, depende del caso) posee más clases que no ut ilizamos? Podemos usar
la segunda ver sión de impor t par a que impor t emos solo la clase út il:

import cc10a.mat.Complejo; // importamos la clase COMPLEJO
public class Programa {
public static void main(String[] args) {
Complejo a = new Complejo (1, 2);
Complejo b = new Complejo (2, 3);
Complejo ab = new Comlejo (a.parte_real + b.parte_real,
a.parte_img + b.parte_img);
}
}

Por supuest o exist e una t er cer a f or ma de usar la clase Complej o sin ut ilizar impor t y es
r ef er enciar la dir ect ament e desde su package. ¿Qué dif er encia hay? usas muchas veces el
mismo t ext o par a r ef er enciar la clase:
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIII: Paquetes de Clases

295

public class Programa {
public static void main(String[] args) {
cc10a.mat.Complejo a = new cc10a.mat.Complejo (1, 2);
cc10a.mat.Complejo b = new cc10a.mat.Complejo (2, 3);
cc10a.mat.Complejo ab = new cc10a.mat.Comlejo
(a.parte_real + b.parte_real,
a.parte_img + b.parte_img);
}
}

¿Peludo?
Compilar y Ej ecut ar una clase de un Package
Obviament e no t odo iba a ser sencillo, por que no es t an f acil ej ecut ar una clase. Comencemos
con la compilación.

Si la clase que nosot r os pr ogr amamos par a el package la guar damos en cc10a\ mat ent onces
deber emos met er nos en ese dir ect or io par a compilar lo, igual como si compilár amos cualquier
ot r a.

El pr oblema viene al moment o de ej ecut ar . Par a hacer ést o, debemos r ealizar lo desde la r aíz
de las bibliot ecas, es decir , desde el C:\ Bibl por ej emplo:

C:\Bibl\> java cc10a.mat.Complejo

Como podemos ver , par a llamar una clase de un package, debemos ant eponer le el nombr e del
package obviament e. Pues ese r ealment e es el nombr e.

En gener al no se ej ecut an esas clases, sino que uno cr ea sus pr opias clases que ut ilizan los
packages, o una clase pr incipal que cont r ola t odo el modelo de paquet es.
Pr oblema
Pongamos en pr áct ica lo que has apr endido. Tenemos def inida la siguient e clase:

import java.io.*;
public class ArchivoLectura {
private BufferedReader fd;
public ArchivoLectura (String nombre) {
try {
this.fd = new BufferedReader(
new FileReader(nombre));
}
catch (Exception e) {
}
}
public String leerLinea() {
try {
return this.fd.readLine();
}
catch (Exception e) {
return null;
}
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIII: Paquetes de Clases

296
}
public void cerrar() {
try {
this.fd.close();
}
catch (Exception e) {
}
}
}

(a) A par t ir del dir ect or io C:\ J ava\ CC10A cr ear la bibliot eca io.ar chivo.t ext o que per mit e
manipular ar chivos de t ext o.

R: Suponemos que est amos par ados en el dir ect or io J ava\ CC10A indicado y cr eamos la
car pet a io:

C:\Java\CC10A\> mkdir io
C:\Java\CC10A\> cd io
C:\Java\CC10A\io\> _

Cr eamos la car pet a ar chivo:

C:\Java\CC10A\io\> mkdir archivo
C:\Java\CC10A\io\> cd archivo
C:\Java\CC10A\io\archivo\> _

Y cr eamos la car pet a t ext o:

C:\Java\CC10A\io\archivo\> mkdir texto
C:\Java\CC10A\io\archivo\> cd texto
C:\Java\CC10A\io\archivo\texto\> _

Luego ver if icamos si la car pet a J ava\ CC10A est á en el CLASSPATH:

C:\Java\CC10A\io\archivo\texto\> set CLASSPATH

Si ese dir ect or io no est á, lo agr egamos al CLASSPATH:

C:\Java\CC10A\io\archivo\texto\> set CLASSPATH=%CLASSPATH%;C:\Java\C
C10A
C:\Java\CC10A\io\archivo\texto\> _

(b) I ndicar qué se debe hacer par a que la clase per t enezca a ese paquet e.

package io.archivo.texto;
import java.io.*;
public class ArchivoLectura {
...
}

Después de que est é escr it a la clase, se debe guar dar en el dir ect or io cr eado en la
par t e (a)

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIII: Paquetes de Clases

297
(c) Escr ibir un pr ogr ama que per mit a impr imir en la salida est ándar (Syst em.out ) t odo el
cont enido de un ar chivo ut ilizando la clase Ar chivoLect ur a.

import io.archivo.texto.*;
public class Programa {
public static void main (String[] args) {
ArchivoLectura al = new ArchivoLectura("xxx");
while (true) {
String linea = al.leerLinea();
if (linea == null) break;
System.out.println(linea);
}
al.cerrar();
}
}

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

298
Capít ulo XXI V: Diseño de Sof t war e UML
37

Mot ivaci ón
Hoy t e levant as de t u cama y t ienes un mail esper ando en t u comput ador a. Vas y t e das cuent a
que el Pr esident e t e encar ga r esolver un pr oblema que t e plant ea de la siguient e f or ma:

From: Ricardo Lagos
Subject: Proyecto de Software

Hola.

He sabido que los alumnos de CC10A tienen mucha fama en desarrollar
programas para cualquier tipo de problemas.

Necesitamos un software que nos permita modelar el comportamiento de
las leyes en el Congreso. Es decir, que vigile una ley desde que
esta se escribe por algún profesional hasta que es aceptada por las
Cámaras Alta y Baja y es promulgada tras mi firma.

Espero que puedan ayudar al paıs. Recibirán una gratificación si
realizan este programa.

Como ven, est e ext r año enunciado es muy abst r act o y no nos hablan de clases, obj et os,
var iables de inst ancia, mét odos, ni nada por el est ilo.

Ver emos algunas pr áct icas que nos pueden ayudar a “t r aducir ” el pr oblema de un usuar io a
especif icaciones de un sof t war e.
Concept o
Par a el desar r ollo de sof t war e no bast a conocer un lenguaj e de pr ogr amación y saber
pr ogr amar , sino que t ambién es necesar io compr ender las necesidades de un client e o las
especif icaciones de un pr oblema. Par a ello exist en met odologías de diseño de sof t war e:
Met odología
Est án pr ovist os de lenguaj es de modelamient o y pr ocesos de desar r ollo
que nos per mit en modelar un pr oblema y especif icar el pr oduct o f inal.

Exist en muchas met odologías que son ut ilizadas por los pr of esionales en la act ualidad. En est e
capít ulo nos enf ocar emos en la pr imer a par t e de la met odología que es el lenguaj e.
UML
La sigla UML signif ica Unif ied Modeling Language (lenguaj e unif icado de
modelamient o) y es la not ación, pr incipalment e gr áf ica, par a expr esar
diseños de sof t war e Or ient ados al Obj et o.

37
Toda est a mat er ia f ue sacada del libr o UML Got a a Got a (UML Dest illed) de Fowler y Scot t .
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

299

UML es el sucesor de la oleada de mét odos de análisis y diseño or ient ados a obj et o (OOA&D)
que sur gió a f ines de la década del 80 y pr incipios de los 90. Pr incipalment e unif ica los mét odos
de Booch, Rumbaugh (OMT) y J acobson
38
, per o su alcance es mucho más amplio.

Par a ent ender UML es muy impor t ant e ent ender Or ient ación al Obj et o (OO), y que J ava t iene
como base en su pr ogr amación. Se dice que un buen modelamient o hecho con UML puede ser
“t r aducido” f ácilment e en un sof t war e OO, en nuest r o caso hecho en J ava.

Las t écnicas de UML son:
Tar j et as CRC (Clase – Responsabi lidad – Colabor aci ón)
39

Of icialment e no per t enecen a UML, per o son muy valiosas par a apr ender OO. Or iginal ment e las
t ar j et as CRCf uer on diseñadas par a t r abaj ar con obj et os. El t ér mino “t ar j et as” f ue usado por
su car act er íst ica f ísica de ser t ar j et as de 6x4 pulgadas de t amaño:

Nombr e de la Clase
Responsabilidades Colabor ación
Responsabilidad 1
Responsabilidad 2
...
Clase 1
Clase 2
...

Las Clases er an r epr esent adas por cada una de las t ar j et as y son f ieles element os de modelo
que int er pr et an una ent idad en la vida r eal (dent r o del pr oblema).

Las Reposabilidades son la descr ipción de los pr opósit os de la clase (mét odos). El espacio er a
r educido, por lo que las descr ipciones er an muy escuet as en unas cuánt as f r ases (solo lo que
cabía dent r o de la t ar j et a).

Las Colabor aciones er an clases con las que se t r abaj aba par a cumplir el o los pr opósit os de la
clase (uso de obj et os).
Diagr amas de I nt er acción
Son muy út iles par a hacer explícit a la est r uct ur a de los mensaj es y, en consecuencia, t ienen la
vent aj a de r esalt ar los diseños demasiado cent r alizados, en los que un obj et o r ealiza t odo el
t r abaj o. Est os diagr amas pueden ser de 2 t ipos:

Los Diagr amas de Secuencia son diagr amas que especif ican el or den de llamadas y
pr ocesamient o de la inf or mación a t r avés de t odos los obj et os que per t enecen al sist ema. Es

38
Booch, Rumbaugh y J acobson son conocidos en el ámbit o de Sof t war e como “The Thr ee
Amigos” al igual que en esa película cómica ambient ada en México.
39
Ver ht t p:/ / www.c2.com/ doc/ oopsla89/ paper .ht ml. No hay muchas publicaciones al r espect o
y es una de las or iginales que aún exist e.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

300
bast ant e int uit ivo pasar de un diagr ama de secuencia a un pr ogr ama, pues sale casi línea a línea
que va r ealizando el mismo.

Los Diagr amas de Colabor ación son diagr amas que muest r an la comunicación ent r e las clases y
los obj et os que int er act úan en el sist ema.
Diagr amas de Clases
Son usados par a ilust r ar modelos de clases. Los modelos de clases son muy similar es a los
modelos de dat os (diagr amas de t ablas) que hemos vist o en el capít ulo ant er ior , por lo que
r esult an cómodos. El mayor pr oblema de est os modelos es que se t iende a or ient ar lo a los
dat os y no al obj et o (algo que hay que t ener mucho cuidado).
Diagr amas de Caso de Uso
Son diagr amas que muest r an la int er acción de los act or es (ent idades ext er nas) con dist int os
módulos o clases del sist ema. Es muy gr áf ico e int uit ivo, pues especif ica con poca not ación los
pr ocesos que el sof t war e debe seguir y son muy f áciles de int er pr et ar por el client e.
Concept o de Pat r ones
El empleo de pat r ones es vit al par a OO, pues hace cent r ar se en logr ar buenos diseños y
apr ender en base a ej emplos. Una vez que hayamos logr ado el domini o de algunas t écnicas par a
modelar , t ales como diagr amas de clases o de int er acción, ser á el moment o de ver los pat r ones.
Desar r ollo I t er at ivo I ncr ement al
Algo no t an despr eciable es ut ilizar la t écnica o pr oceso de desar r ollo adecuado. Con UML
viene de la mano el desar r ollo llamado I t er at ivo- I ncr ement al que t r at a de par t ir de una base
sencilla del pr oblema complet o y r esolver lo de maner a it er at iva, es decir , con ciclos cor t os
dent r o de los cuales se vayan solucionando los sub-pr oblemas más impor t ant es hast a t ener al
f inal el desar r ollo complet o del pr oblema que el client e plant ea.

Es así como par a r ealizar un sof t war e, no es t an sencillo como sent ar se f r ent e al comput ador y
pr ogr amar . Ahor a, hagamos un alt o y comencemos viendo cómo es el pr oceso de desar r ollo paso
a paso y la sint axis que el lenguaj e UML pr ovee par a el desar r ollo de est e pr oceso ut ilizado por
los ingenier os en la act ualidad.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

301
Pr oceso de Desar r ollo
La t écnica del Desar r ollo I t er at ivo- I ncr ement al es la clave par a explot ar la OO.


Concepci ón Elabor ación Const r ucción Tr ansacción


Se divide en 4 et apas de desar r ollo:

La Concepción es la pr imer a et apa, la cual per mit e ver el pr oblema en su punt o de vist a global.
Es cr ucial que el equipo de desar r ollo ent ienda la impor t ancia de ent ender y compr ender las
necesidades del client e o los punt os más r elevant es del pr oblema y aclar ar la nebulosa que
siempr e t iene el client e como idea de pr oduct o.

La Elabor ación es la segunda et apa. En ella se r ealiza la mayor especif icación de
r equer imient os del sof t war e que se desea const r uir . El cont act o con el client e es cr ucial en
est a et apa, por que es quien r ealiza las obser vaciones necesar ias par a que se aj ust e a sus
necesidades. La ut ilización de diagr amas y UML en la especif icación de r equer imient os es muy
impor t ant e, pues los diagr amas dej a mucho más clar os t ant o a los client es (Casos de Uso) como
a los codif icador es (Diagr amas de Clases y Secuencia).

La Const r ucción es la t er cer a y más f uer t e et apa. En ella se desar r ollan la mayor par t e de los
r equer imient os especif icados y se complement an con las obser vaciones del client e. La mayor
par t e del t iempo empleado en est a et apa se gast a en la codif icación de los r equer imient os, es
por eso que, a t r avés de los dist int os ciclos que posee, es impor t ant e que la cali dad del
sof t war e sea clar a, ya que como es un desar r ollo incr ement al, t oda pieza de sof t war e ser á
ut ilizada de alguna maner a en el pr oduct o f inal.

La Tr ansacción es la últ ima et apa y conf or ma t oda la par t e de implant ación, seguimient o,
af inamient o y mar cha blanca del sof t war e. En gener al en est a et apa no se especif ican nuevos
r equer imient os per o se r ealiza un af inamient o de aquellos que ya f uer on desar r ollados. Muchas
veces en est a et apa queda la capacit ación de los usuar ios, que est á muy de moda en la
act ualidad. Los paquet es de sof t war e ya no son ent r egados como caj as negr as y las empr esas
r equier en más seguido una capacit ación de su per sonal par a la ut ilización de ellos.

Cada una de est as et apas, posee un element o que es llamado it er ación. Cada una es un ciclo de
desar r ollo del sub-pr oyect o en donde posee cier t as car act er íst icas (en f or ma gener al
40
):

• Planif icación de la I t er ación
• Especif icación de Requer imient os
• Diseño de Sof t war e
• Codif icación
• Pr uebas

40
Cada it er ación posee más sub-et apas, per o pr incipalment e se pueden dividir en esas 5 ár eas.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

302

La car ga de cada una de est as car act er íst icas a t r avés de las f ases del desar r ollo se
dist r ibuyen más o menos de la siguient e f or ma:

Concepción Elabor ación Const r ucción Tr ansición
Requer imient os
Diseño de Sof t war e
Codif icación

La it er ación posee un t iempo def inido y abar ca el espect r o de un gr upo de f uncionalidades
específ icas (sub-pr oyect o). Al f inal de cada et apa la idea es t ener un pr ot ot ipo ya ar mado y
f uncionando, que es un sof t war e, más pequeño que el deseado, per o que est á complet ament e
oper at ivo.

A t r avés de cada et apa del desar r ollo, las it er aciones se van dist r ibuyendo según la cant idad
de r equer imient os. Per o en gener al, se puede t ener un númer o f ij o de it er aciones por et apa:

• Concepción: 1 it er ación que básicament e solo es la def inición del alcance del pr oyect o y
la planif icación del pr oyect o.

• Elabor ación: 1 a 3 it er aciones en donde se r eúnen los r equer imient os más det allados, se
hacen análisis y diseños de alt o nivel par a def inir ar quit ect ur a base y se cr ea el plan de
const r ucción.

• Const r ucción: Muchas it er aciones dividiendo la cant idad de r equer imient os f uncionales
a t r avés del t iempo par a const r uir los r equer imient os en pr oduct os incr ement ales.

• Tr ansición: 1 it er ación que básicament e es la implant ación y mar cha blanca del
pr oyect o. Acá se incluye la capacit ación y la af inación del desempeño, aunque est o
puede ser ot r a it er ación adicional.

También es muy impor t ant e mencionar que par a el desar r ollo con est e pr oceso, los aut or es han
pr ocur ado cr ear ot r os element os impor t ant es que def inen cómo t r abaj ar , a est o se le llama
Roles.

Los r oles dent r o del pr oceso de desar r ollo cumplen la f unción de indicar quién debe ser el
r esponsable de cada una de los pasos en una it er ación. Es así como hay Diseñador es de
Sof t war e, Codif icador es, I ngenier os de Requer imient os, et c. que no necesar iament e son
dist int as per sonas, per o si son dist int os “per sonaj es” en ese moment o.

Todo est e pr oceso de desar r ollo es llamado act ualment e RUP(Rat ional Unif ied Pr ocess)
41
y es
acompañado gener alment e por document ación que explica paso a paso t odo est o.

41
Rat ional es una empr esa cr eada por los aut or es de UML y su pr oceso posee un sin f in de
her r amient as par a el apoyo al desar r ollo de cada uno de los element os que son necesar ios y que
ver emos en est e capít ulo.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

303
Casos de Uso
Un Caso de Uso es en esencia una int er acción ent r e un usuar io o per sonaj e ext er no y un
sist ema comput acional. Los casos de uso básicament e cumplen con 3 car act er íst icas:

• Capt a alguna f uncionalidad visible par a el usuar io
• Puede ser pequeño o gr ande
• Logr a un obj et ivo punt ual par a el usuar io

En su f or ma inicial (básica) el caso de uso es cr eado a par t ir de una ent r evist a o conver sación
con el client e que solicit a la f uncionalidad del sist ema o por el usuar io que solicit a el sist ema:
Se abor da cada r equer imient o en f or ma discr et a (punt ual), se le da un nombr e y un t ext o
descr ipt ivo br eve que indique su obj et ivo.

Los Caso de Uso más gener ales apar ecen en la et apa de elabor ación, per o no se desesper en, ya
que en las siguient es et apas se pueden ir complicando, digo, complet ando y dando más valor a
cada caso de uso que r ealicen. :-)

Cada caso de uso nace a par t ir de int er acciones con el sist ema que r ealiza el usuar io. Por
ej emplo, veamos lo que hace la f unción de For mat o de Text o que t r ae Micr osof t Wor d como un
sist ema (conocido como St yle Sheet s), Pr imer o def inamos las int er acciones que t iene:

• Cambiar Ti pogr af ía
• Def inir Est i lo de Text o
• Usar Est ilo de Text o
• et c.

En gener al, est as int er acciones def inen lo que el usuar io hace con el sist ema, per o no el
obj et ivo que el usuar io t r at a de conseguir usando la her r amient a. Los ver dader os Obj et ivos
del Usuar io se descr ibir án como “Dar For mat o al Text o” y “Ut ilizar For mat o en ot r os
Pár r af os”.

Es así como ambos casos pueden r epr esent ar se como Casos de Uso, per o en inst ancias
dif er ent es de pr oblemas. En el caso de int er acciones, el caso de uso sir ve par a planif icación.
En los obj et ivos del usuar io pueden ver se dist int as alt er nat ivas par a solucionar los pr oblemas
de maner a más amplia, que con el pr imer caso muchas veces se r est r inge.
Diagr amas de Casos de Uso
Los diagr amas de casos de uso son r epr esent aciones gr áf icas que nos per mit en dar f or ma a los
dist int os casos de uso que par t icipan en el sist ema. Par a la not ación, los casos de uso ut ilizan 2
element os básicos que pr oceder emos a explicar :

Act or es: Los act or es, gener alment e r epr esent ados por per sonaj es alar gados
(como dibuj os inf ant iles), son ut ilizados par a r epr esent ar al usuar io, cuando
desempeña ese papel con r espect o al sist ema.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

304

Un act or en gener al r epr esent a solo un ROL dent r o de la especif icación dent r o del sist ema, es
decir , r epr esent a a un per sonaj e gener al y no a una per sona f ísica. Muchos act or es pueden
r epr esent ar a la misma per sona f ísica (por ej emplo el act or Pr of esor Auxiliar (que hace las
clases auxiliar es) y Pr of esor Evaluador (que cor r ige los cont r oles) en gener al son
per sonif icados a veces por las mismas per sonas, es decir , el pr of esor auxiliar siempr e t iene
que t omar el papel de evaluador después de un cont r ol.

Siempr e es más f ácil ident if icar los Casos de Uso a t r avés de los act or es, pues es más sencillo
inicialment e plant ear se los obj et ivos par a cada act or (que obviament e uno los puede conocer a
pr ior i cuando se enuncia el pr oblema) y luego enumer ar cada uno de los Casos de Uso que
r esponden a esos obj et ivos por act or . Si t r at ár amos a pr ior i de list ar t odos los casos de uso,
es pr obable que lo pr imer o que ocur r a es que se nos quede uno en el t int er o.

Una par t icular idad de un act or es que no es necesar io que sean ser es humanos, es decir , un
act or per f ect ament e puede ser ot r o sist ema inf or mát ico r elacionado.

Veamos un ej emplo sencillo: Repr esent ar el diagr ama de casos de uso par a un sist ema PAC
(Pago Aut omát ico de Cuent as) de una nueva empr esa I nt er net llamada Págat e. cl.

En la pr imer a ent r evi st a con ej ecut ivos de la empr esa podemos obt ener :

• Los client es que ut ilizan el sist ema son usuar ios r egist r ados.
• Si un client e desea ser usuar io debe r egist r ar se en nuest r o sist ema ingr esando sus
dat os per sonales.
• Par a el pago de una cuent a, se consult a el saldo al sist ema de consult a de Tr ansbank.

En est as poquit as líneas (que en gener al no son más de 5 a 10 minut os de conver sación) ya
podemos ident if icar a los act or es y algunos de los obj et ivos. Veamos:

• Usuar io: Per sona r eal
• Client e: Per sona r eal. Puede ser el mismo usuar io (ES un usuar io)
• Tr ansbank: Sist ema I nf or mát ico de Consult a de Saldos (SI CS)

Como ya podemos ver t enemos 3 act or es dist int os que se pueden r epr esent ar por una per sona
única y un sist ema comput acional (y no 3 per sonas como quedan en el diagr ama).

A modo de r egla gener al, los act or es que se muest r an en el diagr ama ser án solo aquellos que
necesit en de un caso de uso, y no necesar iament e que int er act úen con él. Por ej emplo, en el
caso del SI CS nombr ado ant er ioment e, ser á consider ado como Act or solo por el hecho que
r equier e una t r ansacción a r ealizar de pago del sist ema par a car gar a la cuent a cor r ient e o
t ar j et a de cr édit o, y no por la consult a de saldos que es la impor t ant e a r ealizar .

Casos de Uso: Son ident if icados por elipses con un t ext o dent r o y r epr esent an
un obj et ivo o una int er acción del usuar io necesar ia con el sist ema que se est á
desar r ollando.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

305

Todos los casos de uso t r at an de f uncionalidades r equer idas ext er nament e (no int er nament e).
Si el SI CS necesit a de una t r ansacción par a pr ocesar el car go a la cuent a cor r ient e o a la
t ar j et a de cr édit o, ese se convier t e en un r equer imient o que se debe sat isf acer .

Veamos como ident if icar los casos de uso del ej emplo de Págat e. cl. Tomando el mismo
enunciado, list emos pr imer o los obj et ivos de usuar io por act or a sat isf acer :

• Usuar io:
o Regist r a como Client e
• Client e:
o Administ r a de Cuent as
o Administ r a Medios de Pagos
o Paga de Cuent as
• Tr ansbank:
o Realiza Tr ansf er encia

Ya conocemos los obj et ivos de los act or es, dibuj emos nuest r o pr imer caso de uso:




















Al ver est e diagr ama, es clar o not ar que, al most r ár selo a un no especialist a inf or mát ico se
ent ienden las int er acciones que t endr á el sist ema con el ext er ior , aún cuando no posea ninguna
especif icación de sof t war e det r ás.

Per o ¿sat isf ace lo que el sof t war e r ealment e har á al f inal?. La r espuest a es que t al vez no,
por que es solo una compr ensión de los obj et ivos que se deben cumplir par a que el sof t war e sea
exit oso. Tal vez exist an muchos casos de uso que no hemos consider ado, y que cumplir án un r ol
impor t ant e, per o eso lo ir emos r ef inando a t r avés del pr oceso de desar r ollo.
Regist r o
Client e
Adm
Cuent as
Adm Medio
de Pago
Paga
Cuent as
Tr ansf e-
r encia
Usuar io
Client e
Tr ansbank
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

306
Uses y Ext ends: Los uses (o usa) y ext ends (o ext iende) se r epr esent an con
una f lecha de punt a blanca y un t ext o (use o ext end). I ndican las r elaciones que
exist en ent r e 2 casos de uso del sist ema.

Con mucha f r ecuencia se conf unden ambos concept os, per o es lo nor mal y det allamos a
cont inuación cada uno:

• Ext end: se usa cuando se t iene un caso de uso que es similar a ot r o, per o que hace un
poco más que él. Lo más compar able con est o es cuando se ext iende una clase
(her encia) en J ava, ya que, en est e caso, el caso de uso “her eda” el compor t amient o de
su padr e.

• Use: se usa cuando se t iene una por ción del compor t amient o de un caso de uso en ot r o
y no se quier e duplicar esa conduct a. Al igual que el ant er ior , podemos par ear lo con la
ut ilización de mét odo que llaman a ot r os que poseen esa cualidad, ya que no se desea
copiar dicha inf or mación en los mét odos, por que es siempr e el mismo pr oceso.

En nuest r o ej emplo, podemos ident if icar est as r elaciones.

En el caso de un ext end podemos ver la sit uación cuando Tr ansbank r echaza la t r ansacción por
f alt a de f ondos. En t ant o, la r elación de use apar ece cuando par a r ealizar un pago, debe
ingr esar se un medio de pago y además r ealizar la t r ansacción con Tr ansbank:




















A modo de r esúmen:

• Usa r elaciones ext ends cuando escr iba una var iación de una conduct a nor mal (casos
especiales, condiciones de bor de, ot r as ut ilizaciones).
<<xxx>>
Regist r o
Client e
Adm
Cuent as
Adm Medio
de Pago
Paga
Cuent as
Tr ansf e-
r encia
<<use>>
<<use>>
Falt a de
Saldo
<<ext end>>
Usuar io
Client e
Tr ansbank
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

307
• Usa r elaciones uses par a evit ar r epet iciones de casos de uso ya r ealizados (conj unt os
de conduct as más pequeñas o gener alizaciones).

Escenar io: Un t ér mino que se asocia con los casos de uso, y que muchas veces se conf unde con
ellos, es el t ér mino de escenar io. Un escenar io cor r esponde a una sola r ut a de pr oceso en un
caso de uso (por ej emplo, el pr oceso de Pago de Cuent a). Es por eso que decimos que un caso de
uso se compone de muchos escenar ios.

Realización: En la j er ga de UML t ambién ut ilizamos est e concept o par a nombr ar a las dist int as
f or mas de pr esent ar un caso de uso. Muchos diseñador es de sof t war e hacen var ias
r ealizaciones de un mismo caso de uso par a poner lo en discusión y t omar la mej or alt er nat iva.

Es muy común que los diseñador es hagan los casos de uso con los usuar ios, ya que son ellos los
que ident if ican sus pr opias necesidades más f ácilment e. Ot r os pr of esionales que pueden hacer
un caso de uso r ápidament e son los psicólogos y comunicólogos, quienes pueden ident if icar las
necesidades de los usuar ios en una ent r evist a, haciendo las pr egunt as exact as y escuchando
ent r e f r ases (o ent r e líneas).
Pr obl ema
Modele el Caso de Uso que r esponde a est a sit uación:

Un sistema de administración de notas para primer año se puede
realizar en Java de muchas formas. Este proyecto es muy importante,
ya que permitirıa una publicación automática y consulta por los
alumnos de manera sencilla.

Considere las siguientes caracterısticas:

• Los evaluadores ingresan las notas de cada alumno en las
preguntas del control.
• Los alumnos pueden revisar sus notas y publicar un reclamo
para una re-revisión por los evaluadores.
• Si posee un reclamo, el evaluador tiene por misión re-
corregir. Un aviso vıa correo electrónico le llega con una
lista de los usuarios que reclamaron.
• La secretaria docente ingresa al sistema para obtener un
listado con las notas de los alumnos para publicarlas en el
fichero.
• Los profesores de cátedra pueden ver estadısticas de notas y
los promedios de cada alumno. Ellos también pueden corregir
notas en caso de que el reclamo se realice directamente a
ellos.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

308
Diagr amas de I nt er acción
Def ini ción
Modelos que descr iben la maner a en que colabor an gr upos de obj et os
par a cier t o compor t amient o, capt ando el compor t amient o de un Caso de
Uso.

El diagr ama se compone de dist int os obj et os y mensaj es que act úan en un pr oceso de un Caso
de Uso. Muest r a cier t o númer o de ej emplos de obj et os y mensaj es que se pasan ent r e est os
obj et os dent r o del caso de uso.

I lust r emos con la siguient e especif icación de caso de uso:

1. El usuar io inicia un nuevo pedido.

2. La Vent ana Ent r ada de Pedido envía un mensaj e “pr epar a” a Pedido.

3. El Pedido envía ent onces un mensaj e “pr epar a” a cada Línea de Pedido dent r o del
Pedido

4. Cada Línea de Pedido r evisa el Ar t ículo de I nvent ar io cor r espondient e:

4.1. Si est a r evisión devuelve “ver dader o”, la Línea de Pedido descuent a la cant idad
apr opiada de Ar t ículo de I nvent ar io del almacén. Si la cant idad r est ant e es más
baj a que el st ock de r eor den, gener a un nuevo Ar t ículo de Reor den par a aument ar
el st ock del Ar t iculo de I nvent ar io.

4.2. De lo cont r ar io, no se r ealiza el pedido.

En donde el Caso de Uso quedar ía como:







Los diagr amas posibles de int er acción pueden ser de 2 t ipos, que analizar emos cada uno por
separ ado:
Diagr ama de Secuencia
Los diagr amas de secuencia muest r an cómo los obj et os int er act úan ent r e sí con el envío de
mensaj es y condiciones. En si da una secuenci a de cómo se ir á ej ecut ando (paso a paso) el
sist ema par a que los obj et os cumplan su f inalidad dent r o del caso de uso.
Pedido
Usuar io
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

309

Analicemos el diagr ama se secuencia del caso de uso que dimos de ej emplo:






















Est e diagr ama de secuencia r epr esent a básicament e lo que est á especif icado como caso de
uso.

Cada línea ver t ical se llama Linea de Vida del obj et o y r epr esent a la vida del obj et o dur ant e la
int er acción.

Cada Mensaj e se r epr esent a por una f lecha ent r e las líneas de vida de dos obj et os. El or den en
el que se dan est os mensaj es t r anscur r e de ar r iba hacia abaj o y cada uno es et iquet ado por lo
menos con el nombr e del mensaj e. Exist en dist int os t ipos de mensaj es:

(a) Mensaj es en donde se especif ica el nombr e son como las llamadas a mét odos. Est os se
pueden especif icar t ambién los ar gument os par a que quede más clar o, per o no es
est r ict ament e necesar io.

(b) I t er aciones que se indican con un * ant es de la condición de it er ación, por ej emplo,
“* [ por cada L.P.] pr epar a()”signif ica que por cada Línea de Pedido en un pedido llamar a
a pr epar a de esa Línea de Pedido.

(c) Asignaciones a at r ibut os como por ej emplo “exist e := r evisar ()” per mit e guar dar en
exist e un valor de ver dad si es que exist e o no invent ar io de ese ar t ículo.

una Vent ana de
Ent r ada
un Pedido una Línea de
Pedido
un Ar t ículo de
I nvent ario
un Ar t ículo de
Reor den
pr epar a()
* [ por cada L.P.]
pr epar a()
exist e := r evisar ()
[ exist e]
descuent a()
r eor denar := ver ()
[ r eor denar ]
nuevo
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

310
(d) Condiciones que se especif ican con las condiciones ent r e cor chet es y la acción baj o
ellas, como por ej emplo “[ exist e] descuent a()” que signif icaba que si el at r i but o exist e
es ver dader o, envía el mensaj e descuent a().

(e) Aut odelegación que es sencillament e cualquier mensaj e que pueda hacer se hacia el
mismo obj et o por ej emplo, “ r eor denar := ver ()”.

(f ) Cr eación que se especif ican con la palabr a nuevo en caso de cr ear ot r o obj et o que no
exist a hast a ahor a en la int er acción.

(g) Regr eso que se indica con una f lecha punt eada hacia at r ás indicando que la últ ima
llamada r et or na. Hay algunos r egr esos que no se especif ican, por que su llamada es
punt ual, es decir , llama y r et or na en seguida.

Exist en t ambién unos diagr amas de secuencia especiales par a la sincr onización de pr ocesos
concur r ent es o en par alelo, que se par ecen mucho a los ant er ior es, per o ingr esan nuevos
element os. Por ej emplo:

Act ivación: Se especif ica como un r ect ángulo a lo lar go de la línea de vida en el moment o en
que el pr oceso est á cor r iendo (est á pr ocesando o t r abaj ando en algo). En los lugar es en que no
se est á pr ocesando, la línea de vida apar ece punt eada.







Mensaj e Asíncr ono: I ndican a t r avés de una f lecha, con media cabeza abaj o, aquellos mensaj es
que se envían a ot r os obj et os o pr ocesos que cor r er án en par alelo (sin bloquear al invocador ).




Bor r ado: Most r ado como una X baj o la línea de vida de un pr oceso, indica cuando ese pr oceso u
obj et o dej a de exist ir a t r avés de un r et or no o si mplement e por f inalizar se a si mismo.

una Línea de
Pedido
Lapso de act ivación del pr oceso
X
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

311
Diagr ama de Colabor ación
Los diagr amas de colabor ación son ot r a f or ma de ver los diagr amas de int er acción, per o que
signif ican casi lo mismo. La idea es ver los obj et os en ext enso (sin líneas de vida) per o en
donde las int er acciones nos muest r an los f luj os y los mensaj es ent r e ellos.

Veamos el ej emplo del Pedido par a que quede bi en clar o como va cambiando el mismo diagr ama
per o de dist int os punt os de vist a.
















En est e caso se obser va como “colabor an” los obj et os que par t icipan en la int er acción. Las
f lechas indican los mensaj es y las líneas las int er acciones. Además, cada uno de los mensaj es
est á et iquet ado debidament e numer ado par a indicar el or den en el cual son emit idos.

Ref er ent e a las et iquet as, una var iant e de ellas es ut ilizar par a cada uno de los obj et os un nivel
de pr of undidad de un esquema numer ado. Es así como los mensaj es quedan individualizados por
obj et o y no por el conj unt o complet o del diagr ama.

Un últ imo det alle es que los nombr es de los obj et os est án individualizados como Nombr e del
Obj et o : Nombr e de la Clase. Es posible omit ir el nombr e del obj et o solo dej ando el nombr e de
la clase y mant eniendo los dos punt os (:) delant e de el la, si es necesar io.

La ut ilización de est os diagr amas de int er acción puede ser diver sa, y dependiendo de la
sit uación es impor t ant e ut ilizar uno de secuencia o de colabor ación. En muchos casos el de
secuencia es mucho más or denado y r igur oso en el or den de los mensaj es, per o si se desea un
esquema de int er acción ent r e los obj et os, se r ecomienda el de colabor ación.

Per o la complej idad es un punt o muy r elevant e. Siempr e es impor t ant e que est os diagr amas
sean sencillos y no demasiado sobr ecar gados y consider e siempr e que es solo par a r epr esent ar
un Diagr ama de Casos de Uso y no un conj unt os de ellos.

: Ent r ada de Pedido
: Pedido
Línea M : Línea de Pedido I nvent ar io M: Ar t ículo de I nvent ar io
: Ar t ículo de Reor den
1: pr epar a()
2: * [ por cada LP] : pr epar a()
5: r eor denar := ver ()
6: [ r eor denar ] : nuevo
3: exist e = r evisar ()
4: [ exist e] : descuent a()
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

312
Diagr amas de Est ados
Un siguient e paso en UML es analizar lo que son los Diagr amas de Est ado. Ant es de est o
def inir emos pr imer o lo que es un Est ado baj o el cont ext o de UML:
Est ado
Gr upo de car act er íst icas def inidas de un obj et o que pueden cambiar
solo a t r avés de una acción (cambio de est ado).

Est a def inición t an “de diccionar io” nos ayuda a compr ender y nivelar que ent endemos por
est ado. Por ej emplo: Con la acción de encender una ampollet a (est ado apagada) se pasa a un
modo de iluminación (est ado encendida) de la ampollet a.

El est ado posee una ser ie de car act er íst icas o Var iables de
Est ado que nos per mit en cont r olar y/ o saber que se involucr a
en ese est ado. También posee una ser ie de Act ividades que
r epr esent an la misión que el obj et o cumple en ese est ado. Todo
est o se ilust r a con un r ect ángulo r edondeado en las punt as y
con las var iables y act ividades dent r o.

Exist en 3 t ipos de act ividades:

• ent r y - act ividades que se r ealizan al ent r ar al est ado
• exit - event os que se ej ecut an al abandonar el est ado
• do - act ividades r ealizadas mient r as se est a en el est ado
Diagr ama de Est ados
Es un diagr ama que ilust r a las t r ansiciones ent r e los dist int os est ados
que el obj et o puede t omar .

El diagr ama de est ado ent onces se puede const r uir a par t ir de un conj unt o de est ados posibles
que puede poseer un obj et o en especial. Por ej emplo los dist int os est ados de una ampollet a
(encendido/ apagado/ quemado) y cómo se pasa de un est ado a ot r o.

La not ación que se ut iliza en los diagr amas se basa en los est ados (ant es ya nombr ados), las
t r ansiciones y los est ados incial y f inal.

Est ado I nicial: Es el comienzo del di agr ama y se ve como un
est ado sin impor t ancia, per o út il par a el moment o de saber cuál
es el pr imer est ado. Su r epr esent ación es un cír culo r elleno.

Est ado Final: Al igual que el est ado inicial, est e est ado solo se
ut iliza par a saber cuándo t er mina el diagr ama (o cuál es el últ imo
est ado ant es de f inalizar el f uncionamient o). Su r epr esent ación
es un “oj o de t or o” (del inglés “bull eye”).
Nombr e del Est ado

Var iables
de Est ado


Act ividades
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

313

Tr ansición: Es simplement e el t r aspaso ent r e un est ado a ot r o.
Se r epr esent a con una f lecha y una et iquet a opcional que le
indica la acción manual que pr oduj o ese cambio de est ado.

La t r ansición puede ser expr esada como un mensaj e o como una condición (ent r e cor chet es).

Por ej emplo, veamos el sencillo caso del f uncionamient o de un calef act or eléct r ico:









Como podemos ver , en el pr imer est ado, el calef act or necesi t a de 2 var iables de est ado par a
su f uncionamient o y que son t empMaxima y t empMinima. La idea que ese es el mar gen de
t emper at ur as en el cual el calef act or va a mant ener calef accionado. Además, posee unas
act ividades en cada est ado que son encendido del t er most at o y apagado del t er most at o,
por que en ese est ado, el calef act or debe cumplir esas act ividades par a f uncionar mej or .

Ahor a bien, est e sencillo diagr ama nos ilust r a básicament e los est ados que el calef act or puede
t omar . Per o dent r o del est ado “Funcionando” se puden encont r as más est ados, ya que el
calef act or se apaga (st and by) cuando est á muy calur oso (t empMaxima) y se enciendo cuando
la t emper at ur a vuelve a baj ar del mínimo (t empMinima). Veamos como podemos ext ender el
diagr ama par a abar car est as condiciones.


















acción
Funcionando

t empMaxima
t empMinima

ent r y / encender
t er m
do / calent ar
Encender
Apagando




exit / apagar t er m
Apagar
Encendiendo

t empMaxima
t empMinima

ent r y / encender t er m
Encender
Apagando




exit / apagar t er m
Funcionando




do / calent ar
St and by


do / dej ar de calent ar
Apagar
[ t empMaxima]
[ t empMinima]
Apagar
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

314

En est e nuevo diagr ama se ilust r a más det alladament e cómo es el pr oceso de f uncionamient o
del calef act os eléct r ico. Podemos ver que exist e una validación en las t r ansiciones que van
desde Funcionando a St and by, ya que esas t r ansiciones se r ealizar si se ha alcanzado esa
t emper at ur a máxima (de Funcionando a St and by) o se ha llegado a la t emper at ur a mínima (de
St and by a Funcionando).

Con un análisis simple podemos dar nos cuent a que aún quedan algunos est ados “int er nos” que
explicar y es como se validan y obt iene las t emper at ur as el t er most at o par a encender o apagar
el calef act or . Par a ello ut ilicemos subest ados dent r o de Funcionando y St and by:


























Con est os diagr amas ya se t iene bien clar o el f uncionamient o del obj et o que se deseaba
analizar . También, se ha dej ado lo suf icient ement e explicit ado cómo se hacen los diagr amas de
est ado.
Ut ilización
Es necesar io r ealizar diagr amas de est ado, por que ellos ayudan a los analist as, diseñador es y
desar r ollador es a ent ender el compor t amient o de los obj et os en un sist ema. Los
pr ogr amador es en par t icular , deben suponer que hacen los obj et os par a poder implement ar los
en el sof t war e. No es suf icient e implement ar los obj et os solo con las especif icaciones de lo
que hace.
Funcionando
Midiendo




do / medición de t emp
Compar ando


ent r y / compar a
do / t emper at ur a
act ual – t empMaxima
[ t empMaxima no alcanzada]
[ t empMaxima alcanzada]
St and by
Midiendo




do / medición de t emp
Compar ando


ent r y / compar a
do / t emper at ur a
act ual – t empMinima
[ t empMinima no alcanzada]
[ t empMinima alcanzada]
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

315
Pr obl ema
A t r avés de diagr amas de est ado, modele el compor t amient o de un ascensor . Suponga que el
ascensor comienza siempr e en el pr imer piso. Además, el ascensor debe volver siempr e al
pr imer piso pasado un cier t o t iempo.

Solución


















Det enido en 1º Piso

t iempo esper a
Det enido en Piso


Subiendo


do / I r al piso
Baj ando a 1º Piso


Baj ando


do / I r al piso
subir (piso)
subir (piso)
baj ar (piso)
[ t iempo esper a]
viaj ar
viaj ar
viaj ar
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

316
Diagr amas de Clase
A par t ir de un “buen” diseño de casos de uso (diagr amas) se pueden ident if icar las
int er acciones y los obj et ivos que, clar ament e el usuar io quier e del sist ema que se desea
desar r ollar . Ent onces, ahor a que ent endemos al client e, ¿cuál es el siguient e paso par a
ent r egar o r ealizar el desar r ollo del sof t war e pedido?

Los Diagr amas de Clase descr iben los t ipos de obj et os que hay en el
sist ema y las diver sas clases de r elaciones est át icas que exist en ent r e
ellos.

En est a def inición semi -f or mal podemos encont r ar los f undament os de lo que son los diagr amas
de clase, per o en r ealidad qué son y par a qué si r ven lo podr emos ir vislumbr ando a par t ir de un
desar r ollo más t angible que de la t eor ía comput acional en I ngenier ía de Sof t war e.
Clase
Una Clase es una r epr esent ación de una unidad, per t enecient e al
sist ema, y que r ealiza algunas int er acciones o r elaciones con el ent or no
(ot r as clase o act or es ext er nos al sist ema).

Como hemos vist o a t r avés del cur so, es muy clar o que algunos obj et os que son t angibles en la
vida r eal pueden ser “modelados” a t r avés de lo llamado como Clase. Es bast ant e sencillo
r ealizar el mismo par alelo con las clases que se ut ilizan en los di agr amas de clases.

En el diagr ama son r epr esent ados por caj as de t ext o con 3 t ipos
de campos: el Nombr e de la Clase que la ident if ica, los At r ibut os
que son car act er íst icas que def inen a la clase y las Oper aciones
que r epr esent an las f uncionalidades a las que r esponde o que
r ealiza la clase.

El Nombr e de la Clase ident if ica r ápidament e una clase dir ect a en el lenguaj e de
pr ogr amación. Por ej emplo en J ava ident if ica inmediat ament e la clase que se debe empezar a
pr ogr amar .

En el caso de los At r ibut os, t ambién es clar o que pasan a ser las var iables de inst ancia de la
clase. Muchas veces se especif ica el t ipo de los at r ibut os indicando con 2 punt os después de
su nombr e. Por ej emplo: “ nombr e : St r ing” indicar ía que el at r ibut o nombr e es un St r ing.

Las oper aciones t ambién son r epr esent adas en la codif icación como las f unciones o mét odos de
la clase. En est e caso (y de hecho así es la not ación) podemos dar nos cuent a que las
oper aciones se anot an con un par ént esis vació después de su nombr e si no posee par ámet r os.
En el caso de poseer alguno, est os son especif icados ent r e los par ént esis. También, y al igual
que los at r ibut os, las oper aciones pueden t ener un t ipo de r et or no, el cual se especif ica con 2
punt os después de su “f ir ma”.

Nombr e de la Clase
At r ibut os

Oper aciones


Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

317
Un ej emplo del par alelo que hay ent r e el diagr ama y J ava es:

public class Alumno {
public int run;
public String nombre;

public Control darControl(int x) { ... }
}
Relaciones Est át icas
Las Relaciones Est át icas son vínculos ent r e las clases del model o y que
indican la int er acción y uso en el desar r ollo del sist ema.

Exist en 2 t ipos de r elaciones en un diagr ama de clases:

Asociaciones: Repr esent an r elaciones ent r e inst ancias o concept uales ent r e las clases. Son
r epr esent adas por una r ect a que va desde una de las clases r elacionadas hast a la ot r a clase
r elacionada.





Como se puede ver , una asociación posee var ios element os:

• Et iquet a: Es un t ext o que indica el t ipo de asociación que exist e ent r e las clases.
• Mult iplicidad: Es un indicador que per mit e ident if icar la cant idad de obj et os que
par t icipar án en la r elación dada. Si la mult iplicidad dice * (ast er isco) indica que son
muchos element os.

Las mult iplicidades más gener ales son:

A
1
B

Un obj et o de clase A se asocia siempr e con un obj et o de clase B
A
1..*
B

Un obj et o de clase A siempr e se asocia con uno o más obj et os de clase B
A
0..1
B

Un obj et o de clase A siempr e se asocia con ninguno o con un obj et o de clase B
A
*
B

Un obj et o de clase A siempr e se asocia con ninguno, uno o más obj et os de clase B
A
m..n
B

Un obj et o de clase A siempr e se asociar án con un númer o ent r e m y n de obj et os
de clase B

Subt ipos: Son r elaciones que nos per mit en indicar cuando una clase es subt ipo de ot r a (caso
especial de la clase padr e). Se r epr esent an con una r ect as que unen a la super clase (clase
padr e) y la subclase o subt ipo (clase hij o) con un t r iángulo en la punt a de la clase padr e.

Alumno
r un
nombr e
r esponder Cont r ol()

Not a
valor
r evisar Cont r ol()

1 *
Cont r ol


Evaluado
Alumno
r un : int
nombr e : St r ing
dar Cont r ol(int ) : Cont r ol

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

318












El discr iminador indica que cada una de las inst ancias del super t ipo que se est é ut ilizando
cor r esponde a una y solo una inst ancia de las de los subt ipos, aún cuando un super t ipo puede
t ener muchos subt ipos (cada uno desunido ent r e si, es decir , independient es).

Un ej emplo que ut iliza t odo lo ant er ior ser ía el modelar las clases par a un sof t war e de
pr ocesamient o de pedidos en una panader ía:



















Sint axi s
Veamos algunas gener alidades sobr e la sint axis par a que quede más clar o.

Exist en var ios element os que cont r ibuyen a la sint axis de los at r ibut os y oper ador es de las
clases en el diagr ama. Est as son:

Visibilidad: I ndica que t an visible ser á el element o. Est o puede ser + (público), # (pr ot egido), -
(pr ivado). Es lo mismo que en J ava llamábamos como pr ivacidad.
Per sona
r un
nombr e

Docent e
cur so

Alumno
mat r icula : int
r endir Cont r ol()

Discr iminador
Client e
+ numer o : int

Pedido
+ cant idad : int
+ pr oduct o : Pr oduct o
+ t ot alizar () : int

Pr oduct o
+ codigo : int
+ pr ecio : int
+ calcular Pr ecio(cant idad : int ) : int

Panader ía


Past eler ía


1 *
1
*
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

319

Nombr e: El nombr e del element o es una cadena de car act er es.

Tipo: El t ipo cor r esponde al t ipo del element o en cuest ión.

Valor por Omisión: Es el valor por def ect o que debe t ener ese element o en caso de ser
inicializado.

La sint axis de los At r ibut os es:

<visibilidad><nombr e> : <t ipo>= <valor por omisión>

siendo solo el nombr e un par ámet r o obligat or io.

La sint axis par a una Oper ación es:

<visibilidad><nombr e> (<par ámet r os>) <t ipo de r et or no>

siendo el nombr e, los par ámet r os y el t ipo de r et or no los obligat or ios. En el caso de la sint axis
de los par ámet r os, est os se r epr esent an de la misma maner a que los at r ibut os de una clase.
Ot r os Concept os
Navegabilidad
La navegabilidad se aplica en t or no a lo que son las asociaciones. Las asociaciones pueden t ener
una “dir ección” que nos indica qué obj et os t ienen la r esponsabilidad de deci r a que clases
cor r esponden y quienes no:







En est e ej emplo indica que un Pedido debe de decir a qué Client e cor r esponde. Est o es muy út il
par a la implement ación, por que nos indicar á en donde declar ar emos las inst ancias de la clase
asociada. Sin embar go, no es necesar io especif icar las, ya que eso indicar ía una navegabilidad no
def inida (modelos concept uales).

Reglas de Rest r icciones
Est e element o, cuya sint axis se especif ica como t ext os f lot ant es encer r ados en llaves { ... } en
t or no a las clases, nos indican af ir maciones que deben cumplir se (algo como los if ) dent r o de
esas clases.

Client e
+ numer o : int

Pedido
+ cant idad : int
+ pr oduct o : Pr oduct o
+ t ot alizar () : int

1 *
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

320
Un ej emplo ser ía que “Si el pedido.client e.est adoCr édit o() es ‘Pobr e’ ent onces
pedido.pr epagado debe ser ver dader o” en donde est adoCr édit o() es un mét odo de Client e y
pr epagado es una var iable de inst ancia.

Clases Abst r act as
Las clases abst r act as en UML se r epr esent an por dibuj os r ect angular es igual que en el caso de
las clases, per o cuyo t ext o es en cur sivas:











Se ut iliza una clase abst r act a al igual como se def inen en J ava: Una “gener alización” de una o
más clases que compar t en algunos at r ibut os o f uncionalidades. Es por eso que la “her encia” en
UML es conocida como “gener alización”.

I nt er f aces
Las int er f aces en UML t ambién r epr esent an dir ect ament e lo que signif ican en los lenguaj es de
pr ogr amación como J ava: Una capar azón en la cual se encapsulan las f uncionalidades de un
gr upo o t ipo de clase. También es conocido como t ipo, ya que los obj et os que se inst ancias son
del t ipo de la int er f az, per o su enlace dinámico es a una clase específ ica (que implement a la
int er f az).

La “implement ación” de las int er f aces en UML se le llama r ef inamient o y se dibuj a igual que la
gener alización, per o con líneas punt eadas.















Vent ana
{abst r act o}

alFr ent e()
alFondo()

<<int er f az>>
Figur a

Elipsoide
cent r o
r adiox
r adioy
ar ea()
per imet r o()

Polígono
punt os
ar ea()
per imet r o()

Vent ana de Windows

alFr ent e()
alFondo()

Vent ana de Mac

alFr ent e()
alFondo()

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

321
Dependencia
El concept o de dependencia es un t ipo de asociación que se ut iliza cuando exist en int er f aces o
clases abst r act as, y es una asociación que indica cuando ot r a clase ut iliza de alguna f or ma una
clase abst r act a o una int er f az.

Su not ación es una f lecha punt eada que va desde la clase que ut iliza el element o hast a el
element o del cual depende.






En est e ej emplo, Pincel depende de los obj et os dinámicos que f uer on cr eados a par t ir de
r ef inamient os de la int er f az Figur a.
Per spect iva
Exist en muchas f or mas de apr oximar se a una r epr esent ación de un sist ema con un diagr ama de
clases y est as cor r esponden a 3 punt os de vist a dist int os que t al vez t ienen punt os en común.

Per spect iva Concept ual
Es r ecomendable r epr esent ar en el diagr ama los concept os del dominio que se est á est udiando.
Est os concept os se r elacionan de maner a nat ur al con las clases que los implement an, per o con
f r ecuencia no hay una cor r elación dir ect a. De hecho, los modelos concept uales se deben
dibuj ar sin impor t ar el sof t war e con que se implement ar án, por l o cual se pueden consider ar
como independient es del lenguaj e.

En est e t ipo de per spect iva, la def inición de at r ibut os, oper aciones y r elaciones se hacen en
f or ma bast ant e básica, solo par a que se pueda compr ender la idea y el plano gener al del modelo
a desar r ollar .

Per spect iva de Especif icación
Viendo el sof t war e se puede llegar a est a per spect iva. Sin embar go, la implement ación se ve a
t r avés de int er f aces y no de las clases r eales que se deben implement ar , por lo t ant o, en
r ealidad vemos los t ipos y no las clases. El desar r ollo or ient ado a obj et os pone un gr an énf asis
en la dif er encia ent r e est os element os, aunque se pase por alt o con f r ecuencia.

Obser var a t r avés de est a per spect iva puede r esult ar en muchos casos algo complej o, pues
t endr emos que mir ar “ent r e líneas” par a llegar a la implement ación.

Per spect iva de I mplement ación
Dent r o de est a concepción, r ealment e t endr emos clases y no int er f aces ni concept os
f ilosóf icos del sist ema. Con est e t ipo de per spect iva, que es la más común dent r o de los
pr ogr amador es y la más út il al moment o de codif icar el sof t war e, vemos dir ect ament e en br ut o
las especif icaciones de las clases y la implement ación dir ect a.

<<int er f az>>
Figur a


Pincel

dibuj ar ()
pint ar ()

Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

322
El punt o de vist a global de est a per spect iva nos per mit e cont r olar mej or la implement ación,
pues vemos en ellos (en los diagr amas) las int er acciones y r elaciones ent r e las inst ancias
f ísicas de cada una de nuest r as clases.

Es alt ament e r ecomendado un diseño como ést e si es necesar io cont r olar una gr an cant idad de
clases que se pueden conver t ir en inmanej ables al moment o de codif icar las.

Cuándo y Como usar Diagr amas de Clases
Los diagr amas de clases son la columna ver t ebr al de casi t odos los mét odos OO. El pr oblema
r adica en que ést os diagr amas son t an r icos que pueden llegar a ser complicados y
abr umador es. Per o, si hablamos de r ecet a de cocina, t enemos algunos consej os pr áct icos par a
r ealizar buenos diagr amas y en el moment o y lugar adecuado:

• No t r at e de usar t oda la not ación a su disposición. Empiece siempr e con la not ación más
sencilla def iniendo las clases, asociaciones, at r ibut os, f uncionalidades y al f inal la
gener alización o her encia. Exist e más not aciones que son út iles solo si se necesit an,
per o no son r ecomendados par a empezar .

• Aj ust e la per spect iva desde la cual se dibuj an los diagr amas dependiendo la et apa del
pr oyect o.

ü Si es en análisis, dibuj e modelos concept uales.
ü Cuando t r abaj e con sof t war e, cént r ese en modelos de especif icación.
ü Dibuj e modelos de implement ación cuando est e most r ando una t écnica de
implement ación en par t icular .

• No dibuj e modelos par a t odo, por el cont r ar io, cént r ese en las ár eas clave del sist ema.
Es mej or usar y mant ener al día unos cuant os diseños que t ener muchos modelos
olvidados y obsolet os.

El pr oblema de los diagr amas es que van empant anando los det alles de impl ement ación. Par a
cont r ar r est ar est o, siempr e es út il usar las per spect ivas concept uales y de especif icación par a
no “casar se” con la implement ación dir ect ament e.
Pr obl ema
Se desea modelar usando UML un j uego de Poker . El Poker se j uega con car t as inglesas las
cuales poseen cada una un númer o y una pint a, t odas dist int as ent r e sí. Cada Mano de poker
posee 5 car t as (que son con las que j uega cada j ugador ). Por supuest o que el j uego no t iene
sent ido sin apuest as, por lo que se dispone de un mont o de 10.000 por cada j ugador par a
r ealizar apuest as. El j uego, par a simplif icar lo, consist e en:

• 1 r epar t idor (posee el mazo con t odas las car t as) y n j ugador es.
• Todos dan una apuest a de 500 inicial.
• El r epar t idor da 5 car t as al azar a t odos los j ugador es (incluyéndose).
• Todos r evisan sus car t as y descar t an un númer o menor o igual a 5 car t as par a
r eemplazar las por ot r as, pagando 100 por hacer est o.
Java: del Grano a su Mesa (Version 1.3)
Capitulo XXIV: Diseno de Software UML

323
• Luego se muest r an las car t as y gana el que posea mej or j uego.

Dibuj e el diagr ama de clases de est a sit uación con la per spect iva concept ual.

Solución
Bueno, siempr e en modelamient o exist e más de una solución, per o es nor mal, pues depende del
punt o de vist a que t enga el pr of esional que se encuent r e modelando. Siempr e es impor t ant e
t ener en cuent a las per spect ivas que se ut ilizan y t ambién que un diagr ama de clases debe
ilust r ar el modelo que el sof t war e t endr á.

























Car t a
valor : int
pint a : int

Mazo

mezclar ()
sacar Car t a() : Car t a
Mano

poner Car t a(c : Car t a)
sacar Car t a() : Car t a
compar ar (m : Mano) : int

<<int er f az>>
J ugador

j ugar ()

Repar t idor
nombr e : St r ing
diner o : int
j ugar ()
dar Car t as(n : int ) : Mano
def inir (j [ ] : J ugador ) : J ugador

Nor mal
nombr e : St r ing
diner o : int
j ugar ()
*
1
* 1 1
1
Java: del Grano a su Mesa (Version 1.3)
Referencias

324
Ref er encias
En est e document o se ut ilizó el siguient e mat er ial:
Li br os
§ I nt r oducción a J ava

§ UML Got a a Got a (UML Dest illed) de Fowler y Scot t
Sit ios Web
§ Online API of J ava 2 Plat f or m SE v1.3.1 (ht t p:/ / j ava.sun.com/ j 2se/ 1.3/ docs/ api )

§ Online API of J ava 2 Plat f or m SE v1.2.2 (ht t p:/ / j ava.sun.com/ j 2se/ 1.2/ docs/ api )

§ Online API of J ava 1.1.x (ht t p:/ / j ava.sun.com/ pr oduct s/ j dk/ 1.1/ docs/ api/ packages.ht ml)

§ J ava homepage (ht t p:/ / j ava.sun.com)

§ Tut or ial de J ava (ht t p:/ / sunsit e.dcc.uchile.cl/ SunSI TE/ j ava/ docs/ J avaTut / index.ht ml)

§ Eclipse (ht t p:/ / www.eclipse.or g)

§ Clases Console y ConsoleCanvas (ht t p:/ / www.holt sof t .com/ j ava/ hsa_package.ht ml)

§ RDBMS mySQL (ht t p:/ / www.mysql.com/ downloads/ mysql-3.23.ht ml)

§ I nf or mación sobr e Tar j et as CRC(ht t p:/ / www.c2.com/ doc/ oopsla89/ paper .ht ml)

§ Tut or ial UML en 7 días (ht t p:/ / odl -skopj e.et f .ukim.edu.mk/ UML-Help/ )

§ Tut or ial UML de Pat r icio Salinas (ht t p:/ / www.dcc.uchile.cl/ ~psalinas/ uml )

§ Más inf or mación sobr e UML (ht t p:/ / www.cs.ualber t a.ca/ ~pf iguer o/ soo/ uml/ )

Java: del Grano a su Mesa (Versio n 1.3)
Introduccio n

Java: del Grano a su Mesa (Versio n 1.3)
Introduccio n

Introducción
Este documento está orientado al apoyo de personas que no tengan conocimiento con el lenguaje Java, ni tampoco con conceptos de programación. Todos los capítulos están realizados con un formato de clases, plantenado primero una motivación que generalmente es un problema que es deseable resolver y que tiene su solución con los conceptos obtenidos a través del capítulo, luego el desarrollo del tema y por último algunos problemas resueltos y propuestos para practicar con los conceptos obtenidos. Como está recopilado por clases de cátedra de un profesor de la Universidad de Chile, existe una posibilidad que hayan inconsistencias entre los capítulos, que serán solucionados en posteriores ediciones de este apunte. Su uso es liberado a nivel académico, tanto por alumnos del curso de Computación I como profesores que deseen usar este material como apoyo a sus clases. También, la idea es dar más herramientas en español para aquellos programadores inexpertos que están ingresando en el mundo de Java.

Agradecimientos
A mi esposa, Verónica, quien comprendió eternamente las largas noches en los cuales preparaba las clases del año 2001, 2002 y 2003 (las que faltaban). Además, para mis alumnos del curso de CC10A – Computación I sección 03 del año 2001, de la Escuela de Ingeniería de la Universidad de Chile, quienes motivaron el desarrollo del contenido de este apunte. También a mis alumnos del curso de CC10A – Computación I sección 03 del año 2002, gracias a quienes logré mejorar, completar información y compilarla en este apunte. De manera especial, agradezco a Daniel Muñoz, quien me hizo reflexionar en el nombre de este apunte y cambiarlo desde su versión original “Java: Programación y Lenguaje” a “Java: del Grano a su Mesa”. A Giselle, Pablo, Claudia y Marko quienes hicieron control de calidad de mi apunte. Por último a los profesores y alumnos quienes utilizan este apunte, ya que gracias a ellos podré recibir comentarios y aportes a mi correo electrónico (andmunoz@dcc.uchile.cl) para mejorar más aún su ayuda académica y computacional. A todos, gracias. Andrés Muñoz O. Ingeniero de Software Profesor Universidad de Chile

3

4

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo I: Principios Ba sicos de Java

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo I: Principios Ba sicos de Java

Capítulo I: Principios Básicos de Java Principios Básicos
¿Qué es Java?
JAVA es un lenguaje de programación creado por SUN Microsystems (http://www.sun.com), muy parecido al estilo de programación del lenguaje “C” y basado en lo que se llama Programación al Objecto.

Programación en Java
Los programas en Java son archivos de texto planos con extensión .java (se utiliza cualquier programa que escriba archivos de texto como son el Notepad de Windows, Wordpad, Textpad e inclusive Word cuando guarda en formato texto) que deben ser compilados con una JVM (Java Virtual Machine) y convertidos en un archivo .class, con el cuál pueden ser ejecutados.

Escribe

x.java

Compila

x.class

Ejecuta

Programación al Objeto
Los principios de la programación al objeto es “modelar” y representar, a través de elementos de programación, objetos que existen en la realidad (tangible o intangibles). Por ejemplo, un lenguaje en donde se pueda modelar una calculadora con todas las operaciones que pueda realizar. Es así como se encapsula y representa un objeto de la siguiente forma (notación UML 1): Calculadora Suma Resta Multiplica Divide ... Este dibujo representa las funciones que uno puede realizar con una calculadora.

Los archivos .class son binarios, por lo que no se pueden abrir con ningún programa.

Un Archivo Java
Un archivo .java debe contener la siguiente estructura base:

// Area de inclusion de librerıas (package) [Opcional] import <package>.*; // Definicion de la clase [public] class <nombre de la clase> { // Definicion de metodos [static] [public/protected/private] <tipo de dato> <nombre> (<param1>, <param2>, ..., <paramN>) { ... } }

Clase
La estructura anteriormente vista la llamaremos Clase y representará algún objeto o entidad, tangible o intagible que queramos modelar. En un principio escribiramos clases que sean nuestros Programas Principales, es decir, aquellos que resuelven los problemas que nos planteemos. Por ejemplo:

public class HolaMundo { static public void main (String[] args) { Console c = new Console(); c.println (”Hola Mundoá); } }

Unified Model Language: Un lenguaje para modelamiento orientado al objeto que veremos más adelante en el curso.

1

Esta clase representa mi programa llamado HolaMundo y solo escribe en pantalla la frase “Hola Mundo”.

5

6

println(”Hola” + ” Mundoá).” (punto y coma).println(”Hola” + ” Mundoá). c. } c. Los métodos son bloques de programas que se ejecutan al ser invocados: // EJECUTABLE Instrucciones Cada línea en Java es conocida como una Instrucción.. Estas 2 línea son interpretadas por el computador como si fuesen una sola: c.. Esta clase puede tener muchos métodos o funcionalidades.println(”Hola Mundoá). y significa que es lo que uno manda a realizar al computador en un determinado momento. Java: del Grano a su Mesa (Versio n 1..println(” Mundoá).” es nuestro fin de instrucción: public class public public public public public .print(”Holaá). c.println(”Hola Mundoá). } Console { void print(String s) { ..Java: del Grano a su Mesa (Versio n 1. } BLOQUE Las clases se componen de 2 partes: un encabezado y un cuerpo: c. Console es una clase (Console.3) Capi tulo I: Principios Ba sicos de Java c..” indica el fin de instrucción.println(”Hola Mundoá). ya que almacena múltiples bloques (métodos) y otras instrucciones. ya que el “. ya que el “. } } Bloques En Java se pueden agrupar las instrucciones en Bloques de instrucciones. Esta línea es equivalente a: 7 8 . al tener el método main significa que lo que está dentro de los paréntesis de llave corresponde a lo ejecutable: public class HolaMundo { static public void main (String[] args) { Console c = new Console(). Este separador funciona como si se le indicara al computador DONDE termina una línea. ya que Java permite que en 1 línea física escribir más de una instrucción: public class HolaMundo { static public void main (String[] args) { Console c = new Console(). Los bloques también pueden almacenar otros bloques como en este caso.3) Capi tulo I: Principios Ba sicos de Java Tipos de Clases Existen 2 tipos básicos de clases: Las clases ejecutables y las que no lo son. Los bloques son delimitados por los paréntesis de llaves (“{“ y “}”). c.. También es normal que uno pueda escribir una instrucción en más de una línea física. que son utilizadas dentro de los otros programas. La clase HolaMundo es del tipo que se puede ejecutar. } } ENCABEZADO CUERPO c... } int readInt() { . El cuerpo de una clase es considerado un bloque de programa..print(”Holaá). } void println(String s) { .. c.println(” Mundoá).. Por ejemplo: static public void main (String[] args) { Console c = new Console(). // Indica al computador que debe // imprimir en pantalla la frase // ”HOLA MUNDOá Todas las instrucciones llevan un separador al final: “. La diferencia entre estas 2 clases radica físicamente en que algunas de ellas son invocadas desde otras clases. } double readDouble() { .println(”Hola Mundoá). c. } long readLong() { . es decir.class) que es invocada o utilizada por la clase HolaMundo anteriormente vista. Por ejemplo..

[INICIO DEL PROGRAMA] Console c=new Console().8 o 1.sun. pero cada quien es libre de usar el que mas le acomode (UltraEdit. Luego que lo tengas en tu computador.3) Capi tulo I: Principios Ba sicos de Java Ejecución de un Programa Java Definiremos plan de ejecución a las líneas que realmente son leídas y ejecutadas cuando uno invoca la clase que desea correr.2. int numero=c. y comienza SIEMPRE por el bloque de programa escrito dentro del método main. 1) 2) 3) 4) 5) 2 Si te atreves a probar en otra versión del JDK queda estrictamente bajo tu responsabilidad.readInt(). el bloque main comienza a ejecutar. pero nada superior a eso.0. Para que tu computador tenga una JVM. etc). nosotros utilizaremos el JDK 1.print("El factorial de:"+ numero+ " es:"+ factorial). Con esto ya tienes lo necesario para comenzar tu aventura.print("Ingrese el numero a calcular: "). El JDK es un compilador y ejecutor de programas Java a través de algo que se llama Java Virtual Machine (JVM) y que es como un computador pero que solo entiende Java. El icono de notepad se encuentra en el menú: MENU INICIO è ACCESORIOS è Bloc de Notas (Notepad) Y el abrirlo se ve una ventana como la siguiente: import java. int factorial = [resultado del bloque siguiente] a) int factorial=1.*. c) return factorial.8 o 1. i<numero. En el caso de la escuela se encuentra instalado el JDK 1. Para efectos del curso. es necesario que descargues el JDK y lo instales en tu computador. El JDK lo puedes descargar de la página oficial de Java de Sun Microsystems (http://java. instala el software y “voila”. Jolie. i<numero.3) Capi tulo I: Principios Ba sicos de Java Java: del Grano a su Mesa (Versio n 1. c.3.1.print("Ingrese el numero a calcular: "). Al momento de ejecutar la clase. class ejemplo{ //este programa calcula el factorial de un numero. 7) . int numero=c.print("El factorial de:"+ numero+ " es:"+ factorial). b) for(int i=1. i++){ factorial=factorial*i. pero recomendamos que instales el JDK 1. El mas simple y que viene de manera predeterminada con windows es Notepad (Bloc de Notas). el plan de ejecución sería el siguiente: . static public int fact(int numero){ int factorial=1. int factorial = fact(numero). Qué necesitas para programar Es muy necesario utilizar el Java Develpment Kit (JDK) adecuado para las necesidades que tengas. i++) [repite el siguiente bloque] i) factorial=factorial*i.2. Como escribir un programa Para escribir un programa lo primero que se necesita es un editor de texto. for(int i=1. La ejecución de un programa en Java es lineal. } return factorial. c.readInt().com) o desde la página de ayuda de la página del curso. } static public void main(String args[]){ Console c=new Console(). } } En este ejemplo. [FIN DEL PROGRAMA] Podemos notar que la ejecución es muy distinta a el órden en el cual se han escrito las líneas de código (instrucciones).1.Java: del Grano a su Mesa (Versio n 1. [devuelve el valor del bloque al 4] 6) c.3. ya que las funcionalidades de la Console pueden verse afectadas por otras versiones 2.0 y las funcionalidades se ven bastante bien. 9 10 .io. Textpad. podamos saber también como llegar a que se ejecuten también. c. Luego se realizan las llamadas necesarias a cualquier bloque o método: En la Práctica La idea es que ahora que conocemos como se escriben los programas.

deberías cambiarlo en el CLASSPATH.1. pero puedes encontrar versiones en la internet.3) Capi tulo I: Principios Ba sicos de Java En esta ventana se puede escribir el código de algún programa.C:\jdk1. c. con el mismo nombre de la clase ( class ejemplo{…} ).class Luego.txt cosa que esta muy mal porque no podremos utilizarlo como programa Java.8 es.3) Capi tulo I: Principios Ba sicos de Java Java: del Grano a su Mesa (Versio n 1.class Message. I++){ factorial=factorial*i. para guardar eso se debe ir al menú Archivo/Guardar como… Se guarda.print("Ingrese el numero a calcular: "). } } Existen otros editores que puedes usar. Algunos conocidos son los llamados IDE.2. i<numero. int factorial=1. Por ejemplo el siguiente código podemos escribirlo dentro de Notepad. Si tu versión es la 1.java: Console.class ConsoleCanvas. para ahorrar confusión. Para ello debemos abrir una ventana de MS-DOS y poner: set CLASSPATH = . } c.Java: del Grano a su Mesa (Versio n 1.print("El factorial de:"+ numero+ " es:"+ factorial). Estos son: § § § § § § IBM Visual Age for Java Borland JBuilder Sun Forte Jade JCreator (La versión Limited Edition es gratis) Jolie (un desarrollo gratis del profesor Kurt Schwarze) Algunos editores de texto que pueden ayudar marcando colores y estructura son: § § Textpad UltraEdit Que en notepad quedaría como: Como compilar un programa Una vez guardado el programa debemos asegurarnos que nuestro CLASSPATH este apuntando correctamente a las librerías de Java.2. en este caso.. Después debemos colocar los 4 archivos que usan la consola en el mismo directorio que el programa que hemos escrito llamado ejemplo. la versión de Java que instalamos.1. for(int i=1.readInt().class FatalError. La mayoría debes pagarlos.java. Las comillas aquí son necesarias o de lo contrario el archivo se guardara con el nombre como: ejemplo.8\lib el directorio jdk1. 11 12 . para que probemos: class ejemplo{ static public void main(String args[]){ Console c=new Console(). int numero=c.

Debemos hacer hincapié en que el nuevo comando se llama java. pero con paciencia también se pueden arreglar. o porque nuestro PATH. sino que solamente “java ejemplo”. no apunta al directorio donde esta el comando java. Lo cual ejecutará el programa ejemplo. Aquí suelen ocurrir cosas inesperadas. deberás poner lo siguiente y volver a compilar: set PATH = %PATH%. Ejemplo: Java: del Grano a su Mesa (Versio n 1.3) Capi tulo I: Principios Ba sicos de Java Luego debemos abrir una ventana de MS-DOS y colocarnos en el directorio donde se encuentra nuestro archivo ejemplo. Una vez compilado el programa y ahora que tenemos el archivo “ejemplo.class.8\bin Una vez ubicados en el directorio llamamos al comando compilador del programa: Como ejecutar un programa. podemos proceder a ejecutarlo.C:\jdk1.Java: del Grano a su Mesa (Versio n 1. volverá a mostrar la línea de comando sin poner nada en pantalla: C:\WINDOWS\Desktop\temp> y en el directorio donde están los programas. es probable que sea o porque java no esta instalado en el computador. en un lenguaje que el computador si puede comprender.class que contendrá el programa ya compilado. generara el archivo ejemplo. Si todo está bien.class”. En este caso.3) Capi tulo I: Principios Ba sicos de Java En caso de que no se ejecute el comando javac.1. y generalmente no lo esta (karma computin). es decir.java mediante el comando “cd”. y que no se ejecuta: “java ejemplo. 13 14 . generar el archivo ejemplo. El cual.class”. y no javac (javac ó java compiler). si todo esta bien.

3) Capi tulo I: Principios Ba sicos de Java Si lo corregimos y lo volvemos a compilar. lo que signifi ca que esperaba la palabra “class” que es claramente el error en que incurrimos.java. ^ En general. En los otros dos casos aparece la frase “cannot resolve symbol” y destacando la palabra “Console”. Por ejemplo.Java: del Grano a su Mesa (Versio n 1.println ("Aqui le falta un punto y coma") ^ El primer error nos dice que en la línea 4 esperaba que hubiera un “. EjemploDeError. al final de ella.java:3: cannot resolve symbol symbol : class Console location: class EjemploDeError Console c = new Console().3) Capi tulo I: Principios Ba sicos de Java Java: del Grano a su Mesa (Versio n 1. ^ EjemploDeError.java:3: cannot resolve symbol symbol : class Console location: class EjemploDeError Console c = new Console().' expected c. Lo que está abajo de la primera línea de error es la línea y está marcado el inicio de la palabra que está mal escrita: clas EjemploDeError { ^ Esta es la lınea errada.println c. o no está definido el CLASSPATH como indicamos anteriormente o faltan las clases.java:4: '.println } } (String[] args) { = new Console(). Este era el problema que habíamos dejado para probar.java:3: cannot resolve symbol symbol : class Console location: class EjemploDeError Console c = new Console().” al final de la línea. es decir. veamos el siguiente programa con errores: clas EjemploDeError { static void main Console c c. Corrijamos todos los errores y veamos como queda: C:\WINDOWS\Desktop\temp>javac EjemploDeError. ("Aquı le falta un punto y coma") ("Esta lınea esta ok"). Existen 2 tipo de errores: de compilación y de ejecución: Errores de Compilación Los errores de compilación son aquellos que salen cuando estamos compilando (usando javac) nuestro archivo .java EjemploDeError.java:3: cannot resolve symbol symbol : class Console location: class EjemploDeError Console c = new Console(). También no hemos puesto las clases de la consola para que veamos qué ocurre. Éste es el error. ^ 3 errors C:\WINDOWS\Desktop\temp>_ Los Errores en Java Lo más común cuando escribimos programas en Java es que tengamos errores. y en la línea 4 hemos dejado sin .java:1 ‘class’ or ‘interface’ expected Indica el archivo y el número de la línea del error. 15 16 .. ^ EjemploDeError. Lo que significa que fue compilado satisfactoriamente.' expected c. el error cambiará: C:\WINDOWS\Desktop\temp>javac EjemploDeError.java:1: 'class' or 'interface' expected clas EjemploDeError { ^ 1 error C:\WINDOWS\Desktop\temp>_ Ahora tenemos 3 errores (como dice la última línea). los errores de compilación son aquellos que son causados por un problema en la sintaxis o que no dependen de los valores de variables.class en el CLASSPATH.java C:\WINDOWS\Desktop\temp>_ El que nos salió en este momento nos dice que “esperaba un class o interface”. Indica donde esta el error en la lınea. EjemploDeError. métodos e ingresos de datos que ocurran al momento de ejecutar. Nótese que hemos deliberadamente puesto clas en vez de class en la definición de la clase. Si lo escribimos y lo intentamos compilar en java obtendremos el siguiente error: C:\WINDOWS\Desktop\temp>javac EjemploDeError. De hecho el compilador nos lo dice: EjemploDeError.java:4: '. Al ver este caso podemos decier inmediatamente que “clas” está mal escrito. 2 de ellos ocurren por causa de la Console (2º y 3º) y otro ocurre por falta del .java EjemploDeError.println ("Aqui le falta un punto y coma") ^ EjemploDeError. Esto ocurre porque no encuentra el archivo Console.

StringIndexOutOfBoundsException: String index out of range: -1 at java. El intérprete de java3 ejecuta un programa y al momento de encontrar un error (que no fue detectado por el compilador) lo envía a pantalla en forma de Excepción (Exception). 3 El Intérprete de Java (Linker) es quien se encarga de ejecutar el . ya que pueden darnos dolores de cabeza como nos pueden salvar la vida en otros casos. int x = c. No tenemos el código fuente de esa clase. a diferencia de otros lenguajes de programación.StringIndexOutOfBoundsException String index out of range -1 Tipo de excepción que ocurrió. ya que se pueden manipular. Más adelante en el curso utilizaremos las excepciones como un apoyo a la programación en Java al momento de incurrir en errores de ejecución. String s = "Un texto".String. Las excepciones son algo súmamente delicado.java.charAt(Unknown Source) at EjemploDeError. En este caso.charAt(-1)). Su lectura es de abajo hacia arriba.println(s.main(EjemploDeError.charAt(-1)). Sigamos más abajo. y nuevamente debemos presionar Control-C para terminar la ejecución del programa. } } Si notamos bien en la línea (ya que por tema de espacio. Si nosotros hacemos caso e ingresamos “a” ocurre: Unable to convert to int Esto nos dice que está mal lo que intentamos ingresar y el programa se pega y debemos presionar Control-C en la ventana de MS-DOS que invocamos “java EjemploDeError”. Con estos valores podemos percatarnos que el error ocurrió porque traté de acceder con el –1 fuera del rango de un String.class en la JVM.java:7) En este caso hay 1 error obvio que está en el charAt(-1). Esto lo veremos más adelante en el curso. 17 18 .lang. c.println(s. Lo que sigue es llamado Stack de Ejecución y nos indica cuántos métodos hemos llamado desde que se ejecutó el primer main. Ahora tenemos algo distinto al error de conversión. pero veamos el otro que puede ocurrir también. Pequeña descripción de la excepción. pero igualmente una excepción que debemos interpretar. c.String. El que llamó a charAt es el main de la clase EjemploDeError. Probemos ahora ingresando un número (correctamente) para que caiga en la otra línea: C:\WINDOWS\Desktop\temp>java EjemploDeError Exception in thread "main" java.Java: del Grano a su Mesa (Versio n 1. Si ejecutamos este programa nos sale en pantalla: Ingresa una letra?_ Si lo analizamos detenidamente (de arriba hacia abajo) dice: a) b) c) d) e) Se cayó en el método charAt de la clase java. el stack es: at java. Valor que causó la excepción.lang. cada línea nos indica en qué archivo y línea ocurrió el error.java:7) Por lo que si vamos a la línea 7 del archivo encontraremos: c.println (”Ingresa una letra?á). las 3 primera líneas son en rea lidad 1 sola) esta nos indica qué ocurrió: java. que es exactamente el problema que queríamos encontrar.lang. Veamos un programa ejemplo que tenga errores de ejecución: class EjemploDeError { static void main (String[] args) { Console c = new Console().3) Capi tulo I: Principios Ba sicos de Java Java: del Grano a su Mesa (Versio n 1. comenzando por el main en la última línea y acabando por el método más interno en la primera. La línea que está haciendo esta invocación es la línea 7.3) Capi tulo I: Principios Ba sicos de Java Errores de Ejecución Los errores de ejecución creo que son los más difíciles de justificar y también los más complejos de leer en Java.main(EjemploDeError.charAt(Unknown Source) at EjemploDeError.lang. El archivo que posee esta clase es EjemploDeError. También. ya que no se puede sacar un valor menor a 0 de un string.String.lang.readInt().

es decir la pueden llamar. PROTECTED: Solo las clases "hijas" pueden llamarlo (concepto de herencia más avanzado que veremos luego).. } se debe guardar en Ejemplo. OBJETO: Un objeto es una variable de un tipo Clase que es creada con un new: Console c = new Console(). Es decir: § PUBLIC: Se puede utilizar esta clase desde cualquier lugar. en la clase Math tenemos el método: public class Ejemplo { . es accesible. § Sin nada: Se puede utilizar en el mismo directorio. PRIVATE: Solo la misma clase que lo define puede llamarlo. Uso de STATIC: El uso de STATIC en los métodos solo nos explica cuando utilizamos un "OBJETO" o cuando utilizamos una "CLASE" para invocar el método.. OBLIGA a guardar la clase en un archivo con el MISMO NOMBRE (ojo con las mayúsculas y minúsculas): y es por esta razón que necesitamos al objeto "c" para invocarlo como: c..java o miprograma.Java: del Grano a su Mesa (Versio n 1. Es decir: § § § § PUBLIC: Lo puedo llamar desde cualquier parte (clases dentro del mismo directorio o de otro directorio). su invocación sería del tipo: double x = Math.java..java. Por ejemplo.random(). Todos los métodos de la clase Console están declarados sin la palabra STATIC. ya que por definición si no ponemos nada. METODOS: La privacidad (a nivel de métodos) indica desde DONDE puedo llamar un método. Sin nada: Para las clases del mismo directorio es pública.3) Capi tulo I: Principios Ba sicos de Java Java: del Grano a su Mesa (Versio n 1. la firma de "println" sería: public void println(String s) { .java y no en ejemplo. Desde otro directorio no existe.. Aquí el nombre del archivo JAVA no importa. es decir: y como posee el "static". en este caso "c" es un objeto de tipo "Console".. la privacidad se refleja casi de la misma forma que los métodos. class Ejemplo { .. por ejemplo. } se puede guardar en Ejemplo.java 19 20 . CLASE: Las llamadas a métodos que se realizan a través del nombre de la clase REQUIEREN la palabra "static" en su definición.println("Esto usa un objeto"). ejemplo.. CLASES: A nivel de clases. } public static double random() { . } Estas palabras no son OBLIGATORIAS.3) Capi tulo I: Principios Ba sicos de Java Principios Avanzados Uso de PUBLIC/PROTECTED/PRIVATE: Estas sentencias (que pueden estar en las firmas de los métodos o en las definiciones de las clases) nos indican el nivel de "PRIVACIDAD" que tiene la clase.

recuperar) el n° ingresado por la persona usando el teclado. Terminar el programa 21 22 . • Entrega (retorna) el número como resultado. int n. • Lee (obtiene. • Lee un número entero desde el teclado y lo asigna (guarda) a (en) la variable n.print(”Por favor ingresa un Nº:á). n = C. • Escribe en la pantalla la frase encerrada entre comillas (“”). 4. • Posee un nombre que la identifica (letra seguida de latras. • print es un método (función) que se aplica al objeto C y que escribe su argumento en la pantalla.readInt().3) Capi tulo II: Conceptos Ba sicos Capítulo II: Conceptos Básicos Motivación COMPUTACION Programa Traducción de un “Algoritmo” en un lenguaje de programación que el computador pueda interpretar para resolver el problema. • Variable • Representación simbólica de un valor (número). • int indica que el tipo de número que puede almacenar la variable es un entero (números sin punto decimal). • Representa una ubicación (celda) en la memoria del computador. C. +: operador). C. reconoce) el número. • Escribe en la pantalla la frase “Gano yo con el”. Escribir (mostrar) en la pantalla la frase “Por favor ingresa un N°:” 2. iremos línea a línea analizando qué significa y cómo se utilizó para traducir el algoritmo anterior. dígitos o _).Java: del Grano a su Mesa (Versio n 1. un “algoritmo” para resolverlo se describe a continuación: 1. Para efectos de estudio en este curso. Escribir un programa que instruya al computador para que establezca el siguiente diálogo con una persona (usuario): Por favor ingresa un Né: 123 Gano yo con el 124 Conceptos Algoritmo Se define como “Algoritmo” a la serie de pasos o “Etapas” (que debe realizar el computador) para resolver un problema En el problema planteado arriba. Leer (obtener. • n+1 Expresión aritmética (n: variable.print(“Por favor ingresa un N°:”).readInt(). • Escribe en la pantalla el valor de la variable n más uno. Computador Problemas Soluciones Para comprender mejor el lenguaje. el lenguaje de programación utilizado para interpretar nuestros algoritmos es Java. C. 3. 1: constante. • C es un objeto que representa la consola (pantalla y teclado) del computador. int n. C. n = C. • readInt() es un método (función sin argumentos) que: • Espera que el usuario ingrese un número (tecleando dígitos y ENTER). • Capacidad: un valor del tipo indicado.3) Capi tulo II: Conceptos Ba sicos Java: del Grano a su Mesa (Versio n 1. • Para abreviar las dos líneas anteriores se puede utilizar int n = C.readInt().print(”Gano yo con el ”).print(“Gano yo con el “). • • • • • • • • • Algoritmos y Estructuras de Datos Lenguajes de Programación Ingeniería de Software Comunicación Humano-Computador Computación Numérica y Simbólica Bases de Datos Usuario Inteligencia Artificial Arquitectura de Computadores Sistemas Operativos Razonamientos: • • • algorítmico lógico capacidad para resolver problemas Traduzcamos el algoritmo que definimos para el problema inicial y veamos como queda en lenguaje Java: C. • Declara n como una variable entera.print(n+1). Escribir en la pantalla: • “Gano yo con el “ • el número (ingresado por la persona en el paso 2) sumándole uno.print(n+1). C.

*.Java: del Grano a su Mesa (Versio n 1. // Se crea una Consola para entrada y salida de datos Console C = new Console().4248 23 24 . Solución 1. escribe y después posiciona el cursor al comienzo de la siguiente línea en la pantalla Java: del Grano a su Mesa (Versio n 1.. • El computador no traduce esta línea. Console: clase de interacción predefinida con métodos para leer y ecribir. Console C = new Console(). sin embargo para el área son complétamente distintos: Caso d entero: Perımetro = 9..println(”Calcular perımetro y area de circuloá). La mayor cantidad de los problemas planteados a la computación se basan en esta básica interacción entre usuario-computador..println(“Gano yo con el “ + (n+1)).println(”Perımetro = á + (pi * d)). C. // Se calcula y despliega los resultados de la operacion C. } } Solución 2 Esta solución considera que el diámetro es un número real y que PI es un número real: // Se declara la constante pi final double pi = 3.pow(d/2. // Jalisco: programa que nunca pierde • Comentario hasta el final de la línea. se presenta a continuación.1416. • Problemas Escribir un programa que establezca el siguiente diálogo. class Jalisco { static public void main(String[] args) { Console C = new Console().1416. // Se calcula y despliega los resultados de la operacion C. • Todo programa Java debe estar contenido en una clase. C. C.print(“Gano yo con el “ + (n+1)). De la misma forma que en la anterior explicación se presentó. int d = C.readInt(). C: objeto de clase Console. Calcular perımetro y area de circulo Diametro ? 3 Perimetro = . Los resultados que se obtienen para el perímetro son iguales. int n = C.pow(d/2.println(”Gano yo con el ”+ (n+1)).readInt(). Area = . // Se obtiene el valor del diametro del cırculo C. • Encabezamiento estándar (significados se explicarán posteriormente). 2)).print(”Diametro ? á). C. se pueden realizar muchos más programas que este sencillo ejemplo.print(”Diametro ? á). C. static public void main(String[] args) {…} • Método que contiene instrucciones del programa principal (main). para hacerla sencilla y que el computador pueda obtener la información necesaria para resolver el problema.readDouble(). double d = C.println(”Calcular perımetro y area de circuloá). import java. Esta solución considera que el diámetro es un número entero y que PI es un número real: // Se declara la constante pi final double pi = 3. Mejora: C. // Se obtiene el valor del diametro del cırculo C. se detalla línea a línea la ejecución del programa con la traducción que el computador realiza. // Se crea una Consola para entrada y salida de datos Console C = new Console(). • Con estos conceptos.println(”Area = á + ( pi * Math.println(”Perımetro = á + (pi * d)).println(”Area = á + ( pi * Math. C. Solución al Problema Una solución completa al problema planteado. la cual sería fácilmente probada en el laboratorio.3) Capi tulo II: Conceptos Ba sicos • Operadores Aritméticos válidos: • Adición: (+) • Substracción: (-) • Producto: (*) • Cuociente: (/) Para abreviar las dos líneas anteriores se puede utilizar C. • Inserta declaraciones necesarias para que programa lea/escriba class Jalisco {…} • Define la clase de nombre Jalisco.*. • (+) : Este operador se convierte en un concatenador (añade) de caracteres.awt..print(”Por favor ingresa un Nº:á). // Jalisco: programa que nunca pierde import java. puesto que es solo una línea informativa y no influye en la ejecución del programa. 2)).3) Capi tulo II: Conceptos Ba sicos • • • Abre una ventana para leer y escribir.awt.

4 Ver http://www. public int maxcol(). para luego pasárselo a los programas que la utilizan. Leer un valor desde el teclado utilizando la consola. public Console(String). Obtener el tamaño de columnas y filas que puede contener la consola abierta. public void println(String).3) Capi tulo II: Conceptos Ba sicos Caso d real: Perımetro = 9.html#Console para mayor información. public void hideCursor(). Limpiar la consola. public short readShort(). Descripción Constructores de la clase Console por defecto.4248 Area = 7. puesto que al operar un cuociente (caso que puede dar un resultado con decimales) con ambos valores enteros. el resultado SIEMPRE será entero.Java: del Grano a su Mesa (Versio n 1. En este documento se utiliza la mayor parte de los capítulos por simplicidad. Diseñar el diálogo y escribir un programa que calcule la velocidad de un móvil en km/hora... dadas la distancia (en metros) y el tiempo (en segundos). Le definición de Console permite realizar las siguientes funcionalidades: Método public Console(). Programa para el siguiente diálogo Calcular perımetro y area de rectangulo Largo ? 2 Ancho ? 3 Perımetro = . public long readLong(). String). public void showCursor(). Sintaxis Clase Console4 Esta clase es simplemente un encapsulamiento de la Entrada y Salida estándar de Java.5 entero real Area = 3. cómo se comunica nativamente Java con el usuario.holtsoft. 2. no obstante la utilización de System para entrada y salida estándar también se detalla en caso de desear utilizarla. por definición. y con tamaño y título respectivamente. public int maxrow(). Inventar un problema.0686 Este fenómeno ocurre normalmente en Java. con título. public byte readByte(). Es así como clases hechas como Console evitan que uno conozca realmente donde está el ingreso de datos y el despliegue de ellos en la pantalla o interfaz (gráfica de texto) que Java provee. Console es un Applet que utiliza un Canvas en donde se escriben las líneas de texto para la salida estándar y que permite el ingreso de datos a través del teclado.. diseñar el diálogo y escribir.0 = 1.int. public int readInt(). public double readDouble(). Problemas Propuestos 1. Imprimir en la consola. Area = . public boolean readBoolean(). public Console(int.com/java/hsa_package.3) Capi tulo III: Entrada y Salida Capítulo III: Entrada y Salida Motivación La I/O (Entrada/Salida) estándar es. 25 26 . De hecho. public float readFloat()..1416 Java: del Grano a su Mesa (Versio n 1. public void clear(). public void print(String). Por ejemplo: 3/2 =1 3 / 2. Mostrar y ocultar el cursor. 3.

int.): Imprime en pantalla lo que está entre paréntesis (literal o expresión) y salta una línea después de hacerlo. no es tan sencillo como poner: System. public void setTextBackgroundColor(Color). Bastante sencillo. int. int. Veamos ahora como se leen datos con System. Para ver cómo funcionan algunos de los métodos gráficos. int. int. int. Limpiar un trozo del lienzo. public void setFont(Font). no necesita de una referencia a dicha clase: System. public void drawMapleLeaf(int. int.readInt(). public void drawLine(int. con System. public String readLine(). // ESTO ESTA MALO Dibujar todo tipo de figuras.. public void fill3DRect(int. Esta línea reemplazaría a la declaración de la consola en el caso de utilizar Console. public void setTextColor(Color). int.in es una referencia estándar a la entrada desde el teclado. boolean). public void fillPolygon(int[]. int[]. Console c = new Console(). int. ver sección Canvas en página 151. int.out posee las funcionalidades de imprimir en pantalla que han trascendido a objetos como la Console o PrintWriter: Dar tipografía (Font) y color al texto de la consola5.println(. lo que antes imitaba a: Como te llamas? Juan Hola Juan.print(”Como te llamas?á). public String readString(). int. System. int). int.print(. int. int. public void fillMapleLeaf(int.awt. int.. int).Color).out es mucho más sencillo: al ser una variable estática de la clase System. public void drawPolygon(int[]. int).out. Dar color al pincel. public void copyArea(int. int. int. Y también existen formas de utilizarla como un lienzo gráfico para dibujar 6: Método public int maxx(). int). int.println(”Hola mucho gustoá). public void drawArc(int. int). Aunque les gustaría mucho. public void fillRect(int. El caso de entrada de datos es más complejo y es lo que lleva a los programadores a crear objetos como Console. int). int. public void drawString(String. public void fillOval(int. int. int). referirse a Canvas en página 151. int.in. int. int. Es decir. int. int. int. int). int).out. int. Descripción Obtener tamaño del lienzo. int). int. public void drawRoundRect(int.. int. Copiar un trozo del lienzo. c. int.Java: del Grano a su Mesa (Versio n 1. era: Console c = new Console().out. J System. int). int. int. Por ejemplo.println(”Hola mucho gustoá). int. Por ejemplo: System. public int maxy(). int). la cual se basa en una serie de funcionalidades estáticas (definidas como static) que permiten interactuar nativamente entre el sistema y el usuario (o los periféricos que tenga). public void fillArc(int. • • System. int. int.3) Capi tulo III: Entrada y Salida public char readChar(). int. int. int). public void drawStar(int.3) Capi tulo III: Entrada y Salida Ahondando en este ejemplo.in)). 27 28 . public void drawRect(int. int. int.. int. int. Clase System En algún lado ya se ha utilizado la clase System. public void draw3DRect(int. lo que con Console imitaba el siguiente diálogo: Hola mucho gusto. mucho gusto y que con Console quedaba más o menos así: 5 6 Para ver cómo funcionan los colores. public void clearRect(int. int). int). int. Java: del Grano a su Mesa (Versio n 1. System. public void drawOval(int. int. public void fillRoundRect(int. int). boolean). int. esto es: BufferedReader in = new BufferedReader( new InputStreamReader(System. pero similar a lo que pasa con los archivos de lectura. int. int[]. public void setColor(java. public void fillStar(int. int).out es un objeto que posee una referencia a la pantalla de salida estándar de Java. ya que también son entradas. int. Es decir. Sin embargo su uso es un poco distinto. int.): Imprime en pantalla lo que está entre paréntesis (literal o expresión) pero sin saltar la línea al final. int). c.

Problema Propuesto Tenemos el siguiente programa desarrollado con Console: Console c = new Console().println(”Hola ” + nombre + ”.println(”Siempreá).charAt(0). Expresiones Parentizadas Operadores Unarios Operadores Multiplicativos (*. String nombre = in. Estas son: 1.3) Capi tulo IV: Asignaciones. La sintaxis de una asignación es: 7 Conversiones String > int y String > double. por lo que métodos readInt y readDouble quedan completamente fuera de lugar. no es tan distinto.print(”Como te llamas?á). Solo se puede utilizar readLine() y leer solo Strings (hay que hacer un cast o conversión explícita 7). la siguiente línea es una expresión: ((6 * a) – (5 + b) / c) * x2 La evaluación de las expresiones sigue las mismas reglas del álgebra. case ”Oá: c. String p = c. System. 2. Java: del Grano a su Mesa (Versio n 1. toda la razoná). case ”Iá: c. case ”Uá: c. Hey. /) Operadores Aditivos (+. } } Concepto A continuación haremos las definiciones básicas necesarias para comenzar con los conceptos de programación y que nos serán útiles a través del curso: Expresión Es una combinación de operadores.readLine(). default: c. En donde: 29 30 . while (true) { c. System.print(”Respuesta: ”). permite la obtención de un valor reutilizable en otro lugar del programa. 3.3) Capi tulo III: Entrada y Salida String nombre = c.println(”Es muy probableá).readLine(). al ser evaluada.out y System.println(”Quizasá).print(”Pregunta: ”).toUpperCase()) { case ”Aá: c. Pero el cambio viene al trabajar con números. Asignación La asignación es una instrucción en la cual el computador da un valor para ser almacenado dentro de una variable o espacio de memoria física. Expresiones y Tipos de Datos Capítulo IV: Asignaciones. switch (p.Java: del Grano a su Mesa (Versio n 1.out.println(”No es ciertoá).println(”Si.out. c. 4. Expresiones y Tipos de Datos Motivación Nos gustaría mucho realizar el cálculo de porcentajes de elección de 2 candidatos instruyendo al computados para que establezca el siguiente diálogo con el usuario: Calcular porcentajes Votos candidato 1? _ Votos candidato 2? _ Total de votos = N– Candidato 1 = xxx % Candidato 2 = xxx % Ahora cambiaría un poquito como: BufferedReader in = new BufferedReader( new InputStreamReader(System. variables y constantes del lenguaje que. case ”Eá: c. mucho gustoá). mucho gustoá). -) Trate de convertir este código para que utilice System. <variable> = <expresion>.println(”Hola ” + nombre + ”.in)).readLine(). se evalúan de izquierda a derecha. Para ver claramente esto.println(”Nuncaá). ya que BufferedReader solo puede leer líneas de texto. c.in como entrada y salida de datos Y en el caso de existir operadores de igual prioridad.

Expresiones y Tipos de Datos <expresión> se escribe en una línea (hacia el lado) y no en varios niveles.println(”Calcular porcentajesá).648 -263 -3. Por ejemplo: double a = 10. podemos realizar las siguientes asignaciones a = v1 + v2. c. total = v1 + v2. operadores unarios (+. Para convertir tipos de datos se usa un CAST explícito o implícito que transforma.println(”Candidato 2 = ” + 100. Esta definición es bastante técnica.3) Capi tulo IV: Asignaciones.0*v1/total).0. Por ejemplo: int a = 6. se debe utilizar la siguiente sintaxis: <tipo de dato> <nombre de la variable>. int v1 = c. -).3) Conversión de Datos Capi tulo IV: Asignaciones. en donde <nombre de la variable> es un nombre cualesquiera que le permita identificar a ese espacio de memoria separado para el tipo de dato indicado. double b = (double) a. La comprenden variables.7 x 10301 Precisión (dígitos) 3 5 10 19 7 15 int total.483. c. En Java existen los tipos de datos numéricos: Tipo Byte Short Int Long Float Double Nº Bits 8 16 32 64 32 64 Mayor Valor 127 32. esta expresión es EVALUADA y el valor obtenido reside en el espacio reservado de memoria para dicha variable. /). operadores binarios (+.readInt().print(”Votos candidato 1á).768 -2. c. double b = a. // Cast explıcito Solución Console c = new Console(). Por ejemplo. por lo que simplificaremos un poquito a la siguiente definición de tipo de dato: Los cast explícitos se deben hacer desde tipos de más grande tamaño (ver tabla) hacia tipos más pqueños. *.647 263 – 1 3. Por ejemplo: int i.4 x 1038 1.767 2. constantes. a = 2. métodos y expresiones entre paréntesis. // Cast implıcito Tipos de Datos Son definiciones de espacios de memoria en los cuales se almacenan valores específicos. Antes de ser asignada a una variable. -. int v2 = c.0*v2/total) Para definir o declarar una variable con cierto tipo.4 x 1038 -1.println(”Candidato 1 = ” + 100. 31 32 . Los cast implícitos se pueden hacer desde tipos de más pequeño tamaño (ver tabla) hacia tipos más grandes.147. c. i = 5.483. c. c.readInt().println(”Total de votos = ” + total).147. Expresiones y Tipos de Datos Java: del Grano a su Mesa (Versio n 1.Java: del Grano a su Mesa (Versio n 1. a = (5 ú a) * 3 / v1.print(”Votos candidato 2á). convierte y/o trunca desde un tipo de dato a otro. Es una clase de números (o datos) con los cuales se pueden definir las variables que los almacenarán.7 x 10301 Menor Valor -128 -32.

En general.1. c.0) abs(-3) pow(2.print(”Ingrese ahora un Area de circunferencia?á).y) min(x.1) max(4. Math. i d d de arg de arg d Ejemplo atan(1.readDouble(). Para que veamos como se invocan los métodos. En Java por ejemplo existe una gran librería matemática que incluye métodos para la raíz cuadrada.3) Capi tulo V: Me todos y Funciones Función atan(x) round(x) floor(x) ceil(x) max(x. f d d i.print(”La tangente original es: ”).f.0 -1.PI9/2 Math.tan(ang)). c.print(”La tangente calculada es: ”).0 5. tangentes. potencias.f.E está definida en la librería matemática. Veamos unos ejemplos de utilización de funciones de la librería matemática: // Calculo de Area y Perımetro c.Java: del Grano a su Mesa (Versio n 1. mínimos. máximos.. senos. d d d d d d d d d Tipo Resultado double del arg d d d d d d d d Ejemplo sqrt(4.PI/4 5L 4.5) floor(4.0 3 8.3) Capi tulo V: Me todos y Funciones Java: del Grano a su Mesa (Versio n 1.println(Math. c. También reciben el nombre de Métodos.PI * r).print(”Ingrese el radio de la circunferencia?á). Estas funciones están escritas para que los programadores las utilicen en sus códigos sin volver a escribir los subprogramas que realizan esas funcionalidades.PI/2) cos(Math. c. Math. requiere de un nombre (del método) y sus parámetros (si es que tiene).E) sin(Math.0 Math..PI * Math.9) ceil(4. redondeo de valores y números aleatorios.0) Resultado 2. c.print(”Ingrese un angulo en radianes? ”).d i. 6. veamos aquellos que se encuentran en la librería matemática: Función sqrt(x) abs(x) pow(x. 6.sqrt(a / Math. // Calculo de la tangente a partir de otras funciones c.1 0.sin(ang)/Math. c. x ≥ 0 |x| xy ex logex seno de < x (x en radianes) coseno de < x tangente de < x arco-seno de x arco-coseno de x Tipo Argumento double i.readDouble().print(”El area de la circunferencia es: ”). exponenciales. 33 34 . f. Significado √ x.l. // Calculo de un radio a partir del area c.println(Math. Concepto Funciones/Métodos Trozos de código que pueden ser reutilizados a través de una llamada a su definición con ciertos parámetros.PI)).println(Math.l.0 6. c.y) exp(x) log(x) sin(x) cos(x) tan(x) asin(x) acos(x) 8 9 En este ejemplo podemos ver como utilizamos un método de la clase matemática dentro de una expresión.E8 1. l.PI está definida en la librería matemática.1[ Tipo Argumento d d.1.println(2 * Math.PI) tan(Math.5) min(4. c. double r = c.print(”El radio de la circunferencia es: ”). c.pow(r.5) random( ) Resultado Math.0) acos(-1. 2)).readDouble(). double ang = c. c.y) random( ) Significado arco-tangente de x redondear x n / n ≤ x < n+1 n / n-1 < x ≤n mayor entre x e y menor entre x e y Nº al azar en [0.0 1. Invocación o Llamada de un Método La llamada es la forma en que el lenguaje invoca o permite la ejecución del trozo de código escrito dentro de un método.print(”El perımetro de la circunferencia es: á).0 1.0) round(4.0. double a = c. cosenos.d Tipo Resultado d l.3) exp(1) log(Math. En este ejemplo podemos ver que se pueden componer en una misma expresión distinto métodos matemáticos sin necesidad de utilizar variables adicionales.println(Math.cos(ang)).0 Math.PI En este ejemplo podemos ver como se puede utilizar una expresión como argumento de un método de la clase matemática. logaritmos.x.pi/4) asin(1.5 4. Capítulo V: Métodos y Funciones Motivación Existen muchas funciones matemáticas y no matemáticas en Java que se encuentran pre definidas.

double val2. Problema Escribir una función que calcule el máximo de 3 números y otra el mínimos de 3 números reales. Puede tener entre 0 y cualquier número de argumentos. resta (val1. Argumento n-ésimo del método.min(val2.3) Capi tulo V: Me todos y Funciones static double suma (double a. double val2. Por ejemplo. } static double multiplica (double a. } static double division (double a. <arg2>. nombre y argumentos se le llama Firma del Método. Math. .) { <instrucciones> return <valor de retorno>. que tenga la siguiente firma: static int aleatorio (int x. podemos escribir el código de los métodos de la segunda motivación: 35 36 . para utilizarlos a distintos niveles. } Y para utilizar esta divertida versión es: double val1 = 5.max(val1. } Motivación Quisiéramos escribir trozos de código que permitan realizar las operaciones básicas de la aritmética (sumar. división y multiplicación). el resultado ∈ [x.println c.println c.Java: del Grano a su Mesa (Versio n 1. double b) { return a + b. } Propuesto Escribir una función que calcule el número aleatorio entre una cota inferior x y otra cota superior y. val3)).max(val2. Math. double val3) { return Math.println c. double val3) { return Math.. double b) { return a * b. Es por eso que nos gustaría crear una estructura de programación que nos permita almacenar subprogramas pre-hechos para ser utilizados dentro de nuestros propios programas. } Desafíate: Saca ahora el de en medio La combinación entre tipo. definamos un método que retorne el valor de una raíz quinta: static double raizQuinta (double x) { return Math. -b).. multiplica (val1. Nombre con el cuál es identificado el método. resta. val2)). c.println (val1 (val1 (val1 (val1 + + + + ” ” ” ” + * / ” ” ” ” + + + + val2 val2 val2 val2 + + + + ” ” ” ” = = = = ” ” ” ” + + + + suma (val1.pow(x. double val2 = 10. double b) { return suma(a. La forma general de declaración de un método es la siguiente: static <tipo> <nombre> (<arg1>. y] Solución Con esto definido.3) Capi tulo V: Me todos y Funciones Java: del Grano a su Mesa (Versio n 1. 1/5). division (val1. Valor que retorna el método a su línea llamadora y que es resultado del procesamiento realizado en el trozo de código o cuerpo del método. } static double min3 (double val1. val2)). int y) y su llamada será (en negritas): double rq = raizQuinta(26). static double max3 (double val1. } static double resta (double a. val3)). double b) { return multiplica (a. Trozo de código que se procesa durante la ejecución del método. En donde: <tipo> <nombre> <argn> <instrucciones> <valor de retorno> Tipo de dato del valor que se retorna al final de la ejecución del método. val2)). 1/b).min(val1. Es decir. val2)). Concepto Declaración de un Método La declaración de un método es la escritura del subprograma que resuelve la funcionalidad del mismo.

4. Recibir los valores de los sumandos dentro del subprograma (llamada del método). Guardar temporalmente el valor de la división de los valores obtenidos en la llamada. Veamos el algoritmo para la división: 1. Las condiciones son expresiones que retornan valores de verdad (verdadero o falso) y que condicionan la ejecución de instrucciones indicadas en el condicional.. Concepto Condicionales Un condicional es una instrucción que permite ejecutar un trozo de código si y solo si cumple con una condición o valor de verdad. 2. Por ejemplo: boolean var1 = true. la segunda parte (o else) corresponde a decir “si la condición NO se cumple” o el famoso “si no” o “de lo contrario”.. 2. Antes de continuar. Es sumamente sencillo. Así que abordaremos un nuevo tipo de dato que soporta almacenar esto: bolean. Verificar si el dividendo es igual a 0 a. Por ejemplo: if (var1) . Como podemos ver. El bolean es un tipo de dato especial que solo puede almacenar VERDADERO o FALSO. Algo como: Si la condicion es cierta Ejecuta las instrucciones cuando es cierta Si no es cierta Ejecuta estas otras instrucciones. Esta segunda parte es opcional. Guardar temporalmente el valor de la suma de los valores obtenidos en la llamada. } La primera parte del condicional corresponde a la condición. Retornar el resultado guardado en el paso 3. Retornar el resultado guardado en el paso 2.3) Capi tulo VI: Condicionales Java: del Grano a su Mesa (Versio n 1. necesitamos algo que nos permita ejecutar (a) solo si el dividendo es 0. double b) { double r = a + b. La gracia es que se puede usar como condición sola en un if. 3. else. Algoritmo Veamos primero el algoritmo para la adición a modo de práctica: 1. Para este algoritmo no hay problema de escribir la solución: static double suma (double a. Valor de Verdad Todos saben cuál es la definición e este concepto.. Su forma general es como sigue: if (<condicion>) { <instrucciones si es verdadero> } else { <instrucciones si es falso> } Una versión alternativa y avanzada sería: static double suma (double a. debemos insertar dos nuevos concepto: Ok. 37 38 .. Capítulo VI: Condicionales Motivación Escribir subprogramas que realicen los operaciones de adición y cuociente de número reales. Retornar 0 (indicando que era 0 para que no haya error) 3.Java: del Grano a su Mesa (Versio n 1. double b) { return a + b. } Sintaxis Los condicionales utilizan un comando especial llamado if . considerando que no se puede dividir por 0. Recibir los valores de los operandos del cuociente. return r. else .3) Capi tulo VI: Condicionales El concepto de condicional es bastante básico. boolean var2 = false...

} else if ( n < 0 ) { c. double b) { if (b == 0) { return 0. int n = readInt().println(n + ” es igual que 0á). } Un ejemplo que utiliza todo lo anterior sería condicionar si es par o impar un número: c. } else { c. } O una muy similar. else. mayor o igual. } Esto es muy fácil de visualizar.3) Capi tulo VI: Condicionales Operadores Lógicos Un operador lógico es un comparador que permite operar valores. double b) { double r = 0. } double r = a / b. } else { c. } Caso Especial Hay un problema muy claro. if (b != 0) { r = a / b.. double b) { double r.print(”Numero?á). A > 5 && A < 10 A < 9 || A > 10 A mayor que 5 y menor que 10 A menor que 9 o mayor que 10 También. int n = readInt(). menor o igual. podemos utilizar una solución alternativa como: static double division (double a. Por último un ejemplo sencillo de que hacer solo si se cumple la condición: c.println(n + ”Es pará). A A A A A A > 5 < 3 >= 1 <= 0 == 4 != 4 OPERADOR OPERADOR OPERADOR OPERADOR OPERADOR OPERADOR MAYOR QUE MENOR QUE MAYOR O IGUAL QUE MENOR O IGUAL QUE IGUAL QUE DISTINTO QUE En este ejemplo podemos ver 3 casos y como se pueden mezclar los distintos if . } else { r = a / b.println( ”BINGOá). es decir cambiar el valor de VERDADERO a FALSO o de FALSO a VERDADERO. Veamos un ejemplo más complejo considerando 3 casos distintos: c. } return r. } Operador de Negación: Este operador permite NEGAR un valor de verdad.println(n + ”Es impará). if (b == 0) { r = 0. cuando se utilizan muchos IF para distinguir distintos trozos con comparadores de igualdad.print(”Numero?á). Por ejemplo: 39 40 . if ( n == 123 ) { c. distinto o simplemente igual.. son eso). if ( n % 2 == 0 ) { c.println(n + ” es mayor que 0á). Solución La solución con este concepto se pone muuuuy sencilla y queda como: static double division (double a. pero algo mas inteligente: static double division (double a. Existe muchos operadores lógicos que describiremos a continuación: Comparador de Valores Numéricos: Permite comparar valores numéricos indicando si es mayor. variable o expresiones y retornar un valor de verdad (verdadero o falso). } En este último ejemplo podemos ver que el ELSE era completamente opcional. int n = readInt(). menor.Java: del Grano a su Mesa (Versio n 1.print(”Numero?á). ! (A == 5) SE TRADUCE POR A != 5 Conjunciones: Son operadores especiales que permiten unir distintos valores de verdad. } return r.3) Capi tulo VI: Condicionales Java: del Grano a su Mesa (Versio n 1.println(n + ” es menor que 0á). return r. Hablando un poco en español sería como el Y y el O (bueno. if ( n > 0 ) { c.

print(”La raız cuarta á). Problemas (a) Se desea escribir un método que calcula la raíz n-ésima de un número considerando que solo se pueden calcular raíces para números > 0 (caso de raíces pares). 2> 3> 4> 5> 6> La raız <n-esima> del numero es = XXXX.*. double x = c. reemplazando “n” por el valor de la raíz 1> import java. int raiz) 41 42 .print(”Opcion?á). int op = c.pow(base. case 4: c. } 2> 3> 4> 5> 6> // Programa principal (solucion parte b) public static void main (String[] args) { Console c = new Console(”Raicesá). } Considere que el término “<n-ésima>” debe indicar: § § § § “cuadrada” si la raíz es 2 “cuarta” si la raíz es 4 “quinta” si la raíz es 5 “n-ésima” en cualquier otro caso.print(”Opcion?á). switch op { case 1: <instrucciones break. c. int raiz) { if (raiz % 2 = 0 && base < 0) return 0. public class Raices { // Aquı se inserta el metodo raizN public static double raizN (double base.readInt(). case 3: <instrucciones break. case 6: <instrucciones break. case 5: <instrucciones break. if (op == 1) <instrucciones else if (op == 2) <instrucciones else if (op == 3) <instrucciones else if (op == 4) <instrucciones else if (op == 5) <instrucciones else if (op == 6) <instrucciones else <instrucciones Java: del Grano a su Mesa (Versio n 1.print(”Ingrese la raiz?á). que no sean variables).readInt(). // Indica que no se puede calcular return Math.print(”La raız cuadrada á). La firma del método es: public static double raizN (double base.XXX 7> } (b) Escriba un programa que imite el siguiente diálogo: Escriba el numero que desea obtener raız? _ Indique la raız? _ Al observar con detención esto. case 2: <instrucciones break. case: <instrucciones break. case 5: c. case 4: <instrucciones break. int n = c. c.3) Capi tulo VI: Condicionales public static double raizN (double base.readInt(). // Se escribe el resultado switch r { case 2: c. 1/raiz). pues si indentáramos quedaría realmente asqueroso. case: 7> en donde los case deben tener valores constantes (es decir. // Se calcula la raiz double raiz = raizN(x.Java: del Grano a su Mesa (Versio n 1.3) Capi tulo VI: Condicionales c.io. // Se imprime en pantalla el dialogo c.readDouble().print(”Ingrese el numero que desea obtener raiz?á).pow(base. n). // Indica que no se puede calcular 1> return Math. se puede tornar engorroso. int op = c. Existe una instrucción que nos puede salvar: switch. 1/raiz). int raiz) { if (raiz % 2 = 0 && base < 0) return 0.print(”La raız quinta á).

println(” del numero es = ” + raiz). porque esto definen un ciclo. Escribir texto “Triángulo” con el valor del triángulo (1) 5.... volver al punto 4 para el triángulo (contador+1) 12. a2 + b2 = c2 Para ello. Pedir y almacenar el resultado a la pregunta del punto 9 11. } c. pero lo más importante son los items 3 y 11 destacados.3) Capi tulo VI: Condicionales c. Escribir en pantalla la cantidad de triángulos calculados 13. Escribir en pantalla la pregunta “Desea Continuar (1=Si/2=No)?” 10.3) Capi tulo VII: Ciclos de Programa Capítulo VII: Ciclos de Programa Motivación Escriba un programa que permita calcular el valor de la hipotenusa de triángulos con los valores de los catetos dados por el usuario. Desea Continuar (1=Si/2=No)? _ Triangulo 2 a?_ b?_ Hipotenusa = . Incrementar el contador 9. Si el usuario ingresa 1.. 43 44 . Escribir en pantalla “Gracias por usar el programa” Este algoritmo se ve un poco más largo de lo común.print(”La raız ” + n + ”-esima á). Iniciar ciclo de programa 4. Pedir y almacenar cateto “b” 7. según la fórmula de pitágoras. } } Java: del Grano a su Mesa (Versio n 1. Escribir texto de bienvenida en pantalla 2. Pedir y almacenar cateto “a” 6. Iniciar contador del nº de triángulos calculados en 1 3.Java: del Grano a su Mesa (Versio n 1. Desea Continuar (1=Si/2=No)? _ Se han calculado 2 triangulos Gracias por usar el programa Suponemos que pone 2 Suponemos que pone 1 Algoritmo: 1. trate de realizar el siguiente diálogo: Calculo de la Hipotenusa de un Triangulo Triangulo 1 a?_ b?_ Hipotenusa = . Calcular e escribir en pantalla el valor de la hipotenusa del triángulo (1) 8.

Sintaxis while (<condicion>) { <trozo de codigo que se repite> } int contador = 1. <condicion>.println(”Se repite este texto en pantallaá). Por ejemplo. while (respuesta == 1) { C.*.println(”Se han calculado ” + (contador ú 1) + Triangulosá). C. int Y = c.Java: del Grano a su Mesa (Versio n 1. Se recomienda que utilices un ciclo for para resolver este problema import java. while (a >= 0) { C.3) Capi tulo VII: Ciclos de Programa Java: del Grano a su Mesa (Versio n 1. ya que ambos hacen exactamente lo mismo. a--.readInt(). // Se piden los valores de los operandos c. Es la condición que debe ser TRUE para que el for no termine. C. Es una instrucción que se ejecuta cada vez que el ciclo es realizado (en cada iteración). en donde: <inicio> <condición de salida> <incremento> Es una instrucción que se ejecuta solo al comenzar el for.pow(a. 45 46 . int X = c. a>0. public class Triangulos { public static void main (String[] args) { Console C = new Console(). contador++.println(”Calculo de la Hipotenusa de un Trianguloá).awt. Observa la equivalencia directa entre el for y el while de ejemplo. C.pow(b.println(”Se repite este texto en pantallaá).*. c.print(”b?á). int a = 10. C.println(”Hipotenusa = ” + Math. respuesta = C.readDouble(). } public class Producto { public static void main (String[] args) { // Se crea la consola Console c = new Console().3) Capi tulo VII: Ciclos de Programa Conceptos Ciclo Un Ciclo es un trozo de programa que se repite según una Condición que evaluada puede entregar verdadera o falsa. } C.sqrt(Math. y se llama While. Solución import java.print(”Desea continuar (1=Si/2=No)?á). C. a--) { C. } } en donde: <condición> Valor de verdad que debe ser verdadero para que se ejecute el trozo de código escrito dentro del while. En Java existe una instrucción para realizar este tipo de código. double b = C.print(”Ingrese el operando X?á).readDouble(). el siguiente código se repite por (for) 10 veces: Console C = new Console(). el siguiente código se repite mientras (while) a sea mayor o igual a 0: Console C = new Console(). } Otra forma de representar un ciclo es con un for (por o para) que es más completo que el anterior: for (<inicio>.println(”Gracias por usar el programaá).awt.print(”Ingrese el operando Y?á). int respuesta = 1. 2) + Math.println(”Triangulo ” + contador). Nota: Recuerda que X por Y es lo mismo que sumar Y veces el valor de X. // esto es lo mismo que escribir a=a-1. < incremento>) { <trozo de codigo que se repite> } Problemas (a) Escribir un programa que pida al usuario 2 número enteros y que luego los multiplique utilizando SOLO sumas. double a = C. Por ejemplo.readInt(). 2)) ).readInt(). for (int a=10.print(”a?á). C.

frases u oraciones (gramaticales) con y sin sentido. int X = c. for (int i=1. c. i++) { potencia = productoXY(X. i<=Y. X). Por ejemplo: c. } // Se despliega el resultado c.readInt(). i<=Y. Existen 2 tipos de Strings. 47 48 . int Y) { int producto = 0.print(”Este es un LITERALó). • “23499 ldslñññsdfñ” también es una Cadena de Texto. c. Haz lo mismo que en el problema anterior (X por Y) pero ahora considerando las potencias (Xy) y utilizando solo PRODUCTOS.3) Capi tulo VIII: Cadenas de Texto y Literales Capítulo VIII: Cadenas de Texto y Literales Motivación Hasta ahora conocemos los números y todo. ¿Puedes hacer lo mismo a b pero solo con sumas? Trata de hacerlo con tus palabras.println(”X por Y = ” + producto). y luego compáralo con la siguiente solución: import java. (c) Desafío.awt. int Y) { int potencia = 0.*. y que representan fielmente su contenido. i++) { producto = producto + X. } } Java: del Grano a su Mesa (Versio n 1. los Literales y los tipos de dato String. Literales: Son aquellos Strings.print(”Ingrese la base X?á). i++) { producto = producto + X. • “Yo soy genial” es una Cadena de Texto. } public static void main (String[] args) { Console c = new Console(). int Y = c. String: Es un tipo de dato especial que permite almacenar literales en variables. c. Por ejemplo: String a = ”Esta es una variable STRINGá. public class Potencias { public static int productoXY (int X. Claramente el parámetro del método print es un literal. representados por cadenas dentro de comillas dobles (“ “). Y)). } return potencia.print(a).println(”X elevado a Y = ” + potenciaXY(X.3) Capi tulo VII: Ciclos de Programa // Se calcula el producto entre X e Y como sumas int producto = 0. Según esta definición: • “Ana” es una Cadena de Texto.Java: del Grano a su Mesa (Versio n 1. ¿cómo utilizar las cadenas de caracteres? Queremos realizar el juego del “repondón” simulando el siguiente diálogo: Hazme preguntas y YO respondo. Recuerda que esta operación es lo mismo que multiplicar Y veces el valor de X. } } Concepto Cadena de Texto Las Cadenas de Texto son un grupo de caracteres uno tras otro y que representan palabras.readInt(). i<=Y. for (int i=1. c. las cadenas de texto tiene un nombre especial y se llaman String. Pero. } return producto. Sintaxis En Java. for (int i=1. } public static int potenciaXY (int X. P? Esto es un entero R: NO P? Eres un computador R: SI P? Yo soy un usuario R: NO P? Sabes computacion R: SI (b) Propuesto.print(”Ingrese el exponente Y?á).

Java: del Grano a su Mesa (Versio n 1. Para buscar una ocurrencia de un texto a partir de una posición específica. ¿Qué está mal? No hay nada malo.readLine(). esta sería alfabeto. Pero si contamos el número desde 1. 49 50 . se utiliza: <variable String>. debemos saber como leer un String desde la entrada de datos.indexOf(”esá. Ooooops. Concatenación de Strings Para concatenar o juntar dos o más Strings se utiliza el operador aritmético de adición (+). es el 19avo carácter. Su forma general queda como: <variable String>. Este ejemplo guardaría lo ingresado por el usuario en la variable a. c.charAt(3)). llamado length: String a = ”Hola mundoá. Su forma general que busca la primera ocurrencia de un texto. Para ello utilizaremos el método de la CONSOLA llamado readLine(): String a. Lo que pasa es que las posiciones comienzan desde 0. Esto se realizar con el método de la clase String charAt(i) en donde i es el i-ésimo menos 1 carácter de la cadena.indexOf(”esá). Algunas funcionalidades útiles de los Strings son: Obtención de un Carácter Al igual que para el largo. Por ejemplo: String s = ”esta es una casaá.println(”La letra 3 es ” + alfabeto. Es decir: <variable String>. c. la posición retornada es –1.length(). existe la forma de sacar 1 sola letra del String. este ejemplo muestra en la consola la frase: “La letra 3 es d”. <posición a buscar>). Por ejemplo: String alfabeto = ”abcdefghijklmnopqrstuvwxyzá. pero si buscamos desde otra posición int n = s. readLine() no posee parámetros y su forma general sería la siguiente: <variable String> = c. es necesario hacerlo con un LITERAL.readLine().charAt(5) como sería lo común. Al igual que los readInt() y readDouble().length() + ” caracteresá). Esto retorna la posición 0. Como podemos ver. Mucha atención. length se utiliza con la variable punto el método length (sin parámetros). Este ejemplo retorna “En 18 hay un punto y coma”.indexOf(”esá. c. Esto concatenaría al final en a la frase: “primero segundo otro primero segundo otro”. es decir. Por ejemplo: String s = ”Texto contiene un . Por ejemplo: String a = ”á.indexOf(”.3) Capi tulo VIII: Cadenas de Texto y Literales Java: del Grano a su Mesa (Versio n 1.println(”En ” + s. 0) Largo de un String Es muy util conocer cuántos caracteres posee un String (variable o literal). Lectura de un String desde el Teclado Para comenzar. Este ejemplo mostraría en la consola “Hola mundo posee 10 caracteres” Como podemos ver en el ejemplo.3) Capi tulo VIII: Cadenas de Texto y Literales Al igual que en el anterior ejemplo.indexOf(<texto buscado>.ó) + ” hay un punto y comaá).print (a + ” posee ” + a. Existen algunas variantes de esté método. Para ello existen un método dentro de la clase String que se utiliza. dentro del cuerpoá. print recibe en este caso una variable String en vez de un literal. Nota: Si el String buscado no está dentro del String s. Con esto entonces podemos buscar desde una posición específica. // es lo mismo decir: s. si quiero la 5 letra. // VACIO a = a + ” primeroá a = a + ” segundoá a = a + ” otroá + a + ”otroá. es: <variable String>.indexOf(<texto buscado>). que al inicializar una variable String. a = c. Búsqueda de un Carácter o Texto Para buscar un trozo de texto o carácter dentro de otro se utiliza el método indexOf(“texto”) el cual retorna la posición i-ésima menos uno (es decir retorna el índice del carácter correcto dentro del String). int n = s.charAt(4) y no alfabeto. 2). sin importar si son número o letras.charAt(<posición i>).

Solución Recordando un poquito tenemos que imitar el diálogo siguiente: Hazme preguntas y YO respondo. 11). Java: del Grano a su Mesa (Versio n 1.print(”P? ”). c.equals(<variable String 2>).substring(<pos inicial>). } A esto se le llama Case Oooops. Entonces. es decir.length()-1))>= 0) c. el caracter del string 1 es mayor según ASCII que el string 2. <pos final>). saca hasta el último caracter antes de <pos final>. métodos de la clase String: Existen 2 métodos que nos ayudan a comparar strings: <variable String 1>. Según la tabla ASCII de valores internacionales. while (true) { c. Si los strings difieren en algo (largo o caracteres) el resultado es FALSE. La otra forma compara los strings según la tabla ASCII: <variable String 1>.3) Capi tulo VIII: Cadenas de Texto y Literales - número > 0 si el string 1 es MAYOR que el string 2 0 si el string 1 es IGUAL que el string 2 número < 0 si el string 1 es MENOR que el string 2 Obtención de Trozos de un String Por último para la clase. es decir: <variable String>.println(”Hazme preguntas y YO respondo:á). Z) se representan por códigos entre el 65 y 90 Las minúsculas (a . 9) se representan por códigos entre el 48 y 57 (respectivamente) Las mayúsculas (A . que representa cada caracter con un número entero entre 0 y 255. es decir. un caracter es mayor que otro cuando su código ASCII es mayor. En cualquier otro caso responde SI. la primer ocurrencia de “es” está en la posición 5.indexOf(pregunta. String pregunta = c.println(”R: SIá). Para ello posee sus propios comparadores.println(a). El siguiente ejemplo sacar lo que va entre sexta y la undécima posición es: String s = ”Este string esta completitoá. porque a partir de la posición 2. nos falta saber como responde el computador: • • Si la pregunta termina con vocal. De esta forma estaríamos pidiendo desde la posición inicial hasta el final del String. “lastIndexOf”.substring(5. Nótese que NO INCLUYE la posición final.. Su forma general queda: <variable String>. Este método retorna TRUE si los strings son EXACTAMENTE iguales (incluyendo mayúsculas y minúsculas10). if (”aeiouó.. z) se representan por código entre el 97 y 122 Todos los demás caracteres poseen distintos códigos Este ejemplo pone en pantalla la palabra string.readLine(). else c.charAt(pregunta. String a = s.3) Capi tulo VIII: Cadenas de Texto y Literales Retornará la posición 5. nos dice que: Los números (0 . veremos como sacamos un trozo de un String. c. si no que la última ocurrencia del texto buscado. Nota: Si anteponemos la palabra “last” a ambas formas del método.Java: del Grano a su Mesa (Versio n 1. es decir. También existe una forma adicional de usarlo y es sin indicar el largo. algo como sacar un pedacito que nos sirva. el computador responde NO. Ahora veamos la solución: Console c = new Console(). P? Esto es un entero R: NO P? Eres un computador R: SI P? Yo soy un usuario R: NO P? Sabes computacion R: SI Comparación de Strings Los strings no pueden ser comparados como los números con operadores lógicos tradicionales.compareTo(<variable String 2>).substring(<pos inicial>.println(”R: NOá). Este método retorna 10 Pero además. ¿Cuándo un string es mayor o menor que otro? Un string es mayor que otro cuando en el primer caracter que difieren. podemos obtener no la primera ocurrencia.. Analicemos lo que vamos haciendo paso a paso y separado por líneas distintas (equivalente al IF de arriba): 51 52 . Creo que es demasiado complicado ver la línea del if por entero.

// Obtenemos el largo del STRING int L = pregunta.equals(letra)) { cont_veces++. i++) { // Ciclo de recorrido texto // Se va guardando al reves. for (int j=0. y cuenta cuántas letras distintas tiene la frase.charAt(L).length()-1. if (cont_veces>0) { c. podemos ir mostrando en pantalla caracter a caracter en vez de utilizar una nueva variable: // Primero.length(). i>=0. // Calculamos el ultimo caracter del string L = L ú 1. } // Se muestra en pantalla c. for (int i=0.print(texto.charAt(i). Nota: Utiliza un string que tenga TODAS las letras del abecedario. caracter a caracter invertido = texto. porque si somos astutos.println("CONTADOR DE LETRAS").charAt(i) + invertido. La firma del método es: 53 54 . pueda simular el siguiente diálogo: Contador de letras en una frase Escriba la frase que desea contar? Esta es la frase a = 3 veces e = 3 veces f = 1 veces l = 1 veces r = 1 veces s = 2 veces t = 1 veces 7 letras usadas Escriba la frase que desea contar? _ Problemas (a) Se desea escribir un programa que solicite una línea de texto al usuario y que simplemente la despliegue en forma inversa. } } // Una vez que cuenta cuantas veces se repite la letra // la mostramos en la Console si es que es != 0. pediremos el texto al usuario c. utilizando e indicando los patrones de programación usados. Escribir un programa que cuente cuántas palabras son verbos (en infinitivo) en un texto ingresado por el usuario. // Ahora tomamos el texto y lo invertimos // guardandolo en una nueva variable String invertido = ”á. pediremos el texto al usuario c. // Ahora lo invertimos for (int i=texto.println(”Escribe un texto para invertir?á).print("Escriba la frase?"). c. int cont_letras = 0. (c) Propuesto. j++) { // Verificamos que sea la letra escogida if (frase. // Trasnformamos toda la frase a minusculas frase = frase.3) Capi tulo VIII: Cadenas de Texto y Literales Java: del Grano a su Mesa (Versio n 1. if (vocal >= 0) // Solo si ultimo es vocal c.readLine().println(”El texto invertido es: ” + invertido). ¿Podría escribir un método que entregue aleatoriamente un String de n caracteres?.charAt(j). // nada que ver con Patrones while (true) { c. i++. (d) Propuesto. la de vuelta. // Primero. } } Es muy importante notar que esta no es la única solución posible.println(”R: NOá). cont_letras++.) { // Sacamos la letra i-esima del abcdario String letra = abcdario.length(). Recuerde que los infinitivos terminan TODOS en una vocal + “r”. else c.charAt(i)). } (b) Propuesto.println(letra + " = " + cont_veces + " veces").toLowerCase(). int cont_veces = 0. es decir.readLine(). // Vemos si es vocal int vocal = ”aeiouá. // Sacamos el ultimo caracter String ultimo = pregunta.length(). String texto = c. String texto = c.println(”R: SIá).println(”Escribe un texto para invertir?á).indexOf(ultimo). j<frase. // Ciclo de programa.3) Capi tulo VIII: Cadenas de Texto y Literales public static String textoAzar (int n).readLine().length().Java: del Grano a su Mesa (Versio n 1. i<texto. Note que lo que hace el programa es contar cuántas veces se repite una letra del abecedario en la frase que ingresa el usuario. i--) { c. Escribe un programa que. Console c = new Console(). // PATRON DE LECTURA DE DATOS String frase = c. i<abcdario. // Se inicia vacıo for (int i=0.

.. while (<condicion>) { .Java: del Grano a su Mesa (Versio n 1.println(”Valoresá). A ellos se les llama Patrones de Programación. double nota = c. <variable> = <variable> <operador> <expresion>. int cont = 0. Existen “elementos” que permiten traducir los algoritmos mentales en códigos de programación y que son comunes entre una solución y otra.0 Contador = 3 La solución del programa anterior. serían elementos que se repiten en distintas soluciones.. + valn producto = fac1 * fac2 * fac3 * ...0 ? 6. Patrón de Acumulación Se utiliza para realizar cálculos como la suma de varios valores acumulados en distintas iteraciones de un ciclo: suma = val1 + val2 + val3 + ..0 ? 5.. Concepto Un Patrón de Programación es un elemento de programa ya conocido que se puede utilizar como parte de la solución de muchos problemas. } Capítulo IX: Patrones de Programación Motivación Los programas no se parten a desarrollar desde cero.. } Un ejemplo concreto sería realizar el siguiente diálogo: Valores ? 4. while (nota != 0. * facm La forma general de este patrón es: <tipo> <variable> = <valorinicial>.readDouble().println("Hay " + cont_letras + " letras en la frase").3) Capi tulo IX: Patrones de Programacio n // Ahora decimos cuantas letras encontramos en la frase c. c...0) { 55 56 . marcando en negritas aquellas que corresponden al patrón de acumulación.3) Capi tulo VIII: Cadenas de Texto y Literales Java: del Grano a su Mesa (Versio n 1. sería: c.. A continuación veremos algunos patrones básicos más utilizados. Como es normal en lo que son los patrones.0 ? 0. .print(”? ”).

<variable> = c. a través del curso encuentres otros patrones de programación. Probablemente.. . for (int i = 0. Java: del Grano a su Mesa (Versio n 1.readDouble().. .println(”Ingrese las notas de los 100 alumnos.3) Capi tulo IX: Patrones de Programacio n Problema (a) En el siguiente problema asocie con números las líneas de código que pertenecen a un patrón de programación. Patrón de Recorrido de Intervalo El patrón de recorrido de intervalo es aquél que permite realizar un ciclo de repetición entre un intervalo de valores enteros.Java: del Grano a su Mesa (Versio n 1. c.print(”Ingrese su nombre? ”). Por ello.readString().á). suma += nota. double suma = 0.readTipo(). Es bastante sencillo y su forma general es: <tipo> <variable>. pues te servirán para todos tus programas (incluso las tareas). } Complemento a la Clase Es muy importante recalcar que estos patrones son los básicos que existen.print(”Alumno ” + i + á?á). Su forma general es: int i = <valor inicial>. } c. } c. } y en forma de for sería: for (int i = <valor inicial>. búscalos y encuéntralos. También los hay en muchas ocasiones y tipos distintos dependiendo d e la solución.. . Solución Console c = new Console(). . i++. while (i <= <valor final>) { . } i La solución a este problema es bastante sencilla con la forma for: 57 58 . c.print(”? á). Patrón de Acumulación 2. Patrón de Lectura de Datos 3. i++) { c.3) Capi tulo IX: Patrones de Programacio n cont = cont + 1. Patrón de Recorrido de Intervalo Console c = new Console(). i < 100. Use la siguiente simbología: 1.á). .readDouble(). nota = c. } c.println(”El promedio del curso es: ” + suma/100). Es muy útil porque es necesario para la interacción con el usuario. Patrón de Lectura de Datos Este patrón involucra las acciones de lectura de valores o datos. i <= <valor final>.println(”Ingrese las notas de los 100 alumnos. i < 100.println(”Hola ” + nombre).println (”Contador = ” + cont). for (int i = 0. i <= n. (2) (1) double nota = c. double nota = c.print(”Alumno ” + i + á?á).println(”El promedio del curso es: ” + suma/100). i++) { suma += i. . i++) { . Un ejemplo sencillo es la resolución de una sumatoria de la forma: Σ n i=0 int suma = 0. c. Ejemplo: c. (1) (3) double suma = 0..readDouble(). i++) { c. suma += nota. c. for (int i = 0. String nombre = c.

0 59 60 . Capítulo X: Arreglos y Matrices Motivación Hasta ahora hemos hecho programas que pueden funcionar hasta con 3 valores distintos. s = new String[23][50]. // Arreglo de 100 enteros double[] b. 4. <var> = new <tipo>[<filas>][<cols>]. n elementos . <var> = new <tipo>[<filas>][<cols>]. Como podemos ver hay formas distintas (pero equivalentes) para crear arreglos. Cualquiera de las dos formas es correcta y hacen exactamente lo mismo. <var> = new <tipo>[<largo>]. un arreglo de largo 10 posee las “casillas” 0. Un Arreglo puede ser muy útil cuando se utilizan este tipo de problemas ya que permiten un trabajo mucho más dinámico que utilizando variables estáticas. . a = new int[100]. 8 y 9. Sintaxis Los arreglos no poseen un tipo especial para ser declarados. o <tipo>[][] <var>. o <tipo> <var>[]. En efecto. Por ejemplo: n-1 int[] a. . y no hemos podido guardar más información. c = new MiTipo[3].3) Capi tulo X: Arreglos y Matrices Es muy importante ver que los arreglos parten desde 0 y terminan en n-1 (si el largo es de n por supuesto). (El dialogo continua mientras no se ponga 0) Voto? 0 Resultados de Candidato 7 = Candidato 3 = Candidato 1 = las elecciones: 58 votos 55 votos 33 votos Dimensiones de los Arreglos Los arreglos pueden ser uni-dimensionales o multi-dimensionales. 1. MiTipo[] c. La diferencia está en las combinaciones que se pueden realizar cuando se programa. <var> = new <tipo>[<largo>]. a veces variables. Por ejemplo: int a[]. Una forma sencilla sería declarar 10 variables que guarden los votos de cada candidato pero ¿qué sentido tiene cuando el número de candidatos es 100 o 1. .3) Capi tulo X: Arreglos y Matrices Java: del Grano a su Mesa (Versio n 1. . Imaginemos el siguiente diálogo: Votaciones Mundiales por la Paz Candidatos = 10 Emision de votos: Voto? 1 Voto? 3 . o Conceptos Arreglos: Lista de elementos (espacios en memoria) de un mismo tipo que son referenciados por una misma variable subindicada a partir de 0 (primera posición) hasta el número de elementos menos 1 (n-1 es la última posición). 7. b = new double[10]. encontraremos otra solución. <tipo> <var>[]. es un ahorro de espacios de memoria cuando se almacenan. . Lo único que hay que hacer es agregar un modificador especial a cada uno de los tipos ya definidos. Hoy.000?. Por ejemplo.. 3. // Matriz de 23 filas x 50 columnas Strings. b. ni nada.Java: del Grano a su Mesa (Versio n 1. La forma (o formas) general es: <tipo>[] <var>. Para nosotros solo nos serán aplicables los arreglos uni-dimensionales (a los que llamaremos solo arreglos) y bi-dimensionales (a las que llamaremos matrices). . // Arreglo de 10 reales String s[][].. // Arreglo de 3 objetos de MiTipo Fin del programa. 5. También. 2. . 6.

¿Qué pasa si necesito un arreglo en un método? Bueno este problema es bastante sencillo. pero si lo hiciéramos con arreglos solo abriríamos el archivo al final: Console c = new Console(). ya que el “tipo del arreglo” está definido tanto por el tipo de dato que almacena + los corchetes que indican que es un arreglo. i++) { c. Fue guardado en archivo.println(”Listo.println(”Se imprime la 15ava posicion del String: ” + s[14]). Como podemos ver. i++) { pw. } // Ahora se graba en el archivo PrintWriter pw = new PrintWriter(new FileWriter(”archivo.println(”El mejor promedio fue el alumno ” + mejorAlumno + á con un promedio de control á + maxProm).ó)) break.Java: del Grano a su Mesa (Versio n 1. } } c. String texto[] = new String[100]. } pw. i++) { c. i++. se utilizan subíndices enteros para indicar que queremos sacar: String s[] = new String[50] .. Para finalizar ponga un punto aislado(.txtá). c. s[3] = ”Esta es la posicion 4á.. mejorAlumno = i.3) Capi tulo X: Arreglos y Matrices Alumno 1: P1? _ P2? _ P3? _ .println(”Ingrese las notas de los 110 alumnos del curso:á).txtá)). c. j < i. i < 3. notas[i][j] = c. c. Alumno 131: P1? _ P2? _ P3? _ El mejor promedio fue el alumno 57 con un promedio de control X. s[10] = ”Esta es la posicion 11á. aquí se realiza una búsqueda después de ingresado los datos a la matriz. i < 110. for(int j = 0. > . o almacenar algo en una posición del arreglo. Pero cuando queremos leer un elemento. Fue guardado en archivo.. Para pasar por parámetro un arreglo o matriz: public void producto (double[] arreglo.readLine(). if (texto[i]..println(”Alumno ”+ i). i<110..println(”Escriba el texto de maximo 100 lıneas que desea almacenar en el archivo. // Nadie tiene peor promedio double mejorAlumno = -1. double[][] matriz) Otro ejemplo. int a[].3) Capi tulo X: Arreglos y Matrices En este caso se declaran 2 arreglos de enteros.X.close().equals(”. i++) { double promedio = (notas[i][0] + notas[i][1] + notas[i][2])/3. Siguiendo con esta regla: 1. El código sería: Console c = new Console(). (Llegar a 100) > ultima lınea. double notas[][] = new double[110][3]. c. la utilización es completamente similar en ambos casos.println() = texto[j]. // Nadie for (int i=0. Listo.txt A diferencia del problema anterior.) á). En este otro caso se declara 1 arreglo de enteros (a) y un entero (b)..readDouble(). for(int i = 0. Para finalizar ponga un punto aislado (. pero ahora con matrices: Ingrese las notas de los 130 alumnos del curso: 2. Ok. Una forma sencilla sería hacerlo que cada vez que escribiera una línea la enviáramos al archivo. Para retornar un arreglo o matriz: public double[] sumaArreglo (. if (maxProm < promedio) { maxProm = promedio.) 61 62 . texto[i] = c. Un ejemplo de utilización de arreglos puede ser realizar una lectura de texto por líneas. b. es decir: Escriba el texto de maximo 100 lıneas que desea almacenar en el archivo. for(int j = 0. } } // Ahora se busca el mejor promedio double maxProm = 0.) > Este es un texto > que es ingresado por el usuario > a traves del teclado.print(”P” + j + ”? á). while(i < 100) { c.print(”> ”). int i = 0. Java: del Grano a su Mesa (Versio n 1.

No hay mucha diferencia.println(”Votaciones Mundiales por la Pazá). c. int filas.. i++) { Buscamos si es mayor que el primer lugar (votos[i] >= votos[maximas[0]]) { maximas[2] = maximas[1]. int cols) { double valTemp = 0.3) Capi tulo X: Arreglos y Matrices Fin del programa.print(”Voto?á). return (suma / notas. el tercero >= votos[maximas[2]]) { = i. } } return M. entregándole por parámetro la matriz original y las dimensiones de ella: public double[][] trasponer (double[][] M. // Ahora for (int // if se buscan los mejores candidatos i=0. modificando solo el trozo de código por el siguiente: . for (int i = 0. c. pero no sabemos cuánto.Java: del Grano a su Mesa (Versio n 1. i++) maximas[i] = 0.println(”Candidatos = 10á). while (true) { c.. i<maximas. Otra opción hubiese sido haber declarado 3 variables para las máximas votaciones.. i < notas. i++) suma += notas[i]. int votos[] = new int[10].readInt(). c.length. j++) { // Es optimo valTemp = M[i][j]. // Se inicializan los votos en 0 for (int i=0.println(”Resultados de las elecciones:á). Por ejemplo: public double promedioNotas (double[] notas) { double suma = 0. j < i.length). c.length.println(”Candidato ”+maxima[1]+”=”+votos[maxima[1]]+” votosá). int candidato = c. maximas[1] = maximas[0]. for (int i=0. M[i][j] = M[j][i]. i++) votos[i] = 0. Solución al Problema Recordemos el diálogo del problema: Votaciones Mundiales por la Paz Candidatos = 10 Emision de votos: Voto? 1 Voto? 3 . 63 64 . el segundo >= votos[maximas[1]]) { = maximas[1]. } La solución a este problema es muy similar al problema de las notas: Console c = new Console(). podemos tratar de hacer un método que permita trasponer una matriz.length sin paréntesis (a diferencia de length() de String obviamente).. if (candidato = 0) break. } // Se inicializan al mayor como el primero int[] maximas = new int[3]. maximas[0] = i. } En este caso notas trae una lista con valores numéricos. c.println(”Fin del programaá). J Otra nota interesante es saber el largo de un arreglo sin tener la necesidad de conocerlo previamente. for (int i = 0. M[j][i] = valTemp. Para ello utilizamos .length. i<votos. i++) { for (int j = 0.println(”Emision de Votos:á).println(”Candidato ”+maxima[2]+”=”+votos[maxima[2]]+” votosá). Para aclarar más los conceptos hasta aquí vistos.println(”Candidato ”+maxima[0]+”=”+votos[maxima[0]]+” votosá).length.3) Capi tulo X: Arreglos y Matrices public double[][] sumaMatriz (. = i. i<votos.) Java: del Grano a su Mesa (Versio n 1. (El dialogo continua mientras no se ponga 0) Voto? 0 Resultados de Candidato 7 = Candidato 3 = Candidato 1 = las elecciones: 58 votos 55 votos 33 votos } } // Buscamos si es else if (votos[i] maximas[2] maximas[1] } // Buscamos si es else if (votos[i] maximas[2] } // Se imprimen los lugares c.. c. votos[candidato]++. Hecho. // Se ejecuta la votacion c.. i < filas.

for (int i=0. que el usuario ingrese el número de vendedores..readDouble(). ya que a través del tiempo no es se guro que siempre tengan 25 vendedores. c. lugar1 = i. J Problemas Una multitienda de Burundí.. double comision = c. se ha dado cuenta de que las utilida des que recibe mensualmente no son tan buenas como lo eran antes.println(”Candidato ”+lugar1+”=”+votos[lugar1]+” votosá).print(”Vendedor?á).Java: del Grano a su Mesa (Versio n 1.. Vendedor 25 = $ XXXXX Solución Console c = new Console(). c. } c. int v = c. es decir.1] += c.println(”Candidato ”+lugar3+”=”+votos[lugar3]+” votosá). i<ventas. lugar2 = i.3) Capi tulo X: Arreglos y Matrices // Se inicializan al mayor como el primero int lugar1 = 0. while (true) { c. Para ello le piden a usted algunos favorcitos: (a) Desarrolle un programa que simule el siguiente diálogo: Tienda de 25 vendedores Porcentaje de comision? _ Inicio de Ventas: Vendedor? _ Monto vendido? _ .3) Capi tulo X: Arreglos y Matrices Vendedor? 0 Fin de Ventas Resumen de comisiones Vendedor 1 = $ XXXXX .readInt(). int lugar2 = 0. al genial Yoghu-Rtuh Mghe. int nVendedores = 25. // Se pide el % de comision c.length. c.readInt().println(”Tienda de 25 vendedoresá). // Calculo de comisiones por vendedor c.readInt(). Un estudio con los especialistas económicos de la tribu ha arrojado que la clave de las utilidades está en la atención que los vendedores daban a los clientes. c. i<votos.. En una encuesta anónima se dieron cuenta de que los 25 vendedores de la tienda no tenían incentivos para atender mejor a los clientes porque poseían un sueldo fijo. (b) Hágalo ahora con un número de vendedores variable. Entonces. } } // Buscamos si es el segundo else if (votos[i] >= votos[lugar2]) { lugar3 = lugar2.print(”Monto vendido?á). // Ahora for (int // if se buscan los mejores candidatos i=0..println(”Resultados de las elecciones:á). de la forma en que se hizo en la parte (a) la solución es bastante sencilla. // Se declara el arreglo con lo vendido por el vendedor (Para todos los vendedores es igual) 65 66 .length. . } } // Se imprimen los lugares c.println(”Candidato ”+lugar2+”=”+votos[lugar2]+” votosá). El Negro Judío. for (int i = 0. lugar2 = lugar1. se le ocurrió dar incentivos dependiendo de lo que venda cada vendedor. // Ciclo de venta de la tienda c. // Se declara el arreglo con lo vendido por el vendedor int[] ventas = new int[nVendedores].println(”Resumen de comisionesá). c.length.print (”Porcentaje de comision? á). int nVendedores = c.println ((ventas[i] * comision / 100)). i++) { Buscamos si es mayor que el primer lugar (votos[i] >= votos[lugar1]]) { lugar3 = lugar2.print (”Vendedor ” + (i + 1) + ” = $ ”). Veremos solo un trozo de lo que necesitamos para ver la diferencia: Console c = new Console().println(”Inicio de Ventas:á). i++) ventas[i] = 0. int lugar3 = 0. Java: del Grano a su Mesa (Versio n 1. i < ventas. Pero la elegancia va por dentro. i++) { c. c. ventas[v .print(”Numero de Vendedores?ó). Solución Bueno.println(”Fin de Ventasá).. } // Buscamos si es el tercero else if (votos[i] >= votos[lugar3]) { lugar3 = i. if (v == 0) break. c.

27 32 40 0 109 Note el espacio que hay entre el 5to carácter y el stock del producto 2.3) Capi tulo X: Arreglos y Matrices } Problemas Propuestos Escriba un problema de control de inventario: 1... El inventario fue guardado en inventario. for (int i = 0. Proceso de la siguiente forma: Control de Inventario Inventario Inicial: Producto XXXX = 5 Producto XXXX = . i<ventas.. 2 = salida.out) con la misma estructura anterior. ß Casillas del Arreglo ß Constructor de la Clase 67 68 . . 3.. Tipo (1 = entrada.. Movimientos: Tipo (1 = entrada. 0 = terminar)? _ Codigo del producto? _ . i++) ventas[i] = 0. no puedes llegar y crear el arreglo sin crear cada uno de los objetos (casillas) del arreglo. Java: del Grano a su Mesa (Versio n 1.. Por ejemplo con la clase Complejo: Complejo[] c = new Complejo [20]. Por ejemplo: 39578 84990 12948 38380 92329 .3) Capi tulo X: Arreglos y Matrices int[] ventas = new int[nVendedores]. 2 = salida.. for (int i=0. i++) { c[i] = new Complejo(). Tiene un archivo de entrada (inventario.length. Inventario Final: Producto XXXX = 5 Producto XXXX = .in) en donde guarda una lista con los códigos de los productos (5 caracteres) y sus stocks iniciales (resto de la línea). .out Importante Cuando tu creas un arreglo con una clase pre-definida.length. 0 = terminar)? 0 Fin del dıa.Java: del Grano a su Mesa (Versio n 1. Al final del procesamiento del programa tiene que guardar los nuevos stocks en un archivo (inventario. i < c. ..

suponemos el paso k-1 cierto. if (n == 1) return ”1á. 2. Solución al Problema Para solucionar el problema. ya que es un patrón bastante abstracto cuando se trata de visualizarlo físicamente. El paso general que se ejecuta procesando y llamando a la siguiente iteración. Esto es muy similar a los ciclos. se debe pensar en el caso inicial. sabemos por hipótesis inductiva que: concatenaRecursivo(n) ⇔ n + concatenaRecursivo(n-1) Esto se ve si hubiésemos usado n en vez de k en la hipótesis. Esto quiere decir que debemos concatenarle k. ¡¡¡Es recursivo!!! Y la llamada sería: String serie = concatenaRecursivo(45). Además. n-2. El encabezado del método quedaría como: static String concatenaRecursivo (int n) { // Recibe como parametro el n del maximo en el conjunto.Java: del Grano a su Mesa (Versio n 1. en una visión general nuestro método quedaría como: // Encabezado del metodo static String concatenaRecursivo (int n) { // Caso base retornamos solo el uno. for (int i = 1. resumiendo lo aprendido. En Java se utiliza la hipótesis para n-1 cierta de la misma forma. entonces. . return resultado. quedando: // Caso general con hipotesis inductiva return n + concatenaRecursivo(n-1). para llegar al resultado final. El concepto de Recursividad es un poco complejo de entender de buenas a primeras. i++) resultado = resultado * i.3) Capi tulo XI: Recursividad Capítulo XI: Recursividad Motivación Sabemos perfectamente calcular el factorial de un número en forma secuencial. para hacer un método recursivo se necesita de 2 pasos muy importantes: 1. es decir que la llamada de concatenaRecursivo(k-1) nos retorna el conjunto de valores entre k-1 y 1 concatenados. if (n == 1) return ”1á. 69 70 . bastaría decomponer la fórmula: Ok… ahora que el caso base está realizado. es decir como { n. definamos el caso base y el caso general.. // Caso general con hipotesis inductiva return n + concatenaRecursivo(n-1).. 3 2 1”) Entonces.3) Capi tulo XI: Recursividad Java: del Grano a su Mesa (Versio n 1. con una condición de salida y variando su parámetro de entrada.. (Guarda en serie el resultado “45 44 43 42 41 40 . i <= n. n-1. podemos verlo en forma de método estático (dentro de la clase principal del programa): static int factorial (int n) { int resultado = 1. Para realizar este problema. es decir cuando n = 1 (menor valor posible para n): // Caso base retornamos solo el uno. es decir. } ¿Se podría solucionar este mismo problema pero sin utilizar un ciclo explícito como for o while? Conceptos Recursividad La Recursividad es un patrón de programación que permite llamar sucesivamente la misma funcionalidad o método. Generar una secuencia (String) de números enteros a partir de 1 y hasta llegar a n (dado por el usuario (como parámetro) en forma recursiva e inversa. la condición de salida de la recursividad. como no podemos sacar un k. 1 }.. Veamos un ejemplo. Caso Base: La condición base para el problema del factorial. 2. Conocer el caso (o casos) base.. } // Fin del metodo y. } Ahora bien.

Un ejemplo mucho más concreto que permite ver la diferencia entre CLASE y OBJETO es el clásico ejemplo de PERSONA. Persona es una clase.3) Capi tulo XI: Recursividad N! = N * (N-1) * (N-2) * . // Caso general return n * factorialRecursivo(n-1).. 71 72 . Problema Propuesto (a) Escriba un método recursivo para resolver la siguiente sumatoria: Σ n i=0 Objeto Se define como Objeto a una referencia específica de un elemento que de cierta clase. } Java: del Grano a su Mesa (Versio n 1. Caso General: Si realizamos una equivalencia matemática de la fórmula obtendremos el caso general: N! = N * (N-1)! Bueno. (1. Características: Poseen una parte real y una parte imaginaria. saludar. se suman. es decir. Realmente es algo interesante modelar como se podrían realizar operaciones con números complejos. esta equivalencia es muy común en soluciones matemáticas de problemas de este tipo.4. Recuerde que la exponencial está en la clase matemática y funciona como Math. Para este problema es necesario primero definir conceptos generales para la utilización de tipos especiales de datos. etc). Como podemos observar. Un concepto muy importante para problemas matemáticos. 3.. etc. pues agrupa a una serie de individuos que cumplen con un conjunto de características comunes (tienen sentidos. si COMPLEJO es una clase.. Funcionalidades: Pueden ser escritos en forma binomial o en forma de vector. Conceptos Clase Se define como Clase a una estructura de programación que permite definir características y funcionalidades especiales a un grupo de objetos que poseen el mismo comportamiento (en la vida real). (b) Escriba el programa que utilice lo anterior y simule el siguiente diálogo: Ingrese el numero de iteraciones para la suma n? 35 La sumatoria vale = . Entonces.Java: del Grano a su Mesa (Versio n 1.exp(i). se multiplican. Es así como 2+i. podemos dar la solución al problema: static int factorialRecursivo (int n) { // Caso base if ( n == 0 ) return 1.3) Capi tulo XII: Clases y Objetos Capítulo XII: Clases y Objetos Motivación En Java solo existen números enteros y reales. ambas partes son números reales. son bípedos.5)i que son notaciones para los números complejos pertenecen a la CLASE COMPLEJO.. hablar. i * ei En donde n es el valor entregado por el usuario (como parámetro).5+9i. de dos sexos. se dividen. es decir. * 1! * 0! Es claro ver que la condición de salida sería 0! = 1 ya que sin esta definición no termina la serie.. es un elemento que cumple con las características de una clase. ya que utilizamos la inducción para suponer que conocemos (N-1)! y solo lo multiplicamos con nuestro factor incógnita N. se restan. cada uno de sus números complejos serían objetos de esa clase. comer. 2+i es un objeto. con estos dos pasos claramente definidos. etc) y pueden realizar una cantidad de acciones (funcionalidades) comunes (caminar.

Enumeremos algunas de las características que hacen a cada individuo distinto de otro: Color de Pelo. se está simulando una conversac ión entre Alberto y María.println(c. CLASE: Persona OBJETO: María Es así como nace un nuevo concepto: OBJETO: Luis En la figura anteriormente desplazada. idioma y nombre. posee color de pelo. se utiliza la sentencia NEW.76 mts. Otro ejemplo de esto se puede ver más claramente con los números complejos: // Declaramos el complejo 3+5i Complejo a = new Complejo(3. Ahora bien. peso. de piel. Alberto Díaz posee las características de cualquier persona. Declaración de una Clase La declaración de una clase no es muy distinta a lo que ya hemos hecho para poder compilar y ejecutar nuestros programas y ejemplos. OBJETO: Alberto En este último ejemplo. entre otras. ¿qué diferencia una persona de otra?. tallas. si existiera que todas las personas pueden caminar (funcionalidad). Idioma. es decir. esto lo representaríamos como: 73 74 . En esta simple línea le indicamos al ordenador que nos cree un Objeto de tipo Persona y le llamaremos (a la variable) alberto. Por ejemplo: String frase = alberto.binomial()). // Declaramos el complejo ú1+9i Complejo b = new Complejo(-1.sumar(b). Idioma: Espanol Nombre: Alberto Dıaz Java: del Grano a su Mesa (Versio n 1. b y c son referencias a objetos de tipo complejo.caminar(). Como podemos ver. pero es un Objeto de la clase Persona porque podemos distinguirlo del grupo de personas. es decir. alberto y maria son los nombres de las variables que son las referencias. Nombre. talla. Persona alberto = new Persona(). La forma general de declaración de una clase es la siguiente: [public] class <nombre de la clase> { // Variables de instancia [declaracion de variables de instancia] // Constructor de la clase public <nombre de la clase> ( [parametros] ) { <instrucciones> } Creación y Referencia de Objetos en Java Para crear un objeto (de tipo Persona para ejemplos). pesos. de ojos.3) Capi tulo XII: Clases y Objetos Ahora bien. Los tres objetos son de tipo persona porque poseen características comunes como ser bípedos y seres humanos (para ser de tipo Persona).” (punto). Talla.escuchar(frase). Es muy importante decir que las funcionalidades de una clase son definidos como métodos. // Imprime en pantalla la forma binomial del complejo c c.Java: del Grano a su Mesa (Versio n 1. pero cada uno se distingue de otro por tener distintos nombres. En el ejemplo de los complejos.3) Capi tulo XII: Clases y Objetos alberto. Color de Ojos. veremos un Objeto de la clase Persona: Color de Pelo: Castano Color de Ojos: Verde Color de Piel: Blanca Talla: 1. Peso: 73 Kgs. En el ejemplo de las personas.hablar(”hola mariaá). Referencia: Una Referencia a un objeto es la variable que indica el objeto deseado. etc. 5). pueden recibir parámetros y pueden retornar valores. Peso. Como podremos ver. podemos observar definidos 2 objetos adicionales al que anteriormente llamamos Alberto: María y Luis. Color de Piel. para llamar una funcionalidad de la clase del tipo de la variable. Con estas definiciones. a. color de piel. 9). // Declaramos el complejo c como la suma de los complejos // a y b Complejo c = a. maria. se utiliza el separador “.

return resultado.suma (b). podremos utilizar el siguiente código para referenciarlo: // Al hacer NEW se llama al constructor de la clase Persona alberto = new Persona (”Alberto Dıazá).3) Capi tulo XII: Clases y Objetos Es importante destacar que la instrucción THIS se utiliza dentro de la declaración de una clase como una referencia por defecto a ella misma.println(”Yo me llamo ” + alberto. public double parteImag. } public Complejo suma (Complejo sumando) { Complejo resultado = new Complejo (this.parteReal.parteReal + ”. -1). Variables de Instancia: Son variables que representan las características que diferencian l os distintos tipos de objetos de la clase.parteReal = real.parteReal + ”+á + this.3) Capi tulo XII: Clases y Objetos // Inicio de las funcionalidades [public] <tipo de dato del retorno> <nombre del metodo> ( [parametros] ) { <instrucciones> } } Java: del Grano a su Mesa (Versio n 1. public class Complejo { // Variables de instancia public double parteReal. -9).formaBinomial() + ” es: ”).parteImag = imaginario.println(c. } // Funcionalidades (algunas) public String formaBinomial () { return this. } public int sumarEnteros (int n1. Complejo b = new Complejo (0. 5). usemos la clase Persona: public class Persona { // Variables de Instancia public String nombre.parteImag). int n2) { return n1 + n2. á + this.formaVectorial()). <. como se utiliza en un programa principal sería algo como lo siguiente: <.. // Le pedimos que nos de su nombre c. } // Funcionalidades public String decirNombre() { return this. También.. c. // Constructor public Complejo (double real.> 75 76 .parteReal + sumando.decirNombre()). Constructor: Son métodos especiales que permiten el “seteo” inicial del objeto.parteImag + ”iá. // Le pedimos que sume dos numeros int suma = alberto.formaBinomial() + ” y ” + b.parteImag + sumando. // Constructor public Persona(String nombre) { this. Persona. Estas acciones pueden o no devolver datos. Por ejemplo. En particular la mayor parte de las veces se utilizan para setear variables de instancia o darle algunos valores iniciales al objeto. y en forma práctica.> Complejo a = new Complejo (2. para llamar a las variables de instancia. double imaginario) { this.. } } y para este ejemplo. Notemos la ausencia del modificador static frente a la definición de los métodos.nombre..println(”La suma de á + a.nombre = nombre. this. this. // suma es 6 Y para mayor claridad. es decir para el ejemplo. Como podemos ver se parece mucho al programa principal.parteImag + ”)iá. La diferencia se encuentra en los modificadores de los métodos que utilizamos. c. la clase declarada se guarda en un archivo con el mismo nombre que el nombre de la clase. Complejo suma = a. } public String formaVectorial () { return ”(” + this.Java: del Grano a su Mesa (Versio n 1. } } Solución al Problema Revisemos la solución del problema planteado a la motivación para mayor claridad a estos conceptos. Funcionalidades (Métodos): Son las acciones que el objeto puede realizar. A veces se utilizan solo para darle valores a variables de instancia o simplemente para imprimir en pantalla (pasándole como parámetro la consola).java (ojo con la mayúscula del principio que es igualita a la del nombre de la clase).sumaEnteros(1.

Java: del Grano a su Mesa (Versio n 1.print(”b?á). double a = c. 77 78 . 2)).> // Pedimos los datos Console c = new Console(). 2) + Math. this. ÍComo te llamas? ALBERTO Hola ALBERTO mucho gusto en conocerte..b.> (c) (Propuesto) Definir una clase llamada Pantalla que permita almacenar una Console (consola) y que esconda a la consola que hemos utilizado hasta ahora. <.sqrt(Math. Constructor que permite crear un dado con n caras. c.. Simula que se tira veces veces el dado de nCaras caras y suma los resultados. } // Calculo del area public double area() { // Retornamos el area return (this.readDouble(). public String leeString() que permite leer desde el teclado un String cualquiera. } // Calculo del perımetro public double perimetro() { // Calculamos primero la hipotenusa double c = Math..pow(this.perimetro()).area()). (b) Escribir el programa principal que use lo anterior y que simule el siguiente diálogo: Ingrese un Triangulo: a? _ b? _ El perımetro es = [] El area es = [] (me parece conocido de unas clases atrás) <.b + c. // Constructor que recibe los catetos de un triangulo public Triangulo(double a. double b) { this. public double b. Yo soy el computador.readDouble().b = b.b) / 2.3) Capi tulo XII: Clases y Objetos Problemas (a) Definir la clase Triángulo que guarde los valores de los catetos a y b (variables de instancia) y que permita realizar las siguientes operaciones sobre un triángulo rectángulo: • • Calcular el perímetro del triángulo Calcular el área del triángulo public class Triangulo { // Variables de instancia que almacenan los catetos public double a.println(”Ingrese un Triangulo:á). Herencia Existe la clase Dado ya definida como: int nCaras. // Creamos el triangulo con estos catetos Triangulo tr = new Triangulo(a.a * this. Llama a tirarDado(1). // Retornamos el perımetro return this. c. public void escribir(String s) que permite escribir en la consola (de instancia) el string s con un retorno de línea al final (println).. double b = c.println(”El area del triangulo es = ” + tr. Para ello defina los métodos: public Pantalla(Console c) que es el constructor de la pantalla y que permite referenciar la consola externa. (d) (Propuesto) Use la clase Pantalla para escribir el siguiente programa: Hola. } } // Retornamos los valores pedidos c. c.println(”El perımetro del triangulo es = ” + tr.a = a.a + this.3) Capi tulo XII: Clases y Objetos Java: del Grano a su Mesa (Versio n 1. Conceptos Herencia Una clase Hereda de otra cuando posee las mismas características y funcionalidades que su padre. Se pide realizar una clase Dado6 que simule un dado de 6 caras a partir de la clase Dado.pow(this. Dado(int n) int tirarDado(int veces) int tirarDado() Variable de instancias que posee el número de caras del dado. y que se le pueden agregar otras características y funcionalidades particulares para ella. c.print(”a?á). b).a.

} public double dividir(double a.-. c. -. } public double restar(double a.print(”a?á).print(”+.*. double a = c. double b) { return (a * b). b).println(a + ” ” + op + ” ” + b + ” = ” + resultado). /? * b? ᑺ3 5 * -3 = -15 Ahora bien. por el contrario. Definamos la clase Calculadora que permite realizar las operaciones matemáticas básicas (suma. OBJETO Luis En el diagrama (un poco modificado del original visto 2 clases atrás) podemos ver que tenemos los mismos objetos: María. Por ejemplo. double b = c. pero hemos insertado un elemento adicional que es la clase Alumno: ¿Cuál es la idea de esta clase? Alumno es una especialización de Persona porque “todos los alumnos deben ser personas”. b). case ”/á: resultado = cal.readDouble(). Esto quiere decir que un Animal no puede ser un alumno (se parece a la vida real). Y si mostramos la pantalla. } public double multiplicar(double a. String op = c. Necesitamos una clase CalculadoraCientifica que calcule además el SEN y COS.sumar(a. multiplicar y dividir de nuevo.dividir(a. multiplicación y división): public class Calculadora { // Esta clase no tiene variables de instancia // Constructor vacıo y no hace nada public Calculadora() { } // Metodos que permiten operar numeros reales // Pedimos datos c.3) Capi tulo XII: Clases y Objetos El concepto de herencia es otro paradigma de la programación orientada al objeto que la hacen una herramienta poderosa para el desarrollo. Alberto y Luis. double b) { return (a . Console c = new Console(). } } Este ejemplo (y a modo de repaso) se utilizaría de la siguiente forma: //./?á). Veamos un ejemplo concreto. Calculadora cal = new Calculadora(). saldría algo como: a? 5 +. c. es reutilizar lo que se va escribiendo para poder realizar mejores y más estructurados programas.. resta. volviendo al ejemplo de Persona.3) Capi tulo XII: Clases y Objetos public double sumar(double a.readLine(). Para ello no tenemos que programar sumar. b). La idea es no re-construir características ni funcionalidades comunes para muchas clases de objetos.. case ”-á: resultado = cal. b).restar(a. case ”*á: resultado = cal. Estos 3 objetos son Personas porque pertenecen a esa clase.b). OBJETO Alberto SUBCLASE Alumno CLASE Persona OBJETO María Java: del Grano a su Mesa (Versio n 1. // Hagamos un IF multiple de otra forma double resultado = 0. double b) { return (a + b). solo d ebemos heredarlos de calculadora: 79 80 .multiplicar(a. Restar.print(”b?á). *. Entonces.Java: del Grano a su Mesa (Versio n 1. double b) { if (b == 0) return 0. podemos decir que Maria y Alberto son Personas y Alumnos porque todas las funcionalidades y características de Persona son heredadas por la clase Alumno. return (a / b). switch op { case ”+á: resultado = cal.readDouble(). } // Mostramos el resultado c.

double b = c. } public double coseno(double x) { return Math. Problemas (a) Propuesto. } // Los metodos se mantienen por lo que no es necesario // declarar ninguno de los de la clase Dado } y si pensamos como funcionaría esto. = cal. = cal..seno(a). // Tiramos 3 veces el dado c. // Tiramos 1 vez el dado c. } } Java: del Grano a su Mesa (Versio n 1.restar(a. public class Dado6 extends Dado { // Hereda las variables de instancia de Dado // Constructor que no necesita parametros public Dado6() { // Lo creamos con un dado de 6 caras super(6).coseno(a). quedaría un programa como este: // .print(”b?á). // Creamos un dado de 6 caras Dado6 d = new Dado6(). = cal.println(a + ” ” + op + ” ” + b + ” = ” + resultado).. // Tiramos 10 veces el dado c. Dibuja la figura en la consola c. double a = c.Java: del Grano a su Mesa (Versio n 1. Console c = new Console()..readLine().println(op + ”(” + a + ”) = ” + resultado). // Mostramos el resultado if (op != ”senoá && op != ”cosenoá) c.multiplicar(a. if (op != ”senoá && op != ”cosenoá) { c. Crea una figura sin puntos. c. b)..3) Capi tulo XII: Clases y Objetos Solución al Problema Veremos que la solución es mucho más corta de lo que pensamos. /. = cal. double y) void dibuja (Console c) Figura copia () boolean compara (Figura fig) Descripción Constructor vacío.sin(x).print(”a?á). b).dividir(a. y) a la figura.sumar(a.cos(x). = cal. CalculadoraCientifica cal = new CalculadoraCientifica(). // Constructor de CalculadoraCientifica public CalculadoraCientifica() { // Invoca el constructor de Calculadora super().println(d. } // Solo los metodos que nos faltaban public double seno(double x) { return Math. Agrega un punto (x. String op = c. ¡Esto funciona! 81 82 .println(d.tirar()). Console c = new Console(). coseno?á). -. seno. Y el mismo programa anterior podemos cambiar y agregar a CalculadoraCientifica: //.readDouble(). b).3) Capi tulo XII: Clases y Objetos public class CalculadoraCientifica extends Calculadora { // Se heredan los metodos de Calculadora y las variables // de instancia. // Pedimos datos c. Existe una clase Figura definida de la siguiente forma: Método Figura () void agregaPunto (double x. b). Escribir la clase Dado descrita en la motivación.tirar(3)). else c.print(”+. = cal.readDouble().tirar(10)). } // Todos los casos double resultado = 0. Retorna una copia de la misma figura Retorna TRUE si la figura fig es igual a la figura (this) y FALSE si no.println(d. *. switch op { case ”+á: resultado case ”-á: resultado case ”*á: resultado case ”/á: resultado case ”senoá: resultado case ”cosenoá: resultado } Es muy importante destacar que se están utilizando los métodos declarados en Dado y no cualquier otro método.

el tipo con el cual se declara .txtá). Pero el tema no llega hasta ahí. Como podemos ver.. Java: del Grano a su Mesa (Versio n 1. pues por ejemplo no se puede implementar una clase que no tenga superclase. double y. Para esto se tiene la clase Archivo que es capaz de representar un archivo cualesquiera con las siguientes funcionalidades: • • • Archivo(): Constructor de la clase que no hace nada. Esta forma compleja de ver la declaración de una variable se resume solo en la primera oración. al. el modelo jerárquico de clase prediseñadas nace a partir de Object (del paquete java. void serNombre(): Le asigna un nombre al archivo. porque TODAS las clases son subclases de una mayor: Object. y) indica el centro del cuadrado y (lado) es el largo de cada lado.3) Capi tulo XII: Clases y Objetos Y como sabemos. podemos crear objetos del tipo de la subclase y utilizar métodos de la subclase como de la superclase: ArchivoLectura al = new ArchivoLectura().setNombre(”misdatos. Gráficamente esto se vería como: CLASE Archivo SUBCLASE ArchivoLectura SUBCLASE ArchivoEscritura 83 84 . es decir.lang) la cual posee algunas funcionalidades básicas y un constructor genérico. pero ambas deben heredar las características y funcionalidades definidas para Archivo. sin embargo no se sabe si es de Lectura o Escritura. Solo debe implementar el constructor Cuadrado (double x. con los métodos respectivos: ArchivoLectura ArchivoLectura() String leeLinea() boolean esEOF() void abrir() void cerrar() más llamadas ArchivoLectura y ArchivoLectura ArchivoEscritura Constructor Para Leer Datos Para Escribir Datos Identifica el Fin de Archivo Para Abrir el Archivo Para Cerrar el Archivo ArchivoEscritura ArchivoEscritura() void escribeLinea(String s) void abrir() void cerrar() En Java..docá). // Metodo de la Subclase Enlace Dinámico Recordando conceptos pasados.Java: del Grano a su Mesa (Versio n 1. se desea organizar archivos a través de clases. Por ejemplo: String s... es decir: . arch.abrir(). Nótese que debe dibujar punto a punto el círculo. trata de implementar estas 3 clases. que recibe en su constructor el centro (x. Es por eso que una clase que implementemos nosotros con nuestras propias manos no requiere un constructor por obligación. Pero veamos los conceptos básicos para el modelo jerárquico de clases que posee Java: Tipo Estático El Tipo Estático de una variable es el tipo con el cual es declarada dicha variable. ArchivoLectura fd.3) Capi tulo XII: Clases y Objetos (b) Escriba la clase Cuadrado que herede de Figura y que represente un cuadrado. es la clase o tipo primitivo que es usado para indicar a la computadora cuánta memoria reservar.setNombre(”Curriculum. Archivo La clase Archivo está representando cualquier tipo de archivo y posee las operaciones genéricas de ellos. Para aliviar esto. Archivo arch. String getNombre(): Obtiene el nombre del archivo. ambas clases se diferencian por lo métodos. y) y el radio del círculo. podemos definir 2 subclases ArchivoEscritura. Para que practiques. (c) Haga lo mismo que en b pero para la clase Círculo. // Metodo de la Superclase al. Conceptos Lo que hemos visto en la motivación ha sido lo que hasta ahora sabemos de las clases y de las subclases (aparte de su sintaxis). Object Un ejemplo de utilización sería: Archivo arch = new Archivo(). ya que por defecto llama al de Object. double lado) en donde (x.

así que esto lo podríamos solucionarlo con un cast explícito a la subclase (que si está permitido). Java ejecuta el método que es heredado (virtualmente escrito. Para entenderlo un poco mejor. en alguna parte los crean . Sin embargo. arch.length. ¿Cómo es eso?. El Tipo Dinámico nos permite realizar esta “barbaridad” ya que la subclase es una especialización de su padre (superclase) y es posible decir que: “Todo ArchivoLectura también es un Archivo”. arch. String. que no conocemos si son de lectura o escritura: Archivo archs[]. no es el método original). Archivo arch. Por ejemplo si tuviéramos un arreglo de archivos.3) Capi tulo XII: Clases y Objetos clase Archivo. por lo que el compilador no encontrará como válido pedirla a Archivo el método abrir. Pero lo importante es el enlace dinámico que ocurre aquí. Pero qué pasa si hacemos lo siguiente: arch. En este caso prevalece la condición del tipo estático.getNombre() + ” es de á).print (archs[i]. también hay una limitante grande en el siguiente ejemplo: Archivo arch = new ArchivoEscritura(). pero también nos pone algunas restricciones. arch. veamos algunos ejemplos: Primero. Hasta ahora nada nuevo. esto quiere decir. Conclusión El enlace dinámico nos da la facultad de escribir métodos genéricos para un grupo de clases “del mismo tipo”. Este trozo de código que al parecer no tiene nada de malo. Este concepto nos explica un poco más sobre la instanciación de una variable. No obstante a que podamos hacer esto. es el tipo con el cual se instancia la variable. ¿Y para qué sirve hacerlo? Es útil porque si no pudiéramos hacerlo.println(”Lecturaá). ya que aunque el método setNombre esté declarado en la 85 86 . if (archs[i] instanceof ArchivoLectura) c.. arch = new ArchivoLectura(). Con esta instrucción uno puede comparar referencias a objetos y poder comparar el tipo dinámico sin conocerlo explícitamente. Tipo Dinámico El Tipo Dinámico de una variable es el tipo referenciado por ella. Mirando este tan básico ejemplo podemos ver que el tipo estático de arch es Archivo. arch = new ArchivoLectura(). ( (ArchivoEscritura) arch). Java no hace un cast implícito. i++) { c. estamos creando una instancia de esta clase.abrir().setNombre(”miarchivoá).txtá).. i<archs. Bueno. tendríamos que escribir el mismo código una y otra vez dependiendo de los distintos tipos de objetos que necesitáramos. Sintaxis Un elemento muy peculiar en Java es el llamado Instanceof. no funciona.Java: del Grano a su Mesa (Versio n 1. declararemos el tipo estático de arch como Archivo y el dinámico como ArchivoLectura. Por ejemplo: Archivo arch. al momento de su instanciación (segunda línea) estamos llamando al constructor de la clase ArchivoLectura.abrir(). Este tipo puede coincidir con el Tipo Estático como puede ser una subclase de él. diremos que estamos bautizando nuestro archivo de lectura..setNombre(”salida. reciclando subprogramas. En estos 3 casos es llamado Tipo Estático a la clase que hasta ahora hemos llamado TIPO de la variable. ¿Por qué? Si analizamos un poco nos daremos cuenta que arch es de tipo estático Archivo y no ArchivoEscritura que es en donde el método abrir existe. // .setNombre(”salida. el método que efectivamente es ejecutado es el que corresponde al tipo dinámico de la variable. Este concepto nos abre muchas puertas. es decir. Estos dos conceptos hacen el nacimiento del tercero y no menos importante término: Enlace Dinámico El Enlace Dinámico es una situación que ocurre cuando se invoca un método de un objeto referenciado por una variable. Archivo arch = new ArchivoEscritura(). es decir. que podremos saber si una variable es instancia de una clase o de otra.txtá).. Archivo y ArchivoLectura sería la respuesta correcta.3) Capi tulo XII: Clases y Objetos Java: del Grano a su Mesa (Versio n 1. for (int i=0.

Por ejemplo. Todos los métodos que se definen en una interface DEBEN ser públicos. 87 88 . } Interface Clase especial que permite definir las firmas de los métodos que DEBE poseer toda clase heredera de ella misma. public void ponerValor(Object o). y que no son comunes a Nodo. // Esto esta correcto Un ejemplo práctico es: public interface Arreglo { // Dimensionar un arreglo public void dimensionar (int n).length. } // Los siguientes metodos no corresponden a la definicion // de la interface public String sacar(int i) { return this. permite definir un patrón para la creación de las clases hija de una interface. } public void poner(int i.Java: del Grano a su Mesa (Versio n 1. ArregloArchivo. tenemos la clase que implementa la interface. Una Interface NO PUEDE tener objetos. ya que permite dar pautas para escribir clases de cierto tipo. Esto no limita a que podamos escribir más métodos. } Java: del Grano a su Mesa (Versio n 1. Sin embargo la clase ArregloString posee métodos que no son comunes con otros tipos de arreglos (ArregloEntero.println(”Desconocidoá). } } Como podemos ver no hemos construido ni declarado nada dentro de Nodo. Aquí estamos implementando un elemento llamado NodoArchivo que almacena un archivo e implementa los métodos de la interface Nodo. String x) { this.println(”Lecturaá). solo hemos puesto las firmas de los métodos. Entonces la interface Nodo quedaría así: public interface Nodo { public Object sacarValor(). else // caso que es instancia de Archivo c.3) Capi tulo XII: Clases y Objetos else if (archs[i] instanceof ArchivoEscritura) c. ya que su definición depende del tipo de la variable de instancia de la clase propia (els). } Esta Interface define la estructura (interface) general que tienen todos los arreglos: ver y dimensionar el tamaño del arreglo (cantidad de elementos). etc). } } Como podemos observar. // Esto esta errado Clase Abstracta Una Clase Abstracta es un híbrido entre una Interface y una Clase normal que permite definir métodos y variables de instancia (como en las clases normales) pero también dejar por definir en los hijos de la clase algunos métodos (como en las interfaces). escribamos un Nodo que nos permita almacenar una clase Archivo: public class NodoArchivo implements Nodo { private Archivo arch. Implementemos ahora entonces un arreglo de Strings a partir de esta interface: public class ArregloStrings implements Arreglo { private String els[]. public ArregloString() { } // Se implementan los metodos de la interface public void dimensionar(int n) { this. por el contrario. Siempre nacerán funcionalidades específicas que solo NodoArchivo tendrá. es decir: Nodo n = new Nodo().els[i]. podemos declarar una interface llamada Nodo que permite almacenar un elemento cualquiera con características no definidas.3) Capi tulo XII: Clases y Objetos Nodo n = new NodoArchivo(). es decir.els = new String[n].els[i] = x.els. public Object sacarValor() { return arch. porque están definiendo la forma de comunicación que tendrán los programas con las clases que IMPLEMENTEN esta interface. Fíjate que todos son públicos. } public void ponerValor(Object o) { // Debemos suponer que o es de tipo dinamico Archivo arch = (Archivo) o. Por ejemplo. // Largo de un arreglo public int largo(). Este concepto bastante extraño es muy útil. } public int largo() { return this.

// En este caso no tiene metodos propios } Solo eso. } public void abrir () { this.bf. ya que los archivos de lectura/escritura se diferencian en lo que hacen entre el abrir y cerrar. queda claro como la clase se implementa luego: public class ArregloStrings extends Arreglo { private String els[].els = new String[n].nombre ) ). // Constructor vacıo public ArchivoLectura() { } // Los metodos de la interface public void darNombre (String nombre) { this. String x) { this.els[i]. } public void poner(int i.close(). public void cerrar().3) Capi tulo XII: Clases y Objetos Las clases abstractas en general son utilizadas como interfaces más especializadas.3) Capi tulo XII: Clases y Objetos } // Se implementan los metodos de la clase abstracta public void dimensionar(int n) { this. Es decir: public class NodoArchivo extends Nodo { // Ya no se necesitan variables de instancia // Se DEBE implementar public Object sacarValor() { return arch.els[i] = x. Veamos el caso de los arreglos pero con clase abstracta (más fácil): public abstract class Arreglo { // Se presentan los metodos que seran implementados public abstract void dimensionar(int n). } public int largo() { return this. } Vemos claramente que cambia un poco el punto de vista que se puede utilizar para este tipo de casos. igual que INTERFACE public abstract Object sacarValor(). } // Los siguientes metodos no corresponden a la definicion // de la clase abstracta public String sacar(int i) { return this. public class ArchivoLectura implements Archivo { private BufferedReader bf.els. // Para que se definan en los hijos. // pues lo esta en la superclase Nodo. public abstract int largo(). Veamos primero la implementación con Interface: public interface Archivo { public void darNombre(String nombre). NO SE PUEDE tener un objeto del tipo de la clase abstracta. } } Ahora bien. public void abrir().bf = new BufferedReader ( new FileReader( this. Su única regla es que DEBEN implementar aquellos métodos definidos como abstractos en la superclase. La sintaxis de una clase abstracta es muy similar a la de las clases normales. private String nombre. Sin embargo.Java: del Grano a su Mesa (Versio n 1. } public void cerrar () { this. pero con líneas de código útil y que hacen cosas. } Al igual que las interfaces. } } Java: del Grano a su Mesa (Versio n 1. } ¿Alguna diferencia? Solución al Problema Es muy interesante ver el problema de los Archivos de Lectura y Escritura con clases abstractas e interfaces. public ArregloString() { 89 90 .length.nombre = nombre. sin embargo posee algunos elementos adicionales: abstract class Nodo { // Puede tener variables de instancia Object elto. } // El metodo ponerValor() no es necesario implementarlo. las clases que hereden de Nodo en este caso NUNCA sabrán que su padre es una clase abstracta. // y para definir como en clases normales public void ponerValor(Object o) { elto = o.

} // Metodos propios public void escribeLinea(String linea) { this. } } public class ArchivoEscritura implements Archivo { private PrintWriter pw.3) Capi tulo XII: Clases y Objetos Java: del Grano a su Mesa (Versio n 1. this.readLine().3) Capi tulo XII: Clases y Objetos Hey. } } public class ArchivoEscritura extends Archivo { private PrintWriter pw.abrir(). Su definición es la siguiente: 91 92 . } public void cerrar () { this.bf = new BufferedReader ( new FileReader( this.pw = new PrintWriter ( new FileWriter( this.nombre ) ). } } Mucho más bonito que lo que alguna vez vimos ¿no?. } // Metodos propios public void escribeLinea(String linea) { this.bf. } public void cerrar () { this. Problemas Se tiene la clase Carta que permite modelar una carta de un mazo de cartas inglesas (de póker).nombre = nombre. public abstract void cerrar ().bf. } public void abrir () { this. Bueno la utilización de estas clases queda a discreción de ustedes. Veamos como quedan los tipos: public class ArchivoLectura extends Archivo { private BufferedReader bf..printLine(linea). // Constructor public ArchivoLectura (String nombre) { super(nombre).readLine().close().. } } // Metodos propios public String leeLinea() { return this. public abstract class Archivo { // Declaremos el comun de ambos tipos // No es privado porque quiero que lo lean los hijos protected String nombre // Los por implementar son abrir y cerrar public abstract void abrir (). // El generico public void darNombre (String nombre) { this. // Constructor vacıo public ArchivoEscritura() { } // Los metodos de la interface public void darNombre (String nombre) { this. Pero es cosa de gustos y elegir cuál es mejor no es el problema.nombre = nombre. } // Los metodos de la clase abstracta public void abrir () { this.pw. } public Archivo (String nombre) { this.bf. } // Metodos propios public String leeLinea() { return this.printLine(linea).pw = new PrintWriter ( new FileWriter( this. J Ahora veamos la implementación de Archivos con Clase Abstracta.pw. private String nombre.nombre ) ).close(). } } Se nos simplifica más la solución.nombre ) ).darNombre(nombre).bf. pudimos implementar el darMombre sin tener el problema del tipo de archivo. ya que si repasamos más ese tema quedaremos más complicados. // Constructor vacıo public ArchivoEscritura() { } // Los metodos de la clase abstracta public void abrir () { this.bf. } public void cerrar () { this.Java: del Grano a su Mesa (Versio n 1.close().

poner(c2[j2]). j2 = 0.length) { this. this.3) Capi tulo XII: Clases y Objetos new Carta(pinta. if (n > 12) numero = ”Ká.corte] = this. pinta++) { for (int n=1.m = new Cartas[52].m[this. Esto elimina la carta del mazo.indice++.length) { this. String n) { this..length && j2 > c2. } } (b) Escriba el método privado void mezclar() que permite aleatoriamente mezclar el mazo.poner(c1[j1]).poner(c1[j1]).3) Capi tulo XII: Clases y Objetos public class Carta { private String pinta. es decir: 1.length) { if (i % 2 == 0) { this. } while (j2 > c2. } // Y luego volvemos una a una las cartas del mazo actual int j1 = 0. Para ello utilice la siguiente definición de la clase: Mazo () void poner(Carta c) Carta sacar() (Constructor) Crea un nuevo mazo de cartas.numero + ”-” + this. Carta c2) { . } } public Carta (int p.poner(c2[j2]).indice]. private String numero. j1++. j2++. } public String verCarta () { return this. 3. Nota: En este caso considere las pintas como un número.Java: del Grano a su Mesa (Versio n 1..indice = 0. if (n > 10) numero = ”Já. Diamantes Corazones Tréboles Picks Solución public class Mazo { private Cartas m[].corte]. while (j1 > c1. // 1 si c1 > c2 // 0 si c1 = c2 // -1 si c1 < c2 .indice++. Llena el mazo.sacar(). } } while (j1 > c1.m[this.. } } } public void poner (Carta c) { this.pinta } static public int compararCarta (Carta c1. for (int pinta=1. // Creamos los 2 mazoz Cartas c1[] = new Cartas[corte]. i++) { if (i < corte) c1[i] = this. else c2[i . this. this. return this. j1++. private int indice.indice] = c. j2++.trunc(Math. i<52.random()*52).numero = n. public Mazo () { this..m[this. // Luego repartimos los submazos for (int i=0. Solución Tiene muchas soluciones. 2. this. } (a) Escriba la clase Mazo que permite modelar el mazo de cartas. n++) { String numero = (String) n. Java: del Grano a su Mesa (Versio n 1.indice] = 93 94 . 4. } else { this. pero veremos solo una: private void mezclar() { // Cortamos el mazo actual int corte = Math. n<14. if (n > 11) numero = ”Qá.sacar().indice--. this. numero). pinta<5.pinta = (String) p. } public Carta sacar () { this. Pone la carta c en el mazo (en la primera posición) Saca la primera carta del mazo. Cartas c2[] = new Cartas[52 .

sqrt(Math. int n = this.length]. Para ello considere que esta clase posee el siguiente constructor: public Triangulo (double x[]. this. int n = this. } Solución public interface Figura { public double perimetro().y[i]. } public class Triangulo implements Figura { protected double x[]. return p. es decir. Solución public abstract class Figura { protected double x[]. } (d) Se desea implementar la clase abstracta Figura que permita modelar una figura genérica a partir de segmentos de rectas unidas por vértices. i<n. double x2.y = y. } public void revolver(int n) { for (int i=0. Firma del método que definirá cada uno de las áreas de figuras que hereden de esta clase. for (int = 0.x[0]. super. super.length]. this. (x[i]. i++) mezclar().x[i+1]. La definición de la clase es la siguiente: Variables de Instancia public double Perimetro() public abstract double Area() Representación con 2 arreglos de double para almacenar las componentes x e y. this.sqrt(Math. double y2) { return Math. this.3) Capi tulo XII: Clases y Objetos (e) Construya la clase Triangulo a partir de la clase Figura para que permita modelar un triángulo. for (int = 0.length].y[i+1]). protected double y[]. i++) { p += this.length].distancia(this. escriba el método revolver para los siguientes casos (firmas): • • void revolver(): Revuelve una vez el mazo una vez. double y[]) en donde x e y son arreglos que traen 3 valores para cada una de las coordenadas de los puntos del triángulo.y = y.y = new double[y.x = x. this. } p += this. void revolver(int n): Revuelve n veces el mazo.pow(y2 ú y1)). this. Solución public void revolver() { mezclar(). (c) Utilizando (b).y[n ú 1].x[n ú 1]. double x2.y[i]. } public abstract double area(). } Solución public class Triangulo extends Figura { public Triangulo (double x[]. double y2) { return Math. super. Nota: No olvide implementar lo que sea necesario. } public double perimetro () { double p = 0.x.y[0]). public Triangulo (double x[].3) Capi tulo XII: Clases y Objetos } Java: del Grano a su Mesa (Versio n 1.distancia(this.x = x.length. protected double y[]. y[i]) es un punto. Calcula el perímetro del polígono. i < n .x[i].distancia(this. 95 96 . super. super. double y[]) { super. double y1.x. double y[]) { super.pow(x2 ú x1) + Math.x = new double[x. public abstract double area().x[i]. // Se declara el metodo abstracto public double area() { // PROPUESTO: Calculo a partir del perimetro } } (f) Rehaga el problema pero ahora utilizando una Interface en vez de una Clase Abstracta.x = new double[x. private double distancia (double x1.y = new double[y.1. i++) { p += this.pow(x2 ú x1) + Math. i < n . super. } public double perimetro () { double p = 0.pow(y2 ú y1)). this.1. double y1. } private double distancia (double x1.Java: del Grano a su Mesa (Versio n 1.length.

super.x[0]. double x2. } public Cuadrado(double x1. this.5 ú4. Triángulos y demases.-1 0.10 ú1.4 5. incluir dentro de la definición a Circulo como una clase que implementa Figura. (R)ectángulo o (F)igura Puntos: Par de coordenadas del tipo (X. Sin embargo lo anterior.2 2.distancia(this.agregarPunto(x2. double y2): Define un rectángulo a partir de dos vértices diametralmente opuestos. double y.x[n ú 1]. this. y2). double y1. -2 F 1.agregarPunto(x1. } public double area () { // PROPUESTO: Calculo a partir del perimetro } } Java: del Grano a su Mesa (Versio n 1. Por ejemplo: C 1. super.7 ú1. double y1. a partir de trozos de rectas que definen su contorno (hasta un círculo si lo trozos son pequeñitos). } public void definirRectangulo(double x1. x1+d. y) y de lado d. y1. this.-2 3.4 5.0 9. Mientras que en el caso de la utilización de Clase Abstracta el círculo lo DEBEMOS representar como un polígono. la clase puede representar cualquier figura en un plano. double y): Agrega un punto a la figura void sacarPunto(): Saca el último punto agregado de la figura double perímetro(): Obtiene el perímetro de la figura (suma de sus lados) (c) Escriba un método que permita leer desde un archivo de puntos formateado como: • • Tipo (1 carácter): (C)uadrado.y[0]). double y1.y[i+1]). double y2) { super(). double x2.Java: del Grano a su Mesa (Versio n 1. El modelo general (y más adecuado) sería: Clases Abstracta Polígono (b) Implementar la subclase Cuadrado a partir de Rectangulo solo con el constructor: • • Cuadrado(double x. Círculo Solución public class Cuadrado extends Rectangulo { public Cuadrado() { super(). Con esta definición.1 1.-2 10. y1).2 2. y1). Y que las almacene en un arreglo de Figura. double d): Define un cuadrado desde el punto (x.10 .Y) y separadas hasta el fin de línea. y1+d).definirRectangulo(x1. } } (d) ¿Qué ventajas tiene utilizar una con respecto a la otra solución? Solución Al utilizar Interface tenemos la capacidad de.. super. this. super.x[i+1].3) Capi tulo XII: Clases y Objetos this. } } Triángulo Cuadrado Clases Otro Problema (Sacado de un control de hace un par de años atrás) Un problema bastante real sería suponer que existe una clase Figura con los siguientes métodos: • • • • Figura(): Constructor vacío que no hace nada void agregarPunto(double x. double d) { super.agregarPunto(x1.agregarPunto(x2.1 R 3. en este caso. usar Clase Abstracta queda más apropiado según las especificaciones ya que la repetición de algunos métodos no pasa (por ejemplo el del perímetro para figuras como Cuadrados. } p += this. Cuadrado(): Constructor que no hace nada. Interfaz Figura Nota: La superclase de Cuadrado es Rectángulo.. y2).3) Capi tulo XII: Clases y Objetos • • Rectangulo(): Constructor que tampoco hace nada void definirRectangulo(double x1. Solución public class Rectangulo extends Figura { public Rectangulo() { super().y[n ú 1]. return p. (a) Se pide implementar una subclase Rectangulo que tenga los siguiente métodos: 97 98 .

String linea. x = new Double( linea. pero una es un cuadrado.indexOf(”. while ((espacio = linea.agregarPunto(x. for (int i=0. figs[i]. int i=0. } // Y ahora ponemos los puntos de la figura linea = linea.doubleValue().substring(coma + 1. Ok! Contando cuantas figuras hay: Cuadrados: 10 Rectangulos: 2 Otras figuras: 27 Solución public Figura[] leerArchivo(String nombre) { // Declaramos el arreglo de resultados Figura figs[]. Es muy importante fijarse en los espacios que vienen entre cada par de datos) Nota: El nombre de archivo viene por parámetro y vienen 100 figuras en el archivo.print(”Nombre de archivo de entrada?á).substring(espacio + 1).á). // Se leen los puntos c.substring(2). y. length(linea) .readLine(). int espacio. Solución Console c = new Console(). y = new Double( linea.3) Capi tulo XII: Clases y Objetos (Estas son 3 figuras.println(”Rectangulos: ” + nR).println(”Contando cuantas figuras hay:á). coma) ).á).coma) ). y).substring(0. case ”Rá: figs[i] = new Rectangulo().print(”Ok!á). Para ello son necesarios los siguientes métodos: MapaEnteros (int n) void agregar (int i. c. coma) ).println(”Cuarados: ” + nC). nF = 0. double x.. else // figs[i] instanceOf Figura nF++.doubleValue(). c.substring(0. // Inicializamos el arreglo // Ojo que cada casilla requiere un posterior NEW figs = new Figura[100]. i<figs. figs[i]. Saca el elementos de la posición i del mapa.length. int x) int sacar (int i) (Constructor) Crea un nuevo mapa de enteros vacío de n elementos.close(). otra un rectángulo y otra una figura cualquiera. Java: del Grano a su Mesa (Versio n 1. switch tipo { case ”Cá: figs[i] = new Cuadrado().print(”Leyendo puntos. c. Problemas Propuestos (a) Volviendo al tema de la motivación.. coma. nR = 0.agregarPunto(x. á). crear a partir de un Mapa (superclase). i<100. x = new Double( linea.Java: del Grano a su Mesa (Versio n 1. case ”Fá: figs[i] = new Figura().3) Capi tulo XII: Clases y Objetos } (d) Escribir un programa que utilice (c) para simular el siguiente diálogo: Nombre de archivo de entrada? puntos. Note claramente que el agregar no ha cambiado. linea = linea. else if (figs[i] instanceOf Rectangulo) nR++. } c. i++) { linea = bf. espacio .indexOf(”.. // Ahora se cuentan las figuras c. // Discriminamos el tipo de figura String tipo = linea.doubleValue(). } coma = linea.coma) ). int nC = 0. ¿Deberá implementarlo entonces? 99 100 .readLine(). } bf..txt Leyendo puntos. la clase MapaEnteros (subclase) que permita almacenar solo números enteros en el mapa. i++) { if (figs[i] instanceOf Cuadrado) nC++. String nombre = c. Figura figs[] = leerArchivo(nombre).charAt(0). // Retornamos el arreglo de figuras return figs. c. for (int i=0. // Leemos el archivo BufferedReader bf = new BufferedReader( new FileReader(nombre)).println(”Otras Figuras: ” + nF). Agrega el entero x a la posición i del mapa.indexOf(” ”)) > 0) { coma = linea. y). y = new Double( linea.doubleValue().substring(coma + 1.

8 (2) ındice de 7. mediciones[n] = c. Por ejemplo: String nombres[] = new String[100]..á). sin embargo.println(”Bienvenido al Sistema de Control de Contaminacioná)..8 (3) ındice de 7.println(”Clave Rojaá). puede ser un máximo de 100 (para que use un arreglo). c. Esta definición bastante básica es la que nos permite entender que es un algoritmo de ordenamiento.3) Capi tulo XIII: Ordenamiento y Bu squeda Java: del Grano a su Mesa (Versio n 1.0 es clave roja). if (pat. } Capítulo XIII: Ordenamiento y Búsqueda Motivación El MTT ha decidido almacenar las mediciones que realiza a los vehículos en un lugar de Santiago.equals(”0á) || n == 100) break.print(”Indice registrado?á). n). etc).println(”Bienvenido senor..print(”Ingrese patente del vehıculo?á). 2. de mayor a menor.readDouble(). c. int code = c.print(”Ingrese el codigo del Inspector?á).readInt().println(”Se han registrado ” + n + á mediciones:á). lexicográficamente. Ingrese patente del vehıculo? 0 Se han registrado 53 mediciones: (1) ındice de 7. La solución a este problema es bastante sencilla: Console c = new Console(). String pat = c.readLine().Java: del Grano a su Mesa (Versio n 1.1 Clave Roja . es decir. para tener una estadística más clara. pero esta vez ordenadas de mayor a menor. no se sabe cuál es el índice que se está ingresando (mayor que 5. el programa consta de 2 partes: 1.. } // n sale con el numero del siguiente elemento o 100 // que es lo mismo que el NUMERO de elementos // por lo tanto enviaremos a un metodo el arreglo // entre 0 y el maximo + 1 para que quede completa// mente ordenado.6 Solo nos queda pendiente como ordenar el arreglo. int n = 0.println(”Clave Verdeá).3) Capi tulo XIII: Ordenamiento y Bu squeda double mediciones[] = new double[100]. i++) { c. (53) ındice de 2. c.. El ordenamiento de arreglos es muy útil para realizar búsquedas de elementos. La lectura de datos termina con una patente 0 y no e sabe el número de mediciones. J Conceptos Ordenamiento Es un algoritmo que nos permite cambiar el orden (de posición) los elementos para dejarlos ordenados según un criterio fijo (numéricamente. de menor a mayor. c. ordenarArreglo(mediciones. 101 102 . 0. // en alguna parte de se ingresan los nombres // desordenadamente String nombreBuscado = ”Morales Gutierrez Carlos Albertoá. pero no tiene mucho sentido si no hay una aplicación tangible. puesto que cuando buscamos dentro de un arreglo un elemento específico (por ejemplo el nombre de una persona) deberíamos usar la “fuerza bruta” para encontrarlo. Recolectar los datos de cada medición durante el día. while(true). Como se ve en el diálogo. for (int i=0. desplegamos c. Estas mediciones son al azar. Ingrese patente del vehıculo? HG 5857 Indice registrado? 3.. c. if (mediciones[n] > 5. // Ahora que esta ordenado.6 Clave Verde Ingrese patente del vehıculo? AS 2216 Indice registrado? 5. Para esto requiere que se le realice un programa que haga el siguiente diálogo: Bienvenido al Sistema de Control de Contaminacion Ingrese el codigo del Inspector? 538 Bienvenido senor. i<n.println(”(” + (i+1) + á) ındice de á + mediciones[i]).7 (4) ındice de 7.8 Clave Verde Ingrese patente del vehıculo? ZZ 3481 Indice registrado? 2.2 . else c. n++.0) c. Desplegar en pantalla las mediciones realizadas.

Pero no todo es tan malo. esto quiere decir (y lo anotaremos así) que: T(n) = O(n2) Se leerá como: “El tiempo que toma el algoritmo es de orden n 2”. 100 o 1. Entonces. 2. pero para eso. es decir. Buscar el mayor de todos Ponerlo en la primera (o última) posición de un arreglo auxiliar “Anular” el mayor Volver a hacer desde 1 hasta que no quede ninguno Definamos como T0 el tiempo de ejecución de toda línea de código fuera de los ciclos. por lo tanto empezamos de un punto más en la mitad. En la práctica (aunque parezca un chiste) podemos tomar 3 casos: • • • Mejor Caso (arreglo ordenado): O(n2) Peor Caso (arreglo muuuuuy desordenado): O(n2) Caso Promedio (otro caso normal): O(n2) 103 104 . ¿Cómo se hace?. a “Morales” no lo buscaremos al principio.equals(nombreBuscado) ) { i++. partiendo del base que es una forma exhaustiva. 3. i--) { int maximo = 0 Ciclo 2 for (j=0. Sin embargo definiremos lo que es la eficiencia de los algoritmos. ¿Se imaginan que pasaría si la guía de teléfono estuviera desordenada y ustedes quisieran encontrar el teléfono de un tío? ¡¡Qué locura!!. el arreglo hay que ordenarlo. ordenar un elemento tomará el siguiente tiempo: T(1) = T0 + 1 * T1 + 1 * T2 T0 es siempre constante. “Martinez” y “Ortega”. en donde están los “Lorca”.3) Capi tulo XIII: Ordenamiento y Bu squeda for (int i=nEls-1. while ( ! nombres[i]. tenemos el problema que si la persona hubiese sido la última en el arreglo. es decir. pues esto es en teoría. algo que puede ser un punto crítico al momento de elegir una forma de ordenar una serie de datos. Eficiencia En los algoritmos. ya que el for repite esas instrucciones como número de elementos tengamos. Pero no es tan sencillo medir ese tiempo como tomar un cronómetro y ver cuánto se demora en hacer un algoritmo su trabajo con 10. ya que siempre se ejecutará 1 vez independiente de la cantidad de veces que ejecutemos el método. sin embargo T1 y T2 están dependiendo de la cantidad de elementos. Esto significa que si tomamos un arreglo de 100 elementos.000 (5 ceros algo alto cuando hablamos de 1. } Si nos ponemos a analizar este programita para buscar un nombre. // Ciclo 1 T(n) = T2 * n2 + T1 * n + T0 Diremos entonces que el orden del algoritmo es el término variable de mayor exponente dentro de la cuadrática. para n elementos nos quedaría: T(n) = T0 + n * T1 + n * (n * T2) Desarrollando un poquito: Esta es la forma básica. } auxiliar[i] = arreglo[maximo]. es decir no considera los valores dentro de su ejecución. en el fondo nada. int nEls) { int auxiliar[] = new int[nEls]. arreglo[maximo] = -1. porque lo más probable que allí estén “Astorga”. de la siguiente forma: 1. pues al final siempre ordenan un arreglo (de lo que sea). Si la lista de nombres está ordenada. Para medir la eficiencia existe un examen llamado análisis de tiempo que nos permite obtener el valor algebraico del tiempo que nos da la idea de la magnitud del tiempo que puede tomar el algoritmo es su ejecución expresado en función de la cantidad de elementos que posee (cantidad de elementos del arreglo en el caso de ordenamiento).000 de elementos). i>0.Java: del Grano a su Mesa (Versio n 1. Pero ¿qué diferencia hay con los algoritmos de ordenamiento?. pues los tiempos que puede tomar son milisegundos. // Se elimina como posible sgte } arreglo = auxiliar. T1 el tiempo que toma las líneas del ciclo 1 y T 2 las del ciclo 2.000 datos. 4. j++) { // Ponemos el maximo en la ultima posicion if (arreglo[maximo] < arreglo[j]) maximo = j.000. el orden de magnitud del algoritmo será de 10. Todas se miden en forma independiente de las otras. j<nEls. Existen algoritmos de ordenamiento. Bueno. tuvimos que recorrerlo completo para encontrarlo. } Java: del Grano a su Mesa (Versio n 1.3) Capi tulo XIII: Ordenamiento y Bu squeda int i = 0. Veamos cómo analizar el caso de ordenamiento exhaustivo: public void ordenar (int[] arreglo. la eficiencia se mide como el tiempo que toma un algoritmo en realizar su finalidad. “Araya” y todos los primeros apellidos.

Se han definido como base los siguientes: Algoritmo de Selección y Reemplazo Algoritmo de la Burbuja (BubbleSort) QuickSort MergeSort Advertencia: Lo algoritmos de ordenamiento en general se pueden implementar en forma iterativa (for. Olvidarse del máximo ahora y seguir. Se intercambia el último elemento por donde está el máximo c. Veamos como funciona el algoritmo se selección que no utiliza un arreglo auxiliar. . ya que no lleva un patrón fijo de búsqueda del máximo valor (lo que pasa cuando buscamos en un arreglo desordenado. j<nEls. arreglo[i] = auxiliar. Pues sí.3) Capi tulo XIII: Ordenamiento y Bu squeda 2.. } auxiliar[i] = arreglo[maximo]... Veamos como se vería recursivamente: 105 106 . i>0. hasta antes de donde debe estar. int nEls) { for (int i=nEls-1. no repasamos todo el arreglo en cada iteración. // Se elimina como posible sgte } arreglo = auxiliar. Se busca donde está el siguiente máximo b. i--) { int maximo = 0 for (j=0. El arreglo se ordena entre 0 y nEls a. J Veamos ahora cómo escribiríamos eso en forma iterativa: void ordenarArreglo (int arreglo[]. Es muy eficiente y fácil de implementar. 1. j<i. porque si observamos con algo de detención nos daremos cuenta que el segundo for (j) solo recorre hasta el elemento en donde pondremos el máximo –1. Terminar.. Olvidarse del siguiente máximo ahora y seguir.. } int auxiliar = arreglo[maximo]. i>0. Es recomendable que repacen el capítulo de Recursividad para entender mejor este. 3. Pero de todas formas hicimos 2 ciclos. ¿No hay demasiada diferencia con la “fuerza bruta” como le llamamos?. Se busca donde está el máximo b. arreglo[maximo] = -1..Java: del Grano a su Mesa (Versio n 1. El arreglo se ordena entre 0 y nEls-1 a. j++) { // Buscamos el maximo if (arreglo[maximo] < arreglo[j]) maximo = j. } Así.3) Capi tulo XIII: Ordenamiento y Bu squeda Existen muchos algoritmos de ordenamiento definidos que nos permiten eficiencia en el ordenamiento.. int nEls) { // Crearemos un arreglo auxiliar del mismo tamano int auxiliar[] = new int[nEls]. es decir. i--) { int maximo = 0 for (j=0.. porque un arreglo de un elemento está ordenado. Veamos como lo haría una persona inexperta y sin conocimientos para ordenar un arreglo (solo valores positivos por simplicidad): void ordenarArreglo (int arreglo[]. Gráficamente podemos ver esto como: 3 8 2 9 4 1 3 8 2 1 4 9 3 4 2 1 8 9 3 1 2 4 8 9 1 2 3 4 8 9 Algoritmo de Selección y Reemplazo Probablemente este sea el algoritmo más intuitivo que existe. Java: del Grano a su Mesa (Versio n 1. Se intercambia el penúltimo elemento por donde está el siguiente máximo c. pues utiliza una metodología bastante básica que se puede analizar. } } Este método lo que hace es ordenar en FORMA BRUTA un arreglo no es muy eficiente. while) pero son mucho más eficiente cuando se utiliza la recursividad. Ultima. j++) { // Ponemos el maximo en la ultima posicion if (arreglo[maximo] < arreglo[j]) maximo = j. pero solo cuando los arreglos son pequeños. El arreglo se ordena entre 0 y 0 a. arreglo[maximo] = arreglo[i]. // Vamos sacando cada uno de los elementos y // los vamos almacenando el el auxiliar ordenadamente // (Supongamos valores positivos) for (int i=nEls-1. como ya mencionamos).

. j<nEls-2.. ordenarArreglo(arreglo. } Java: del Grano a su Mesa (Versio n 1. int maximo = 0 for (j=0. arreglo[maximo] = arreglo[nEls-1]. La idea es muy similar al de selección. T0 : En este caso es 0 T1 : Se ejecuta n veces T2 : Se ejecuta una cantidad de veces variable dependiendo del valor de i Hagamos la ecuación general de inmediato: T(n) = T0 + n * T1 + A donde A es la cantidad de veces que se ejecutó el ciclo 2 y se expresa como: A = T2 * n + T2 * (n-1) + .. arreglo[i] = auxiliar. intercambiar por el potencial máximo. nEls-1).3) Capi tulo XIII: Ordenamiento y Bu squeda void ordenarArreglo (int arreglo[]. no ha sido mejor que el fuerza bruta. La diferencia está en que no solo intercambia el máximo con el último. Así que los grandes genios de la computación estuvieron buscando otro similar y tan fácil de aprender como el de selección para así dar a luz este algoritmo llamado de la Burbuja. Veamos como se comporta la eficiencia de este algoritmo: void ordenarArreglo (int arreglo[]. i--) { int maximo = 0 // Ciclo 2 for (j=0. Si el siguiente es menor que el que tengo en la burbuja. Juega con las matemáticas. Si el segundo es mayor que el de la burbuja. sino que va “desplazando” los candidatos a máximo hasta posiciones más avanzadas de las que se encuentran. arreglo[nEls-1] = auxiliar. poner el siguiente ahora como potencial máximo.. c. Si el tercero es menor que el que tengo en la burbuja. Así sucesivamente quedaría al final ordenando el arreglo HASTA que quede un elemento. Y veamos en la práctica: • • • Mejor Caso: O(n2) Peor Caso: O(n2) Caso Promedio: O(n2) Malo malo. Desafío: Realizar el intercambio de posiciones. Si el siguiente es mayor que el de la burbuja. arreglo[maximo] = arreglo[i]. es decir.. Ordenar entre 0 y nEls: a. arreglo[nEls-1] = auxiliar. intercambiar por el potencial máximo.. int nEls) { if (nEls == 1) return. . El algoritmo (paso general) quedaría algo como: 1. j<i. } } Pero sin utilizar una variable auxiliar.Java: del Grano a su Mesa (Versio n 1. Si el tercer es mayor que el de la burbuja. poner el segundo ahora como potencial máximo. e. arreglo[maximo] = arreglo[nEls-1]. intercambiar por el potencial máximo. i>0. va ordenando parcialmente. tar da mucho en ordenarlos. pues utiliza el caso general (ordenar entre 0 y nEls) y luego va y vuelva a llamar al caso general con un elemento menos (ordenar entre 0 y nEls-1). + T2 * 2 + T2 * 1 <= T2 * n2 107 108 . de ir inter cambiando los valores hasta dejar el máximo en el último lugar del arreglo. Si el segundo es menor que el que tengo en la burbuja.3) Capi tulo XIII: Ordenamiento y Bu squeda Con esta última igualdad podemos decir que: T(n) <= T2 * n2 + T1 * n T(n) = O(n2) Nuevamente volvemos a ver que es un orden cuadrático. Acá podemos verlo que hace exactamente lo que explicamos arriba como algoritmo. int nEls) { // Ciclo 1 for (int i=nEls-1. poner el tercero ahora como potencial máximo. es decir: int auxiliar = arreglo[maximo]. j++) { if (arreglo[maximo] < arreglo[j]) maximo = j. } int auxiliar = arreglo[maximo]. b. d. Tomar el primero como potencial máximo dentro de una burbuja. } int auxiliar = arreglo[maximo]. Algoritmo de la Burbuja (Bubblesort) La desventaja de utilizar selección y reemplazo es que en arreglos muy grandes. j++) { // Buscamos el maximo if (arreglo[maximo] < arreglo[j]) maximo = j.

arreglo[j] = arreglo[j+1]. j++) { if (arreglo[j] > arreglo[j+1]) { int auxiliar = arreglo[j]. j<i-1. La forma recursiva es bastante sencilla. } } } } 4 9 1 1 9 A modo explicativo suele ser complejo escribir una descripción verbal. 3 2 8 9 4 3 8 3 2 8 9 4 1 8 9 3 2 8 9 4 1 3 2 8 4 9 1 Midamos la eficiencia de este algoritmo: void ordenarArreglo (int arreglo[]. y dejándolo al final. Veámoslo en forma iterativa primero: void ordenarArreglo (int arreglo[]. y es: void ordenarArreglo (int arreglo[]. for (j=0. pues lo que vamos haciendo es ir desplazando al máximo desde donde esté. int nEls) { // Arreglo de 1 elemento esta ordenado if (nEls == 1) return. burbuja puede ser más eficiente. es como super raro!. j++) { if (arreglo[j] > arreglo[j+1]) { int auxiliar = arreglo[j]. cosa que en el algoritmo de selección no ocurría.. Java: del Grano a su Mesa (Versio n 1. reventar la burbuja. int nEls) { for (int i=nEls-1. el for de i que estaba antes casi ni se nota que no está.3) Capi tulo XIII: Ordenamiento y Bu squeda ordenarArreglo(arreglo. j<i-1. porque en el intercambio si influía. si vemos la práctica: • • • Mejor Caso: O(n) Peor Caso: O(n2) Caso Promedio: O(n2) Como podemos ver usamos mucho menos código. Pero veamos realmente en serio cómo podemos ser eficaces al momento de ordenar un arreglo: 109 110 . y volver a repetir todo el procedimiento hasta nEls-1.. + T2 * 2 + T2 * 1 <= T2 * n2 Con esta última igualdad podemos decir que: T(n) <= T2 * n2 + T1 * n T(n) = O(n2) Nuevamente volvemos a ver que es un orden cuadrático. No es tan malo después de todo. De hecho. ya que en arreglos semi-ordenados... } ¡Hey. Veamoslo gráficamente: 3 8 2 9 4 1 3 8 2 9 4 1 8 2 Difiere en casi nada la forma general. i--) { // Ciclo 2 for (j=0. sin andarlo “buscando” antes. arreglo[j+1] = auxiliar. j<nEls-2. arreglo[j+1] = auxiliar.. i--) { for (j=0. int nEls) { // Ciclo 1 for (int i=nEls-1. i>0. Al último. } } } } Veamos el análisis: T(n) = T0 + n * T1 + A donde A es la cantidad de veces que se ejecutó el ciclo 2 y se expresa como: A = T2 * n + T2 * (n-1) + .Java: del Grano a su Mesa (Versio n 1. nEls-1).. i>0. Pero no es difícil de entender al programarlo. encontrándolo en el camino. } } ¿Por qué ha cambiado el mejor caso? Pues porque ese caso está condicionado por un if que puede anular T 2 cuando está ordenado el arreglo (jamás entra). arreglo[j] = arreglo[j+1].3) Capi tulo XIII: Ordenamiento y Bu squeda f. Pero en este caso. arreglo[j+1] = auxiliar. arreglo[j] = arreglo[j+1]. j++) { if (arreglo[j] > arreglo[j+1]) { int auxiliar = arreglo[j]. ya que no pasará el 100% de las veces por el código del ciclo 2.

Veamos cómo lo hace: Caso Base: • Si el arreglo tiene uno o ningún elemento. Su nombre nos indica (y hasta ahora es así) que es el más óptimo que existe. i < l. for(int i = 0. iMin.3) Capi tulo XIII: Ordenamiento y Bu squeda MergeSort Este algoritmo se basa en el principio de “dividir para reinar”. } else { a[i+iMin] = temp[i1++]. int i2 = k-iMin+1. int iMax) { // Caso base if (iMin >= iMax) return. para todo i > k Pero no significa que a cada lado del pivote esté ordenado. Veamos como funciona el código: void quickSort (int arreglo[]. a[k] = a[iPiv]. i++) { temp[i] = a[iMin+i]. a[k] = a[j]. para i = k A[i] > pivote. Es recursivo y funciona bastante bien. } Este método ordena un arreglo entre los índices iMin y iMax. a[j] = aux. k+1. i++) { if(i2 <= iMax-iMin) { if(i1 <= k-iMin) { if(temp[i1] > temp[i2]) { a[i+iMin] = temp[i2++].3) Capi tulo XIII: Ordenamiento y Bu squeda Java: del Grano a su Mesa (Versio n 1. } int aux = a[k]. k+1. va dividiendo el arreglo en problemas más pequeños para realizar el ordenamiento. iMin. Es sumamente corto. Caso General: • Corta por la mitad el arreglo • Ordena cada mitad con MergeSort • Mezcla las mitades para que queden ordenadas. mergeSort(a. int aux = a[k]. } } else { a[i+iMin] = temp[i2++]. está ordenado. iMax). para todo i < k A[i] = pivote. } } else { a[i+iMin] = temp[i1++]. int j = k + 1. int iMin. Es decir debe cumplir que: A[i] < pivote. for(int i = 0. int temp[] = new int[l]. int iMax) { int iPiv = iMin.Java: del Grano a su Mesa (Versio n 1. int iMax) { // Caso Base if(iMin >= iMax) { return. i < l. iMin. escribamos el algoritmo en líneas de código con Java: void mergeSort (int a[]. k). quickSort(arreglo. Ahora. } // Mezclamos int i1 = 0. // Caso general int k = particionar(arreglo. k-1). iMax). más eficiente que los anteriores. int iMin. ya que la mayor parte del trabajo la hace el método particionar: int particionar (int a[]. mergeSort(a. while(j <= iMax) { if (a[j] < a[iPiv] ) { // Vamos poniendo el pivote en medio k = k+1. quickSort(arreglo. es decir. } j++. } // Cortamos para aplicar mergeSort recursivamente int k = (iMin+iMax) / 2. se ha desarrollado bajo recursividad. La idea es que QuickSort toma un elemento dentro de el arreglo como pivote y luego pasa todos los elementos menores que el pivote a la izquierda y los mayores que el pivote a la derecha. // Utilizamos un arreglo temporal int l = iMax-iMin+1. int k = iMin. } } } ¡Es como mezclar 2 trozos de una baraja de cartas (como en Las Vegas)! Si vemos el análisis de orden llegaremos a: T(n) = O(n Log2n) en el caso promedio QuickSort Este algoritmo. iMax). int iMin. 111 112 .

tenemos en total 8 soluciones al problema que pueden ser utilizadas en forma indistinta (solo debemos cambiar el INT por DOUBLE y listo). bubbleSort(a.length-1). void mergeSort (int[] a. a. 0. 0. tendremos que: T(n) = O(n Log2n) Y si vemos la práctica: • • • Mejor Caso: ? Peor Caso: O(n2) Caso Promedio: O(n Log2n) Podemos hacer una ligera modificación a los algoritmos iniciales. a. Hasta ahora el mejor. int iMax): Algoritmo QuickSort donde a es el arreglo. Ya no es necesario pensar en un problema específico para resolverlo. Es realmente mejor en el caso promedio que los anteriores. a. a. int iMin. hasta llegar al mínimo: 1 elemento ordenado. con estos 4 método puedo ordenar trozos de un arreglo. Al final del ciclo se intercambia el a[k] por el pivote y queda la situación requerida. int iMax): Algoritmo MergeSort donde a es el arreglo. Se toma la posición iMin como pivote. para que se cumpla la situación de: a[i] < pivote si i < k a[i] >= pivote si i >= k 3. 4.Java: del Grano a su Mesa (Versio n 1. int iMin.length-1). Solución al Problema Con los algoritmos de ordenamiento y sus formas iterativas o recursivas. int iMax) quickSort (int[] a. En cada iteración con j mayor que el pivote y menor que iMax. En cada recursión el tamaño de los trozos se va achicando. return k. quickSort(a. no importa cuál es. En ambos caso se incrementa j para continuar y se vuelve a 2. Búsqueda Secuencial Veamos como encontrar un valor dentro de un arreglo en forma ineficiente: int buscar (int a[]. iMin es donde empieza el arreglo (0) y iMax es donde termina el arreglo (cantidad de elementos-1). Con esto vamos ordenando “relativamente” cada trozo de arreglo. a. se compara el a[j] con el pivote. 113 114 . Por eso definimos: Ejemplo Para todos los casos de ordenamiento que ya hemos visto. int n): Algoritmo de selección donde a es el arreglo y n es la cantidad de elementos. void bubbleSort (int[] a. mergeSort(a. Si analizamos este algoritmo.length-1). Para ordenar el arreglo a de las 4 formas distintas. 0.3) Capi tulo XIII: Ordenamiento y Bu squeda • void quickSort (int[] a. pues si el problema hubiese sido otro. porque los métodos de ordenamiento son completamente IGUALES. Búsqueda Algoritmo que permite encontrar valores dentro de una lista (ordenada) de ellos. Conceptos Ahora que ya hemos revisado como ordenar un arreglo. para que los 4 sean similares. El cómo funciona es bien simple. int iMax) Es decir.3) Capi tulo XIII: Ordenamiento y Bu squeda a[iPiv] = aux. int iMin. int x) { int i = -1. ya que lo hemos utilizado antes. cada uno tiene su firma distintiva. En su defecto. bastaría que hiciera: selectSort(a. Es sencillo. } Java: del Grano a su Mesa (Versio n 1. Veamos como es eso: • • • • void void void void selectSort (int[] a. int iMin. int iMax) bubbleSort (int[] a. iMin es donde empieza el arreglo (0) y iMax es donde termina el arreglo (cantidad de elementos-1).length-1). 0. int iMin. es muy importante aprender como también buscar dentro de un arreglo. 1. se hace crecer k en una posición y se intercambia el elemento k con el elemento j. Veamos cada una: • • • void selectSort (int[] a. int iMax) mergeSort (int[] a. int n): Algoritmo de burbuja donde a es el arreglo y n es la cantidad de elementos. 5. int nEls. Retornamos el pivote. 2. int iMin. Si es menor.

(a) Escriba un método que modifique la burbuja para que ordene de MAYOR A MENOR el arreglo (no importa si es RECURSIVO o ITERATIVO). int iMin. int nEls) { if (nEls == 1) return. No todos los alumnos tienen notas (“notas. else return buscar(a. 115 116 .0 • Los códigos de los alumnos parten desde 001 y terminan en 110 (1 a 110 para ser más claro).3) Capi tulo XIII: Ordenamiento y Bu squeda for (int j = 0. como 6.txt” está ordenado LEXICOGRÁFICAMENTE. x).9. iCentro-1. Problemas Tenemos un archivo “notas” con las notas del control 1 con el siguiente formato: • • • • Código del alumno (3 caracteres) Nota Pregunta 1 (3 caracteres. Búsqueda Binaria Este tipo de búsquedas se basa en el mismo concepto que utiliza MergeSort y QuickSort: El hecho de subdividir el arreglo para optimizar la búsqueda. la búsqueda binaria en muchísimo más rápida que la secuencial. x). iCentro+1. Pero aún existe una forma más óptima de buscar un elemento. • En total son 110 alumnos (“alumnos. } j++. int iMax. así que añadiremos un parámetro adicional en la firma: int buscar (int a[]. j < nEls. Solución Para hacer esto es cosa de cambiar la condición de orden del método: void ordenarArreglo (int arreglo[]. Fíjense en el mejor de los casos (está en la primera posición) igual se recorre TODO el arreglo para encontrarlo.txt”). iMax. } Si lo vemos de una forma práctica. pues es la lista completa. j++) if (a[j] == x) i = j. int nEls. etc) Nota Pregunta 2 (3 caracteres) Nota Pregunta 3 (3 caracteres) Además. iMin. } Java: del Grano a su Mesa (Versio n 1.txt” no está ordenado. • El archivo “notas.3) Capi tulo XIII: Ordenamiento y Bu squeda return buscar(a. • • • Mejor Caso: n iteraciones Peor Caso: n iteraciones Caso Promedio: n iteraciones En este caso se utiliza como pivote el cortar por la mitad el trozo de búsqueda. 5. int buscar (int a[]. int x) { if (iMin > iMax) return ú1.0. 3. while(j < nEls) { if (a[j] == x) { i = j. int j = 0.txt”) y a ellos se les recomienda que le ponga un 1. int iCentro = (imin + imax) / 2. } Este pequeño código busca en forma secuencial un valor x dentro del arreglo a y retorna la posición en la cual se encuentra. Sencillo de ver. Es muy fácil ver que: • • • Mejor Caso: 1 iteración Peor Caso: n/2 iteraciones Caso Promedio: log2n iteraciones Vamos a ver algunas optimizaciones para corregir esto.txt” que contiene los nombres de los alumnos asociados a los códigos. posee un archivo llamado “alumnos. pero es ineficiente. if (a[iCentro] == x) return iCentro. entender y escribir. } return i. es decir: • • Código del alumno (3 caracteres) Nombre del alumno (el resto de la línea) Con este pequeño cambio podemos bajar el tiempo de búsqueda: • • • Mejor Caso: 1 iteración Peor Caso: n iteraciones Caso Promedio: n/2 iteraciones aproximadas Esto mejora un poco nuestro algoritmo. return i. break.Java: del Grano a su Mesa (Versio n 1. int x) { int i = -1. Su solución es recursiva. else if (a[iCentro] > x) Nota: • El archivo “alumnos.1.

txtá). i++) notas[i] = 1. retornando lo que entrega el método de la parte (a).0. pw.print(linea.println(notas[codigo]).3) Capi tulo XIII: Ordenamiento y Bu squeda for (j=0. arreglo[j+1] = auxiliar. double p2 = new Double(linea. Este método internamente crea un objeto Entero (que debe poseer un constructor que reciba un entero y que lo almacena como variable de instancia) y lo compara con otro entero del mismo tipo (crea otro objeto de la clase Entero con b).close(). while ((String linea = bf2. no declaramos nada de nuevo.doubleValue(). } } ordenarArreglo(arreglo. } bf. nEls-1). while ((String linea = bf. 3)). Solución public class Entero extends EsComparable{ protected int n. double p1 = new Double(linea. } bf2.substring(9. 3)).substring(3)).3) Capi tulo XIII: Ordenamiento y Bu squeda Solución Continuando con el programa. // Leemos el archivo BufferedReader bf = new BufferedReader ( new FileReader(”notas.print(” ”). int b). 3)).substring(0. // Inicialmente TODOS tienen un 1. double p3 = new Double(linea. // Escribimos en lista. } Java: del Grano a su Mesa (Versio n 1.close(). 110). Nótese que usted YA debe tener ordenado el arreglo de MAYOR A MENOR con las notas de los alumnos. utilizando el método anterior. j<nEls-2. BufferedReader bf2 = new BufferedReader ( new FileReader(”alumnos. Solución Console c = new Console(). pw.substring(3.parseInt(linea.println(i + ” saco un ” + notas[i]). i<110.txt” en el cual se escriban los siguientes datos: • • • Nombre del Alumno Espacio (1 carácter) Promedio del Control 1 (e) Escribir una clase Entero que implemente EsComparable y que permita realizar el siguiente método estático: public static int comparar (int a.doubleValue(). y que retorna: § § § nº > 0 si el objeto es mayor que b 0 si el objeto es igual a b nº < 0 si el objeto es menor que b Solución public interface EsComparable { public int compararCon(EsComparable b).Java: del Grano a su Mesa (Versio n 1. Debe poseer entonces esta firma: public int compararCon(EsComparable b).readLine()) != null) { int codigo = Integer. pues está todo listo. i<110. } (b) Escriba un programa que permita leer las notas de los alumnos y escriba en pantalla los promedios ordenados de MAYOR A MENOR indicando Código del Alumno y Promedio. // Desplegamos en pantalla ordenadamente for (int i=0.txt pw. // Ordenamos ordenarArreglo(notas. } (c) Siga con el programa para que luego permita crear un nuevo archivo llamado “lista.substring(0. pw. notas[codigo] = (p1 + p2 + p3) / 3. 3)). (d) Escribir una interfaz llamada EsComparable que contenga una firma que permite a cualquier clase heredada compararse con otro de su mismo tipo.close(). 117 118 . arreglo[j] = arreglo[j+1].readLine()) != null) { // Obtenemos el codigo del alumno int codigo = Integer. j++) { if (arreglo[j] < arreglo[j+1]) { int auxiliar = arreglo[j].txtá)). 3)). PrintWriter pw = new PrintWriter ( new FileWriter(”lista.substring(6. // Creamos el arreglo double notas[] = new double[110].0 for (int i=0.parseInt(linea.txtá)).doubleValue(). i++) { c.

3) Capi tulo XIII: Ordenamiento y Bu squeda public Entero(int x) { this. } public int compararCon(EsComparable b) { return this. else return buscar(a. } (g) Escribir la Búsqueda Binaria (igual que el la parte c). return A. iMin. k+1. iMax. int iMax) { // Caso base if (iMin >= iMax) return.comparar(a[j]. int iMax) { int iPiv = iMin. } int aux = a[k]. a[k] = a[iPiv]. while(j <= iMax) { if (Entero. k-1). iMin. iMax). int b) { Entero A = new Entero (a). iMin. Solución int buscar (int a[].n .n = x.(Entero b).Java: del Grano a su Mesa (Versio n 1. int j = k + 1. int iMax. quickSort(arreglo. Entero B = new Entero (b). Problemas Propuestos (a) Desarrolle el método de SELECCIÓN para que en vez de ordenar de MENOR A MAYOR lo haga en forma inversa. es decir de MAYOR A MENOR. // Caso general int k = particionar(arreglo. int iMin. quickSort(arreglo. a[k] = a[j]. int iMin. a[iPiv] = aux.comparar(a[iCentro]. a[iPiv]) < 0) { // Vamos poniendo el pivote en medio k = k+1. } int particionar (int a[].comparaCon(B). x). int aux = a[k].comparar(a[iCentro]. (b) Desarrolle el método de la BURBUJA para que en vez de ordenar llevando el MAYOR dentro de la burbuja. if (Entero. iCentro+1. Solución void quickSort (int arreglo[]. haga el proceso inverso de llevar el MENOR a la primera posición. int k = iMin. x) == 0) return iCentro. x) > 0) return buscar(a. else if (Entero.n. 119 120 . x). } j++. iMax). } } int iCentro = (imin + imax) / 2. a[j] = aux. (f) Escribir el QuickSort en forma genérica para que compare con el método comparar que de la parte (e). int iMin. int x) { if (iMin > iMax) return ú1. return k. } } static public int comparar(int a.3) Capi tulo XIII: Ordenamiento y Bu squeda Java: del Grano a su Mesa (Versio n 1. iCentro-1.

al igual que la consola). Algo bastante feo J. Escritura de un Archivo de Texto Para escribir un archivo de texto en Java. Algo igualmente feo J. en vez de la famosa ventana de la Consola.3) Capi tulo XIV: Archivos de Texto Java: del Grano a su Mesa (Versio n 1. 1. BufferedReader es el tipo de dato que guarda la referencia a una ENTRADA de datos (que también se utiliza tanto para archivos como para teclado en el Java estándar). // se repite mientras hayan datos while (<condicion para terminar el archivo>) { // se obtiene los datos para una lınea <instrucciones> 121 122 . Otra forma de hacerlo es: // se abre el archivo BufferedReader arch = new BufferedReader( new FileReader(”archivo.Java: del Grano a su Mesa (Versio n 1.close(). } // Se cierra el archivo arch. 2. // se repite mientras no este en el final del archivo while (linea != null) { // se procesa la lınea leıda desde el archivo <instrucciones> // se lee siguiente lınea PrintWriter es el tipo de dato que guarda la referencia a una SALIDA de datos (que también se utiliza tanto para archivos como para pantalla en el Java estándar).readLine(). Pero eso no es todo. FileWriter es una clase que permite obtener un ESCRITOR para PrintWriter a un Archivo de Texto. Por lo tanto. Por lo tanto. para escribir un archivo de texto tenemos el siguiente ejemplo: // se abre el archivo PrintWriter arch = new PrintWriter( new FileWriter(”archivo. // se lee la primera lınea del archivo String linea = arch. } // se procesa la lınea leıda desde el archivo <instrucciones> } // Se cierra el archivo arch. 2. existen 2 clases que son muy importantes: 1. sino que existe dos métodos muy utilizado para la escritura y son print(String) y println(String) (si. Los de más fácil acceso son los llamados Archivos de Texto. // se repite mientras no este en el final del archivo while (true) { // se lee siguiente lınea linea = arch. sino que existe un método muy utilizado para la lectura y es readLine() (si. existen 2 clases que son muy importantes: Es así como abrir un archivo de texto para la lectura quedaría de la siguiente forma: BufferedReader <var> = new BufferedReader( new FileReader(”<nombre de archivo>á)).close(). // se verifica que no se este al final del archivo if (linea == null) { break. para leer un archivo de texto de inicio a fin. Es así como abrir un archivo de texto para la escritura quedaría de la siguiente forma: PrintWriter <var> = new PrintWriter( new FileWriter(”<nombre de archivo>á)). FileReader es una clase que permite obtener un LECTOR para BufferedReader desde un Archivo de Texto.txtá)). al igual que la consola).readLine(). Sin embargo la utilización de los archivos es un poco engorrosa y complicada. La idea es poder obtener datos desde un archivo de t exto guardado en el disco duro en vez del teclado y/o escribirlos en otro archivo de texto que también se guarda en disco duro.txtá)).txtá)). Sintaxis Lectura de un Archivo de Texto Para leer un archivo de texto en Java. tenemos el siguiente ejemplo (incompleto por supuesto): // se abre el archivo BufferedReader arch = new BufferedReader( new FileReader(”archivo.3) Capi tulo XIV: Archivos de Texto linea = arch. Capítulo XIV: Archivos de Texto Motivación En Java se pueden utilizar distintos tipos de archivos para lectura y escritura.readLine(). Pero eso no es todo.

while(linea != null) { suma += Double.0 . n++. linea = br.parseDouble(linea).indexOf(”:á). Ejemplo de Archivos Escribir un programa que lea desde el teclado una serie de notas y las escriba en un archivo.readLine().. i). Realice el siguiente diálogo: Inicio de Sesion Nombre de usuario? jperez Clave? jp ERROR: Su clave no corresponde Nombre de usuario? jperez Clave? Jpa INGRESO ACEPTADO 123 124 . // Con nombre y clave comparas los ingresados // por el usuario // .close(). //.3) Capi tulo XIV: Archivos de Texto Además.println(datos). // se escribe la lınea en el archivo arch. // Suponemos que tenemos en linea lo leido int i = linea..txt y tiene la siguiente estructura: amendoza:lskksa jperez:Jpa nromero:nata1. // Ahora verificamos por que salio.readLine(). else { Problema (a) Escribir un programa que simule la conexión de un usuario con nombre y clave. Console c = new Console(”Lector de Notasá).print(”Clave de Acceso?á). String nombre. // Trozo de programa que lee de pantalla y // almacena en archivo c:\notas. double suma = 0.. } // se cierra el archivo arch.readLine(). // Despliega la nota c. String clave.equals(sunombre)) break.substring(0.substring(i+1). debe utilizar este archivo para obtener el promedio del curso completo. String linea = bf. i).readLine(). // Se compara solo el nombre if (nombre.txtá)).println(”ERROR: El usuario no existeá).close(). c. Solución 1 Esta solución utiliza el HINT que se entrega.readDouble(). considere que los nombres de usuario y claves se encuentran en un archivo llamado claves.close(). while (nota != 0) { pw.readLine().println(”Inicio de Sesioná)..readDouble().3) Capi tulo XIV: Archivos de Texto Java: del Grano a su Mesa (Versio n 1.txtá)). c.. } br. nota = c.readLine().indexOf(”:á). Termine con un 0á).. // Iniciamos el ciclo de sesion while (true) { c. // Trozo de programa que lee el archivo de notas BufferedReader br = new BufferedReader( new FileReader(”c:\\notas. // Siguiente usuario linea = bf. Hint: Para separar nombre de usuario y clave de acceso puedes utilizar: // .println(nota). if (linea == null) c. } pw. Luego.println(”El promedio es ” + (suma / n)). // Se abre el archivo de claves BufferedReader bf = new BufferedReader( new FileReader(”claves. c.substring(i+1)..println(”Ingrese las notas de los alumnos. clave = linea.substring(0. String linea = br.txtá)).Java: del Grano a su Mesa (Versio n 1. while (linea != null) { // Se obtiene el nombre y la clave del archivo int i = linea.txt PrintWriter pw = new PrintWriter( new FileWriter(”c:\\notas. int n = 0.close().print(”Nombre de Usuario?á). String sunombre = c. } bf. double nota = c. String nombre = linea. nombre = linea. String clave = linea. String suclave = c. Console c = new Console()..

txt tiene el siguiente texto: 125 126 . El resultado de cambiar “@” por “Juanita” entregaría el siguiente archivo Juanita_micarta. c. no olvides llevar plata. c. // Siguiente usuario linea = bf. Ası que. Ası que.print(”Clave de Acceso?á).txt La dea es que. } } // Como solo sale si la clave es correcta c.. por ejemplo si el archivo micarta.. :) (b) Escriba un programa que reemplace textos en un archivo. String sunombre = c. Siempre tuyo Tu amado PS: @. c. else break..println(”ERROR: La clave es incorrectaá).println(”ERROR: La clave es incorrectaá). String suclave = c. porque no tengo.print(”Nombre de Usuario?á).Java: del Grano a su Mesa (Versio n 1. } bf.txtá)).close(). que simule el siguiente diálogo: Ingrese el nombre del archivo? micarta. } // Como solo sale si la clave es correcta c.println(”Inicio de Sesioná). // Se abre el archivo de claves BufferedReader bf = new BufferedReader( new FileReader(”claves. porque no tengo..3) Capi tulo XIV: Archivos de Texto if (clave. String linea = bf. Siempre tuyo Tu amado PS: Juanita. while (linea != null) { // Se compara la linea completa if (linea. // Ahora verificamos por que salio.equals(sunombre + ”:á + suclave)) break. Java: del Grano a su Mesa (Versio n 1.readLine().equals(suclave)) break.readLine().readLine().. es decir. pero no utiliza el juego con substrings y es algo más corta.println(”INGRESO ACEPTADO!!!!á).. :) Solución 2 Esta otra solución también funciona... // Iniciamos el ciclo de sesion while (true) { c. contestame este mail y te espero. por favor Juanita.readLine().println(”INGRESO ACEPTADO!!!!á). Console c = new Console().3) Capi tulo XIV: Archivos de Texto Mi amada @: A traves de la presente carta he querido invitarte para que manana podamos ir al cine y luego tal vez quien sabe. if (linea == null) c.txt: Mi amada Juanita: A traves de la presente carta he querido invitarte para que manana podamos ir al cine y luego tal vez quien sabe. String clave. String nombre. por favor @.txt Ingrese el patron a reemplazar? @ Ingrese valor a reemplazar? Juanita El resultado quedo en Juanita_micarta. no olvides llevar plata. contestame este mail y te espero.

Con esto nos aseguramos que nuestra clase Java pueda crear ventana gráficas y escribir en ellas (como lo hacemos en la Console) o dibujar sobre ellas. La idea es que el contructor de la clase sea el constructor de la interfaz y que permita que se refleje en pantalla.*. imágenes. listas de valores y cualquier tipo de elemento gráfico (de Java) que se puede insertar dentro de una interfaz.*. es decir.. Las interfaces gráficas son programas son componentes que nos permiten trabajar directamente con gráficos como botones. 11 127 128 . etc. lo que hacemos realmente es crear una clase que almacenará nuestra interfaz dentro de si las componentes y todo. usuario del programa con el computador. import java. Para ejecutar esta interfaz gráfica es importante recalcar que se debe crear una clase que cree nuestra interfaz personalizada (al igual que la console): public class MiPrograma { static public void main (String args[]) { MiInterfazGrafica ig = new MiInterfazGrafica(). Conceptos Interfaz Gráfica Programa (en Java) que permite una interacción con el usuario a través de una ventana con botones y otras componentes haciendo más amigable la interacción con el Usuario.event.. textos. áreas de texto. áreas de dibujo. Es por eso que todos los programas Java que utilizan interfaces gráficas empiezan con la importación de: import java. } } Hasta ahora. Nuestro foco ha estado todo este tiempo en lo que son los programas y solo hemos hecho interacciones sencillas con el usuario utilizando una herramienta llamada “Console”.3) Capi tulo XV: Interfaces Gra ficas Capítulo XV: Interfaces Gráficas AWT Motivación Pantalla Programa Sintaxis Para la utilización de interfaces gráficas es obligatorio utilizar unos paquetes de clases que se encuentran en la API del JDK (Java Delevopment Kit). gráficas.applet. public class MiInterfazGrafica { .awt. Estos elementos son sensibles a “ocurrencias” de la interfaz llamadas “eventos”. Los componentes pueden ser botones. Pero ¿Qué es Console? ¿Cómo funciona? ¿Podemos hacer otro tipo de ventana s más bonitas? Es hora de llevar nuestra atención a realizar interfaces distintas a Console. import java.*. Se refiere solo a la interacción humano-computador. todos los programas interactúan con el usuario tal como lo dice la figura11: Mostrar datos en pantalla y pedir datos por el teclado.3) Capi tulo XV: Interfaces Gra ficas Java: del Grano a su Mesa (Versio n 1.... Conceptos Componente Elemento u objeto (en Java) que se utiliza para construir una interfaz gráfica. Como se ve en el ejemplo.Java: del Grano a su Mesa (Versio n 1. pero que no involucran al usuario directamente. y que puedan sernos de mucha utilidad. } Usuario Teclado } . Existen más interacciones como por ejemplo con Archivos y Bases de Datos. public MiInterfazGrafica() { // Creamos la ventana y las componentes .awt..

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XV: Interfaces Gra ficas

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XV: Interfaces Gra ficas Método Frame(String) void setSize(int, int) void setResizable(boolean) void setLayout(Layout) void add(Component) Descripción Constructor que crea una ventana de tamaño 0x0 y con el título definido por el parámetro. Dimensiona el frame para que tenga un tamaño (x, y) en pixeles reflejados en los 2 parámetros del método. Hace que el frame quede sin permiso para redimensionar el tamaño con el mouse. Le indica la grilla que va a utilizar el frame para contener los componentes. Estas grillas serán descritas más adelante. Pone la componente dentro del frame en la primera posición libre del mismo (dependiendo de la grilla). Pone la componente dentro del frame y en la posición de la grilla indicada en el parámetro String. Agrega un listener para ejecutar una acción cuando ocurre el evento X. X va variando dependiendo del listener (lo veremos más adelante). Prepara el despliegue del frame en pantalla. Muestra el frame en pantalla.

Sintaxis
Existen muchos componentes para las interfaces gráficas :
12

Frame
Un frame es un área que nos permitirá dentro de ella crear la interfaz gráfica. Practicamente es la ventana que se abre al ejecutar nuestra clase:

Aquí va el título de nuestra Interfaz Gráfica

void add(String, Component) void addXListener(XListener)

void pack() void show()

Layout
Aquí va el contenido de nuestra Interfaz Gráfica Las grillas o Layout son utilizados dentro de los frames para darle “espacios disponibles” para poner un Componente. Para que un frame pueda contener “componenter” es necesario definir cuántos puede contener y luego empezar a generarlos. Existen distintos tipos de grilla (LayoutManager es la clase que define una grilla) y las v eremos con dibujos a continuación: GridLayout:
import import import public java.applet.*; java.awt.*; java.awt.event.*; class MiInterfazGrafica { private Frame ventana; public MiInterfazGrafica() { ventana = new Frame("Mi Interfaz Grafica"); ventana.pack(); ventana.show(); }

Esta ventana es producida por el siguiente código:

Este layout corresponde a una distribución cuadriculada (tipo planilla excel) y que ocupan el mismo tamaño todos los cuadritos.

}

Entonces, podemos ver que la componente Frame posee varios métodos que aquí se describen 13: Método Frame() Descripción Constructor sin parámetros que crea una ventana de tamaño 0x0 (sin área de contenido) y sin título definido.

Por ejemplo, esta grilla tiene 6 posiciones. Para crear un Frame con esa distribución, se debe escribir:
... f. setLayout(new GridLayout(3,2)); ...

12 13

Mayor información en la API del JDK: http://java.sun.com/j2se/1.3/docs/api/index.html Los parámetros se encuentran en el mismo orden de aparición que en la descripción.

donde f es el frame que quiero darle esa grilla. Una vez que se setea, se van poniendo en orden las componentes con cada void add(Component) que se va

129

130

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XV: Interfaces Gra ficas realizando en el constructor de la IG. FlowLayout: Este layout permite en general poner un arreglo de componentes uno al lado del otro pero con tamaño variable de cada uno, como si se estuviera poniendo una cajita al lado de otra.

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XV: Interfaces Gra ficas Existen otros Layouts más complejos, pero con una composición de estos 3 se puede crear lo que uno desee.

Panel
Los paneles son componentes “contenedoras” que nos permiten crear sub -interfaces dentro de nuestros Frames. El uso de paneles es una forma muy útil, ya que para componer o mezclar distintos Layouts de pantalla, utilizamos paneles. También, dentro del panel podemos trabajar como si fuese un frame, es decir, agregamos componentes a libre elección según el layout seleccionado. La definición de un panel se hace a través de objetos de la clase Panel14: Método Panel() void setLayout(Layout) void add(Component) void add(String, Component) Descripción Constructor del panel. Le indica la grilla que va a utilizar el panel para contener los componentes. Pone la componente dentro del panel en la primera posición libre del mismo (dependiendo de la grilla). Pone la componente dentro del panel y en la posición de la grilla indicada en el parámetro String.

Por ejemplo, este arreglo de botones se puede utilizar dentro de una IG y se declara de la forma:
... f.setLayout(new FlowLayout()); ...

donde f es el frame que se quiere usar. Una vez que se setea, se van poniendo en orden las componentes con cada void add(Component) que se va realizando en el constructor de la IG. BorderLayout: Este layout es el más elaborado y utiliza una distribución de puntos cardinales para las componentes que se van insertando.

Un ejemplo de uso sería el siguiente programa:
public class MiInterfazGrafica { // Frame private Frame ventana; // Paneles private Panel p; public MiInterfazGrafica() { ventana = new Frame("Mi Interfaz Grafica"); ventana.setLayout(new GridLayout(4, 4)); p = new Panel(); p.setLayout(new BorderLayout());

Para crear una grilla como esta se debe hacer:
... f.setLayout(new BorderLayout()); ...

...

// Creacion de la interfaz

ventana.add(p); ventana.pack(); ventana.show(); } }

donde f es el frame al cual se le asigna esa grilla. Una vez que se setea la grilla, las componentes deben ser asignadas según dónde van con add(pos, Componente). La posición es un String que corresponde al área deseada “North”, “South”, etc.

Como podemos ver en el ejemplo, estamos creando un frame de distribución cuadrada de 4x4 y con un panel en la primera casilla con distribución de BorderLayout.

14

Panel posee más métodos, pero para efectos académicos no nos serán útiles.

131

132

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XV: Interfaces Gra ficas

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XV: Interfaces Gra ficas
p2 = new Panel(); p2.setLayout(new GridLayout(8, 1)); ventana.add("West", p2); p3 = new Panel(); p3.setLayout(new FlowLayout()); ventana.add("South", p3); ventana.pack(); ventana.show(); } }

Importante: Recuerda que para crear interfaces más complejas, la idea es siempre ir componiendo a través de paneles para llegar a los Layouts básicos. Imaginemos que queremos la siguiente distribución:

Ahora veamos otras componentes para que vayamos creando nuestras interfaces:

Label
Las áreas de texto o etiquetas son súmamente útil en todas las interfaces, ya que pueden servirnos de informativos o más bien de títulos para algunas cosas. La clase Label posee los siguientes (reducidos) métodos: Método Label(String) Label(String, int) Descripción Constructor del label que pone el texto en su contenido. Constructor del label que pone el texto en su contenido y lo alínea según el segundo parámetro. El alineamiento que va como parámetro es identificado como: § Label.CENTER § Label.LEFT § Label.RIGHT Retorna el texto que posee el label. Cambia el texto original por otro que va como parámetro. Alinea el texto dentro del label. El alineamiento que va como parámetro es identificado como: § Label.CENTER § Label.LEFT § Label.RIGHT Ejemplo:
// Crear un label con un texto fijo Label titulo = new Label(”Este es un tıtuloá); // Cambiar el texto del label titulo.setText(”Cambio de tıtuloá); // Alinea a la derecha el label titulo.setAlignment(Label.RIGHT); // Crea un nuevo label, centrado, con el texto del otro Label tit2 = new Label(titulo.getText(), Label.CENTER);

Podemos distinguir claramente varios paneles dentro de este frame 15: § § § § § El Layout del frame es BorderLayout (marcado más grueso) En el centro hay un Panel con GridLayout de 3 x 3. En la izquierda hay un Panel con GridLayout de 8 x 1. Abajo puede ser un Panel con GridLayout de 1 x 2 o FlowLayout. A la derecha y arriba no es necesario un Panel. String getText() void setText(String) void setAlignment(int)

y eso quedaría escrito cómo:
public class MiInterfazGrafica { private Frame ventana; private Panel p1, p2, p3; public MiInterfazGrafica() { ventana = new Frame("Mi Interfaz Grafica"); ventana.setLayout(new BorderLayout()); p1 = new Panel(); p1.setLayout(new GridLayout(3, 3)); ventana.add("Center", p1);

Todas estas líneas son imaginarias, ya que la distribución se ve reflejad a en las componentes que cada panel contiene realmente.

15

133

134

Constructor que da a un botón un texto como etiqueta. // Desactivamos el boton b. int) TextArea(String) TextArea(String. int. int) void setColumns(int) void setText(String) String getText() void setEditable(boolean) boolean isEditable() Ejemplo: // Crea un textfield de 20 caracteres de largo TextField tf = new TextField(20). Fija el largo del textfield. int. Activa (TRUE) o desactiva (FALSE) el botón. a diferencia de los textfield. Constructor de un textfield con un texto definido. // Escribe en el textfield un texto tf.3) Capi tulo XV: Interfaces Gra ficas Método Button() Button(String) void setLabel(String) void setEnable(boolean) boolean isEnabled() Descripción Constructor de un botón vacío.setEnable(false).SCROLLBARS_BOTH La clase Button posee los siguientes métodos: 135 136 . Constructor de un textarea con un text. Configura para que el textfield sea editable (TRUE) o solo de lectura (FALSE). Retorna si el botón está activado (TRUE) o desactivado (FALSE). int) Descripción Constructor de un textarea vacío. Asigna a un botón una etiqueta específica. Button Las componentes buttons son sencillos botones de acción que se utilizan en las interfaces gráficas como gatilladores de eventos específicos (ver sección de eventos más adelante). Constructor de un textfield de largo definido. Retorna el texto del textfield. int. Constructor de un textarea de largo definido como filas x columnas.3) Capi tulo XV: Interfaces Gra ficas Java: del Grano a su Mesa (Versio n 1. Constructor de un textfield con un text y largo definido. // Creamos un boton con texto Button b = new Button (”Aceptará). Por ejemplo: La clase TextField posee los siguientes (reducidos) métodos: Método TextField() TextField(int) TextField(String) TextField(String.setEditable(false). Pone el texto como contenido del textfield. Descripción Constructor de un textfield vacío.setText(”Este texto es fijoá). largo definido con filas x columnas y los scrollbars: § TextArea. Constructor de un textarea con un text y largo definido con filas x columnas. Retorna si el textfield es editable (TR UE) o no (FALSE). // Lo pone como solo de lectura tf.Java: del Grano a su Mesa (Versio n 1. TextArea Los textarea son áreas de texto en donde se pueden escribir mú ltiples líneas. TextField Son campos de ingreso de datos de una sola línea. Constructor de un textarea con un texto definido. int) TextArea(String. La clase TextArea posee los siguientes métodos: Método TextArea() TextArea(int.

for (int i=0. Retorna el valor del elemento seleccionado. aparece la lista completa de valores del choice. (Modo de selección simple) Entrega el índice del elemento seleccionado. Choice El choice es un elemento de selección que puede ser tomado desde una lista más grande de datos. Retorna el número de elementos que tiene el choice. si queremos una lista con muchas opciones: List l = new List(10. boolean) Descripción Constructor de una lista vacía con un número de líneas visibles igual a 4 con selección única. i<100. Java: del Grano a su Mesa (Versio n 1. para general la ventana que aparece como ejemplo. La clase List del awt posee la siguiente definición: Método List() List(int) List(int. Por ejemplo. Retorna el elemento de la posición indicada. List Las listas son uno de los elementos más útiles después de los botones y las áreas de texto. false). Una vez que uno presiona la flecha del costado derecho. i<2100. Retorna el índice del elemento seleccionado. Constructor de una lista con un número de líneas visibles definido y selección única.SCROLLBARS_NONE Fija la cantidad de columnas del textarea.3) Capi tulo XV: Interfaces Gra ficas for (int i=2000. 137 138 .SCROLLBARS_HORIZONTAL_ONLY § TextArea. (Modo de selección múltiple) Entrega un arreglo con todos los índices seleccionados. Descripción Constructor de un choice vacío. } void setColumns(int) void setRows(int) void setText(String) String getText() void setEditable(boolean) boolean isEditable() Esta lista entregaría todos los años entre el 2000 y el 2099. int) void select(int) boolean isIndexSelected(int) int getItemCount() int getSelectedIndex() int[] getSelectedIndexes() Por ejemplo. i++) { l. Selecciona el elemento de la posición indicada. Indica si una posición está (TRUE) o no (FALSE) seleccionada. Agrega una nueva opción en la posición indicada. void add(String) void add(String. int) int getItemCount() int getSelectedIndex() String getSelectedItem() String getItem(int) void select(int) void select(String) Por ejemplo Choice c = new Choice(). 30). i++) { c. Configura para que el textarea sea editable (TRUE) o solo de lectura (FALSE). Agrega un nuevo elemento al choice (al final).Java: del Grano a su Mesa (Versio n 1. Retorna si el textarea es editable (TRUE) o no (FALSE).add(”Opcion ” + i). Retorna el texto del textarea. Agrega una nueva opción al final de la lista.add(”Ano ” + i). Fija la cantidad de filas del textarea.3) Capi tulo XV: Interfaces Gra ficas Método Descripción § TextArea. Constructor de una lista con un número de líneas visibles definido y con opción de selección única (FALSE) o múltiple (TRUE). Selecciona el elemento indicado. La clase Choice se define como: Método Choice() void add(String) void insert(String. es necesario crear el textarea de la siguiente forma: Textarea area = new TextArea(10.SCROLLBARS_VERTICAL_ONLY § TextArea. } Esta lista entregaría 100 opciones con selección simple. Retorna la cantidad de elementos de la lista. Inserta un nuevo elemento al choice en la posición indicada. Pone el texto como contenido del textarea. Selecciona el elemento de la posición indicada.

import java. polígonos) y se puede atrapar eventos sobre él. // Aca van solo las componentes que son utiles // para el programa private Choice jugadas[][]. Por ejemplo. false). 139 140 .3) Capi tulo XV: Interfaces Gra ficas Pero si queremos sabes por ejemplo los grupos de interés de un usuario. private Button salir. Crea una opción con un texto definido.*. Método Canvas() void paint(Graphics) Descripción Constructor que crea un canvas. Asigna al grupo la opción. CheckboxGroup. canvas lo dejaremos para más adelante.. Checkbox sexoM = new Checkbox(”Masculinoá. es resuelta por el siguiente programa: import java. Por ser un tema especial. las opciones quedan con la posibilidad de marcar SOLO 1 de ellas. null. si queremos un selector de sexo de una persona (si es Masculino o Femenino) hacemos: CheckboxGroup sexo = new ChekboxGroup(). esta opción debe ser “null”. boolean. es dependiendo si se puede o no marcar múltiples opciones. Checkbox y CheckboxGroup Los checkboxes son opciones que permiten marcar un texto específico y que le permiten al programador interactuar con opciones (alternativas).3) Capi tulo XV: Interfaces Gra ficas Java: del Grano a su Mesa (Versio n 1. Permite re-dibujar en el canvas lo que esté almacenado en él. null.awt. Crea una opción con un texto.*.awt. sexo.*. Ejemplos de Componentes Un primer ejemplo de utilización de componentes es el juego del gato (solo interfaz): void setLabel(String) boolean getState() void setCheckboxGroup(CheckboxGroup) CheckboxGroup getCheckboxGroup() Esta interfaz sencillita. Al asignarlas al mismo grupo. boolean) Descripción Crea una opción vacía. indicando si está o no marcada y además agrupada según un grupo de opciones. sexo. Crea una opción con un texto y le indica si está o no marcada. import java. Retorna si la opción si está seleccionada (TRUE) o no (FALSE). . Checkbox sexoF = new Checkbox(”Femeninoá. Checkbox gr02 = new Checkbox(”Musicaá. false). Dependiendo si se usan la opción de grupo checkboxgroup. Obtiene el grupo al que pertenece la opción. false). public class Gato { private Frame ventana. La clase Canvas está definida como: La clase Checkbox identifica solo una opción de selección con estos dispositivos y posee la siguiente definición: Método Checkbox() Checkbox(String) Checkbox(String. null.. Pone el texto a la etiqueta que acompaña al selector. podemos hacer un grupo de selección diferenciada: Checkbox gr01 = new Checkbox(”Deportesá. y su forma cambia a la de selector redondo en vez del cuadrado (como se ve en la figura). Canvas Un canvas es un rectángulo blanco dentro de la interfaz en donde se puede dibujar cualquier cosa (texto.applet. Checkbox gr03 = new Checkbox(”Televisioná. CheckboxGroup) o bien Checkbox(String. Si no se desea ningún grupo.event. boolean) Checkbox(String.Java: del Grano a su Mesa (Versio n 1. líneas. false). true).

jugadas[i][j]. 3)). i<3. int) void setSize(Dimension) Dimension getSize() void setLocation(int.add(titulo).3/docs/api/java/awt/Component. La clase Component posee las siguientes funcionalidades útiles 16: Método void setVisible(boolean) boolean isVisible() void setSize(int.add(gato).add("X").add("O").com/j2se/1. j++) { jugadas[i][j] = new Choice().html 141 142 . public MiInterfazGrafica() { ventana = new Frame("Jalisco").show(). ventana. TextField TextArea Que se resuelve con el siguiente código: public class Jalisco { private Frame ventana. ventana.Java: del Grano a su Mesa (Versio n 1. } } ventana. 1)).pack(). Le da un tamaño dado por un objeto a un tipo Dimension.3) Capi tulo XV: Interfaces Gra ficas ok = new Button("Ok"). Obtiene la posición de la componente en un objeto Point. ventana. // Y el boton de salida del juego salir = new Button("Terminar"). Le da un tamaño dado por largo x ancho para la componente. ventana. // Dibujamos el tablero para jugar gato Panel gato = new Panel().add(jugadas[i][j]). // Le ponemos el tıtulo a nuestro ejemplo Label titulo = new Label("Gato". y). jugadas[i][j].setLayout(new GridLayout(3. ventana. gato. private Button ok.pack(). Label. i++) { for (int j=0. for(int i=0. Component Canvas Label Checkbox TextComponent List Button Choice Y por supuesto.add(new Label("Ingresa un numero? ")).add(salir). Obtiene en un objeto Dimension el tamaño de la componente.add(numero).setLayout(new GridLayout(3. ventana. nuestro amigo y hermano ejemplo: El programa Jalisco. jugadas[i][j]. ventana. numero = new TextField(4). 16 Todos estos métodos son solo un extracto de los que realmente tiene la clase Component. int) void setLocation(Point) Point getLocation() Descripción Hace aparecer (TRUE) o desaparecer (FALSE) la componente.CENTER). // Esto nos puede evitar tener una variable para el // texto que no nos sirve mas. Es por eso que todas ellas tienen una superclase llamada Component y que posee algunas propiedades y funcionalidades especiales que afectan a todas. } } Java: del Grano a su Mesa (Versio n 1. Pone la componente en la posición (x. ventana. ventana. j<3.3) Capi tulo XV: Interfaces Gra ficas public MiInterfazGrafica() { ventana = new Frame("Juego del Gato").setLayout(new FlowLayout()).sun. Verifica si la componente está (TRUE) o no (FALSE) visible. gato. Choice jugadas[][] = new Choice[3][3]. ventana.show(). Para mayor información se recomienda consultar la documentación de la API de JDK 1. } } Propiedades heredadas de Component Todas las componentes están definidas como clases dentro de la estructura de la API. private TextField numero.add(ok). ventana.add(" ").3 en: http://java. Pone la componente en la posición dada por el objeto Point.

Hasta ahora habíamos visto esa interacción como un ingreso por teclado de datos por parte del usuario.ITALIC.. etc.black). Font.addActionListener(new MiActionListener).. El funcionamiento de las interfaces gráficas no es automático como lo hace cualquier programa. Para capturar estos eventos. Para darle un font. ..setFont(new Font(“Arial”. los listeners son asignados a objetos o componentes de una IG y le permiten darse cuenta cuándo les están enviando un evento a ellos.. le decimos a la IG que. Para utilizar el color.3) Capi tulo XV: Interfaces Gra ficas Listener Elemento que le permite a un componente detectar cuándo ocurre un evento sobre él e indicar qué debe hacer en la interfaz. Al momento de decirle al componente: “escucha el evento”. Obtiene el estilo que tiene el componente. public class MiInterfazGrafica { . al ocurrir un evento de acción sobre la componente (activar el botón en este caso) que capture ese evento y ejecute el “Listener de Acción Personalizado”..setBackground(Color. Redibuja toda la componente.. .. } . Le da color al fondo (Back) o al font (Fore) de la componente. public MiInterfazGrafica() { .. Este listener debe ser declarado dentro de la IG como una nueva clase (¡si! una clase dentro de otra) que implemente un ActionListener.. se le dice también que cuando ocurra realice ciertas acciones. Java: del Grano a su Mesa (Versio n 1. se usa la clase Color: x. de esta forma.. Obtiene el color que está definido para la componente en el fondo (Back) o en el font (Fore). } . 12)). En las IG (Interfaces Gráficas) existen otras formas de ingreso de datos que corresponden a dispositivos comunes como son el teclado y el mouse. o también se puede obtener gracias a la representación de colores en codificación RGB (cantidad de Rojo.3) Capi tulo XV: Interfaces Gra ficas Método void setFont(Font) Descripción A la componente le da un estilo de letra. pues debe haber alguna interacción con el usuario en algún momento. t = new TextField(20). es necesario utilizar un listener del tipo ActionListener: . Font getFont() void setBackground(Color) y también void setForeground(Color) Sintaxis En las interfaces gráficas para Java existen distintos tipos de eventos... Algunos de estos eventos son: Color getBackground() y también Colo getForegrount() void repaint() Eventos de Acción (ActionEvent) Cualquier acción que es gatillada por una componente se le llama evento de acción. acciones sobre archivos. class MiActionListener implements ActionListener { . Conceptos Evento Acción que ocurre dentro en una componente y que es utilizada para gatillar acciones sobre la interfaz (al presionar un botón. Estos eventos son representados por la clase ActionEvent y es ella la que se encarga de almacenar a qué componente corresponde el evento.. Button b = new Button(”Activaá).. b.. 100. Por ejemplo: .. uno puede utilizar el constructor de la clase Font: x. Al hacer click en el botón “Ok” se está gatillando un evento de acción en la IG. que son capturados por los listener. } Al escribir un texto en la casilla se está gatillando un evento dentro de la IG. al escribir un texto o al hacer click en un área específica).. Esas acciones pueden ser cambios en la interfaz.addActionListener(new <Listener de Accion Personalizado>). t.getColor()).Java: del Grano a su Mesa (Versio n 1. bases de datos. 143 144 .setForeground((new Color(100. 100)). Esos ingresos o esa interacción se hace a través de los eventos.. Tal como dice la definición. Verde y Azúl): x.

} } // Fin del ActionListener } // Fin de la IG Este ejemplo produce esta ventana: 27 suponiendo la situación de que el usuario ingrese 27 como número de entrada.awt.setText((n+1) + " te gane!!!").CENTER)). Cada vez que el usuario presione ENTER en la casilla de texto dejada para que ingrese su número. private TextField numero. ya que por estar dentro de la misma clase pueden acceder a todos los elementos de ella sin necesitar de un objeto.parseInt(numero.. en el ActionListener definido para ese botón se debe usar System.*. // Mostramos la IG programa. import java. le estaríamos indicando a nuestra IG que el listener que queremos utilizar se llama MiActionListener. ya que la única diferencia con lo que ya habíamos visto es la línea en la cual le indicamos el ActionListener a la IG. el ActionListener lo ponemos en el TextField (ingreso de datos) para que se active SOLO SI el usuario presiona ENTER dentro de esa casilla (simulando que ingresa número y presiona ENTER). import java. 145 146 . // Ponemos el cuadro de ingreso del usuario numero = new TextField(4).getText()).add(respuesta). programa.show().add(new Label("Ingresa un numero? ". Label.. 1)). salir de la componente. es decir: // Toma el numero de la casilla de texto (numero) y lo transforma // a un entero dejandolo en la variable n int n = Integer.setText("").addActionListener(new UnEscuchador()).CENTER). etc. class Jalisco { // Aca esta nuestra IG fısicamente referenciada private Frame programa.Java: del Grano a su Mesa (Versio n 1. Todas las clases que implementen un ActionListener DEBEN tener esta estructura fija: class <nombre> implements ActionListener { public void actionPerformed(ActionEvent e) { // Aquı van las acciones que se ejecutan cuando ocurre // un ActionEvent } } Las acciones que se ejecutan pueden utilizar elementos de la IG libremente.setLayout(new GridLayout(3. Nota: Para que un applet se cierre al presionar un botón.pack(). presionar el botón.applet.. programa. Veamos el típico ejemplo del programa Jalisco con eventos: import java.3) Capi tulo XV: Interfaces Gra ficas Hasta aquí vamos bien.parseInt(numero. Para capturar los MouseEvents es necesario utilizar un escuchador del tipo MouseListener (caso obvio después de ver los ActionListeners) o uno del tipo MouseMotionListener.. moverse.setText((n+1) + " te gane!!!").add(numero). // Ponemos el area en donde el computador da // su respuesta respuesta = new Label("". numero. // Escribe en el area de respuesta el numero que ingreso el usuario // (n) incrementado en 1 (n+1) y el texto ”te gane!!!á respuesta.awt. programa. public Jalisco() { // Creamos nuestra nueva ventana programa = new Frame("Jalisco").setText(""). // Estos son los componentes que van a actuar cuando ocurre el // ActionEvent respectivo private Label respuesta. respuesta. // Borra el contenido de la casilla de texto. Este es solo el nombre y podrías haber utilizado el que te guste más. class UnEscuchador implements ActionListener { public void actionPerformed(ActionEvent e) { int n = Integer. numero. soltar el botón.event. // Ponemos el texto antes del campo de datos programa. En esta oportunidad. } . private Button salir. Eventos del Mouse (MouseEvent) Los eventos del mouse son eventos que pueden ocurri r sobre una componente cuando con el mouse uno realiza algo: ingresar a la componente. Así de simple funciona.getText()) y lo pondrá como valor de entrada en la casilla de respuestas sumado en 1.getText()). numero. Label. programa.*. el computador tomará ese número (con el comando numero. .exit(0). Así.*.3) Capi tulo XV: Interfaces Gra ficas Java: del Grano a su Mesa (Versio n 1.

i<3.addMouseListener( new JuegaGato()).applet.show(). gato = new TextField[3][3]. 3)). j++) { gato[i][j] = new TextField(1).add("North".CENTER). j<3. mensaje = new Label("Jugador 1". // Esta listo el juego ventana. } } ventana...pack(). .awt.. .*.CENTER)).. Veamos un ejemplo sencillo.awt. Label.event.setLayout(new GridLayout(3.3) Capi tulo XV: Interfaces Gra ficas import java. ventana. Juguemos al Gato entre 2 personas: import java. new Label("Juego del Gato". // El GATO private TextField[][] gato. // Creamos el arreglo para el gato y // el panel que lo contiene Panel pgato = new Panel(). Label.. for (int i=0.*. public Gato() { ventana = new Frame("Gato").3) Capi tulo XV: Interfaces Gra ficas Java: del Grano a su Mesa (Versio n 1. // Para despliegue de mensajes de sistema private Label mensaje. porque los eventos posibles por el mouse son más que uno solo. pgato).add("Center"..setLayout(new BorderLayout()).add(gato[i][j]). ventana. import java. A diferencia de los ActionListeners.add("South".addMouseListener(new <Listener de Raton Personalizado>). pgato.Java: del Grano a su Mesa (Versio n 1. 147 148 . i++) { for (int j=0. b. public class Gato { // IG private Frame ventana. Pero ¿qué pasa si solo quiero hacer algo cuando el usuario hace CLICK en el mouse? Pues simplemente debes dejar los otros métodos en blanco y escribir solo en el método que corresponde al evento de CLICK del mouse: class UnEventoClick implements MouseListener { public void mouseClicked(MouseEvent e) { // ACA SE ESCRIBE CODIGO } public public public public } void void void void mouseEntered(MouseEvent e) { } mouseExited(MouseEvent e) { } mousePressed(MouseEvent e) { } mouseReleased(MouseEvent e) { } Hasta aquí tenemos la interfaz definida para quedar de la siguiente forma: y así funciona. Es por eso que la estructura de los MousListeners cambia: class <nombre> implements MouseListener { public void mouseClicked(MouseEvent e) { // Se ejecuta solo cuando se hace un click del mouse } public void mouseEntered(MouseEvent e) { // Se ejecuta solo cuando el mouse ingresa a una // componente (el puntero ingresa al area de la // componente) } public void mouseExited(MouseEvent e) { // Se ejecuta solo cuando el mouse abandona a una // componente (el puntero abandona del area de la // componente) } public void mousePressed(MouseEvent e) { // Se ejecuta solo cuando el boton del mouse es // presionado y se mantiene ası (no es un click rapido) } public void mouseReleased(MouseEvent e) { // Se ejecuta solo cuando el boton del mouse es // soltado despues de ser presionado (caso anterior) } } Como pueden ver la cantidad de cosas que hay que implementar es más grande. ventana.*. // Quien juega private boolean jugador1. pgato. Canvas c = new Canvas(). jugador1 = true. } . ventana. los MouseListeners tienen una estructura más compleja. mensaje). // A cada casilla le ponemos un // mouselistener gato[i][j].

posee otras características (métodos) que pueden ser de gran importancia: Método int getClickCount() int getX() y int getY() Descripción Retorna el número de clicks que se realizaron...... los listeners de este tipo poseen un método que DEBE ser implementado para poder capturar los ItemEvents: class <nombre> implements ItemListener { public void itemStateChanged(ItemEvent e) { // Aquı van las acciones que se ejecutan cuando ocurre // un ItemEvent } } ya que le estamos diciendo implícitamente “ si el evento fue gatillado sobre la componente gato[i][j].. e. jugador1 = true. solo implementamos el método mouseClicked(MouseEvent e) para solucionar el tema de marcar el gato.addItemListener(new <Listener de Seleccion Personalizado>). pero eso es poco óptimo. List c = new List(10).Java: del Grano a su Mesa (Versio n 1. if (e. } else { gato[i][j]..getSource() : Retorna una referencia a la componente a la cual se le accionó el evento. 149 150 . Al igual que los MouseEvents. } } } } } public public public public } } void void void void mouseEntered(MouseEvent e) { } mouseExited(MouseEvent e) { } mousePressed(MouseEvent e) { } mouseReleased(MouseEvent e) { } Java: del Grano a su Mesa (Versio n 1. Si pensamos un poco. i++) { for (int j=0. cualquiera sea. jugador1 = false.”. ItemEvent. mensaje. es decir..setText("Jugador 1"). } .setText("X"). se selecciona un item o se activa o desactiva una opción. j++) { if (e... Este método sirve no solo para los MouseEvents. si no que para cualquier evento (ActionEvent.3) Capi tulo XV: Interfaces Gra ficas El otro tipo de listener para el mouse es el MouseMotionListener quien se preocupa de los movimientos libres que el mouse puede realizar: class <nombre> implements MouseMotionListener { public void mouseDragged(MouseEvent e) { // Se ejecuta solo cuando se presiona el boton en una // componente y luego se arrastra. sin embargo. relativo a la componente asignada. } public void mouseMoved(MouseEvent e) { // Se ejecuta solo cuando el mouse se muerve dentro // del area de una componente..setText("Jugador 2"). Como podemos ver. . cuando el usuario haga click sobre los campos en blanco se ponga una “X” o una “O” dependiendo si es el jugador 1 o 2 respectivamente: . Todo esto resulta útil cuando estamos tratando de dibujar en un Canvas. class JuegaGato implements MouseListener { public void mouseClicked(MouseEvent e) { // Buscamos casilla seleccionada for (int i=0.. mensaje. List o Choice) cambia su estado. Así evitamos hacer los demás métodos. son 9 casillas distintas que gatillan el mismo evento. además de identificar la componente seleccionada.).3) Capi tulo XV: Interfaces Gra ficas Ahora manipulemos que. Retorna el valor de la posición horizontal (X) y vertical (Y) donde ocurrió el evento. b. i<3. Eventos de Selección (ItemEvent) Los eventos de selección son eventos que ocurren cuando en una componente de selección (Checkbox. Así que diferenciamos dentro de los listeners a cuál componente corresponde con el método getSource() del evento. etc.. Es por eso que podemos compararlo con la componente en forma directa como . estos métodos se pueden utilizar dentro del MouseListener sin problemas (si fuera necesario). Nota: Utilizamos algo nuevo para identificar qué componente se está haciendo click.getSource() == gato[i][j]) { if (jugador1) { gato[i][j]. .getSource() == gato[i][j]) { . } } Para estos últimos eventos es muy importante destacar que la variable e. Para capturar los ItemEvents es necesario utilizar un escuchador del tipo ItemListener.. Podríamos hacer 9 eventos distintos.setText("O"). j<3.

programa.applet. todas las figuras que se realicen quedan con ese color definidas.*. int) fillOval(int. y).pack(). } Una vez que se setea el color. int. En el Canvas. Dibuja el contorno de una elipse en la posición centro (x. int.Java: del Grano a su Mesa (Versio n 1. y) con un tamaño horizontal y vertical definido. Pone un estilo de letra especifico a los elementos de texto que se escriban en adelante. import java. } . Dibuja un rectángulo relleno con vértice superior izquierdo (x. De hecho.yellow = Amarillo etc de Ventana WindowListener Sin dejar de considerar que toda la información que se ha desplegado es simplemente referencial y no necesariamente está completa. public class Paint { private Frame programa. Los colores se definen como constantes en la clase Color: § § § § § § § Color. programa. Escribe el texto en la posición (x. 600). area.sun.add(area). indicando eso si el tamaño de él: import java. int. pues cambia cuando tenemos que dibujar sobre el Canvas algun elemento. import java. al igual que en otras componentes. Canvas Ahora veamos como se utiliza la componente Canvas en las interfaces gráficas.. Dibuja el contorno de un rectángulo con vértice superior izquierdo (x. Graphics a diferencia de las componentes de las IG es una clase que controla el contenido de un Canvas y no tiene nada que ver con su layout o eventos que ocurran porque no es un espacio físico en pantalla.3) Capi tulo XV: Interfaces Gra ficas Como se ve en el ejemplo. int. ninguna.show().red = Rojo Color. int. int) fillRect(int. programa. int) drawOval(int. busca la documentación de la clase Color en el sitio de la API del JDK. Si quieres definir más colores.event.white = Blanco Color. Pero ¿cuál es la gran diferencia con los componentes que ya hemos visto? hasta aquí.setLayout(new FlowLayout()).html 151 152 ..green = Verde Color. int. int) drawRect(int.*. y) de la IG. private Canvas area. area.addMouseListener(new Pincel()).com/j2se/1. area = new Canvas(). int. int. lo que estamos haciendo es creando un Canvas de 800 x 600 pixeles de tamaño. y) y el punto 2 (x. y) y un tamaño horizontal y vertical definido. int) setFont(Font) drawString(String.setSize(800. Dibuja una elipse rellena en la posición centro (x.black = Negro Color. programa. drawLine(int. Dibuja una línea entre el punto 1 (x. int) 17 API del JDK: http://java. solo en la IG con la intención de que al ocurrir un evento de mouse. int. pueden ocurrir eventos de lo más normales. public Paint() { programa = new Frame("Java Paint").awt. y) con un tamaño horizontal y vertical definido.blue = Azúl Color.3/docs/api/index. Se definen los métodos de la clase Graphics: Método setColor(Color) Descripción Cambia el pincel al color de tipo Color.awt. el listener llamado Pincel lo capture. Más Eventos Otros eventos que se pueden utilizar se detallan en la siguiente tabla: Evento de Texto del Teclado Listener TextListener KeyListener Métodos a Implementar en el Listener void textValueChanged(TextEvent e) void keyPressed(KeyEvent e) void keyReleased(KeyEvent e) void keyTyped(KeyEvent e) void windowActivated(WindowEvent e) void windowClosed(Event e) void windowClosing(Event e) void windowDeactivated(Event e) void windowDeiconified(Event e) void windowOpened(Event e) Graphics Esta clase es utilizada por el canvas para dibujar.*.3) Capi tulo XV: Interfaces Gra ficas Java: del Grano a su Mesa (Versio n 1. int. int. una forma de poner un Canvas en una IG es igual que cualquier otra componente. y) y un tamaño horizontal y vertical definido. Para mayor información se recomienda visitar la página de la API de JDK en la página de la empresa SUN Microsystems 17.

// Mostramos la IG creada programa.Java: del Grano a su Mesa (Versio n 1.*. // Acciones que se realizan dentro del Canvas private void dibujaPunto(int x. como podemos ver no tenemos idea donde se está dibujando cada punto. Ese si sería trabajo del listener que.blue).add(salir).fillOval(x. 600). lo que queremos hacer es un área de dibujo utilizando un Canvas (muy similar al ejemplo que habíamos visto anteriormente). int) Descripción Limpia un área definida por el rectángulo asociado (ver drawRect).setColor(Color.. 1)). } Como podemos ver en estas pocas líneas. 5).getGraphics().setLayout(new GridLayout(3.applet.addMouseMotionListener(new Movimiento()). // Seteamos el color azul para dibujar el punto g. // Dibujamos un punto. utilizando el método anteriormente definido: .*. Existe un botón que permitirá terminar la ejecución del programa. private Canvas area. public Paint() { // Creamos primero la ventana de nuestro Paint programa = new Frame("Java Paint"). area. un ovalo de radio 5 // pixeles x 5 pixeles en el punto x. . area.awt. Veamos un ejemplo de utilización del canvas: import java. programa. dibujar un punto en la posición aquella. } .CENTER).add(p). programa. // Ponemos un boton para terminar y cerrar la ventana salir = new Button(”Salirá).. salir. import java. private Button salir. // Creamos el Canvas que nos permitira dibujar en el area = new Canvas(). int.. En este sector está nuestro CANVAS Pero como sabemos que el Canvas no es facil de trabajar. que es el MouseListener. import java.show(). podemos hacer muchas cosas. // Le ponemos un LABEL para la posicion del Mouse pos = new Label("". Panel p = new Panel(). Entonces. 5. p. En este caso particular.setSize(800.3) Capi tulo XV: Interfaces Gra ficas Método clearRect(int.awt. debemos implementar el primero de los listener. prepararemos algunos métodos que nos permitirán hacer “algo” dentro de él..addMouseListener(new Pincel()).addActionListener(new AccionBoton()). el cual nos permitirá hacer que si se presiona el botón del mouse. public class Paint { // Las componentes importates de la IG private Frame programa. cuando se presione el botón del mouse nos diga en qué posición (en pixeles) se hizo el click para dibujar el punto. Es muy importante destacar varios puntos: § § § El Canvas recibe acciones de MouseListener y MouseMotionListener en este ejemplo.add(pos). int y) { // Se obtiene primero el pincel del canvas Graphics g = area.setLayout(new FlowLayout())..pack(). p. area. Ahora bien.. Hay un label que nos indicará la posición (en pixeles) de donde se encuentra el puntero.. int.event. programa. Label. y indicado en // el parametro. class Pincel implements MouseListener { public void mouseClicked(MouseEvent e) { Todo esto queda distribuído y nos muestra algo como lo siguiente: 153 154 . programa..*. nuestro Java Paint solo dibujará puntos (por ahora): . Java: del Grano a su Mesa (Versio n 1.3) Capi tulo XV: Interfaces Gra ficas Con estos métodos. private Label pos. g. y. programa.add(area). es decir.

Problemas (a) Escribir la clase Consola que es una interfaz gráfica similar a la clase Console que hemos utilizado hasta ahora. import java. Es por eso que ponemos esa posición como un par ordenado en el label definido sobre el área llamado pos. Limpia la consola.event. Solución Partamos primero por la parte de dibujo de la IG: import java.. La IG que debe programar debe ser similar a esta: Canvas Como podemos ver suponemos en ambos eventos en los cuales se presiona el botón (click y pressed) para que dibuje el punto en x. Ahora implementemos el que nos indicará en qué posición se encuentra el mouse para mostrarla en el label que definimos sobre el área de dibujo: .getX().. y dado por e. e. Label vacío Botón En este caso.*.getY()). public class Consola { // Primero van las componentes necesarias para controlar // esta nueva consola. " + e..getY.getY() + ")"). Por último. } public void mouseReleased(MouseEvent e) { } } .. Imprime dentro de la consola el texto indicado en la posición actual saltando una línea después de hacerlo.*. } public void mouseDragged(MouseEvent e) { } } . pero si indicar en qué posición está el puntero del mouse. Pero en este caso no tenemos que dibujar.awt. } } } Nota: Los label vacío son solo para darle un toque de margen al cuento. private Frame ventana. el cual cierra la IG: . Java: del Grano a su Mesa (Versio n 1.. completamos con el ActionListener para el botón salir.3) Capi tulo XV: Interfaces Gra ficas dibujaPunto(e. caracter.awt. } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { dibujaPunto(e.setText("(" + e.getX(). // Tambien necesitaremos un punto para indicar en donde nos // encontraremos escribiendo dentro del Canvas private int linea. Crea una consola con el título indicado y de tamaño 320 x 240. class AccionBoton implements ActionListener { public vois actionPerformed(ActionEvent e) { // La IG se cierra si el programa termina System.getX() y e.3) Capi tulo XV: Interfaces Gra ficas Método Consola() Consola(String) void imprimir(String) void imprimirsl(String) void limpiar() Descripción Crea una consola con el título “Consola” y de tamaño 320 x 240.Java: del Grano a su Mesa (Versio n 1. private Button salir. class Movimiento implements MouseMotionListener { public void mouseMoved(MouseEvent e) { pos.getY()). mouseMoved nos indica si el mouse se mueve o no.*. Solo programe los siguientes métodos: 155 156 .. e. Imprime dentro de la consola el texto indicado en la posición actual sin salto de línea. import java.applet.exit(0).. Ojo con el Layout que está casi directo con el gráfico.. private Canvas area.getX() + ".

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XV: Interfaces Gra ficas

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XV: Interfaces Gra ficas
// Obtenemos el pincel Graphics g = area.getGraphics(); // Limpia la pantalla completa. g.clearRect(0, 0, 320, 240); // La posicion vuelve al inicio. linea = 1; caracter = 1; } // Metodos que imprimen en pantalla public void imprimir(String s) { // Obtenemos el pincel Graphics g = area.getGraphics(); // Escribimos el texto en el canvas g.drawString(s, (caracter ú 1)*7, linea * 12); // Dejamos el cursor al final caracter += s.length() + 1; } public void imprimirsl(String s) { // Usamos el metodo anterior imprimir(s); // Movemos el lapiz a la lınea siguiente linea++; caracter = 1; } }

public Consola(String titulo) { // Creamos la ventana con BorderLayout, con el tıtulo // pasado por parametro y color de fondo gris claro. ventana = new Frame(titulo); ventana.setLayout(new BorderLayout()); ventana.setBackground(Color.lightGray); // Creamos el Canvas de tamano definido 320x240, con // color de fondo blanco (diferenciarlo del frame) y // puesto al centro del layout del frame. area = new Canvas(); area.setSize(320, 240); area.setBackground(Color.white); ventana.add("Center", area); // Creamos el boton salir y lo ponemos al sur del // layout del frame. Ojo que para que quede pequenito // usamos un panel con FlowLayout. salir = new Button("Salir"); Panel p = new Panel(); p.setLayout(new FlowLayout()); p.add(salir); ventana.add("South", p); // Le damos el listener para que cierre la ventana // al click en el boton ”Salirá. salir.addActionListener(new Finalizar()); // Ponemos los labels vacıo de margen al rededor del // Canvas, es decir, al norte, este y oeste. ventana.add("North", new Label()); ventana.add("East", new Label()); ventana.add("West", new Label()); // Mostramos la ventana. ventana.pack(); ventana.show(); // Inicializamos como inicio de escritura. linea = 1; caracter = 1; } public Consola() { // Llama al otro constructor, pero con el tıtulo fijo. this("Consola"); } // Ahora le damos el listener del boton. class Finalizar implements ActionListener { public void actionPerformed(ActionEvent e) { System.exit(0); } }

Como los caracteres son de un tamaño de 12 pixeles de alto y 7 pixeles de ancho, podemos simular que escribimos el string en la posición (caracter-1)*7, linea*12 (considerando que para escribir necesitamos indicar la base del string). Ahora si probamos algo, podremos saber como queda:
public class MiPrograma { static public void main(String[] args) { Consola c = new Consola("Mi Consola"); c.imprimirsl("1234567890"); c.imprimir("123"); c.imprimir("123"); } }

Una vez que la parte gráfica está lista, podemos poner los métodos que trabajarán sobre el canvas y escribirán o borrarán algo:
// Metodo que limpia la pantalla public void limpiar() {

157

158

Java: del Grano a su Mesa (Versio n 1.3)
Capi tulo XVI: Interfaces Gra ficas SWING

Java: del Grano a su Mesa (Versio n 1.3)

Capi tulo XVII: Excepciones y Control de Errores

Capítulo XVI: Interfaces Gráficas SWING
(En construcción)

Capítulo XVII: Excepciones y Control de Errores Motivación
Lo más común al hacer programas en Java son los errores que aparecen en la “pantalla de la muerte” o salida de errores. Cómo manejarlos, entenderlo y lograr prever los posibles problemas en tiempo de ejecución es un trabajo de lo que se llaman Excepciones. Lo más importante es que Java provee una forma para que el programador controle fácilmente estos errores sin conocer las condiciones en las que ocurren previamente, bajo solo suposiciones del estilo “el archivo puede tener p roblemas de lectura/escritura, no existir o simplemente estar malo”.

Conceptos
Existen 2 clases de errores:

Errores de Compilación
Los errores de compilación son aquellos errores que son detectados por el compilador (javac) en el momento en que se genera la clase ejecutable (archivo .class) deseada.
Estos errores comúnmente ocurren cuando existe un error de sintaxis o falta alguna clase que es llamada en los archivos que crea el programador. Lo interesante de estos errores es que se pueden detectar rápida mente, pues el compilador indica exactamente qué pasó y donde ocurrió, lo que los hace muy fácil de controlar y corregir. Sin embargo, lo interesante no es esta clase de errores sino la que viene a continuación.

Errores de Ejecución (Runtime)
Los errores que ocurren en tiempo de ejecución o runtime son problemas que, al momento de ejecutar las clases ya compiladas, suelen ocurrir por ingreso de datos, manipulación de dispositivos de entrada/salida, condiciones de borde, conversión de tipos de datos, etc.
Existe una infinidad de razones de por qué el programa se cae en tiempo de ejecución. Veamos un pequeño ejemplo:
public class UnArreglo { static public void main (String[] args) { int[] ar = new int[10]; ar[10] = 25; } }

159

160

Java: del Grano a su Mesa (Versio n 1.3)

Capi tulo XVII: Excepciones y Control de Errores

Java: del Grano a su Mesa (Versio n 1.3)

Capi tulo XVII: Excepciones y Control de Errores
ar[0] = new Double("ALFA1").doubleValue(); } }

Este sencillísimo programa lo que hace es asignar fuera del rango del arreglo un valor. Bueno, si compilan este programita, se darán cuenta que no hay error detectable. Pero al momento de ejecutar la clase UnArreglo, lanzará el siguiente error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10 at UnArreglo.main(UnArreglo.java:4)

El stack de excepción quedaría:
Exception in thread "main" java.lang.NumberFormatException: ALFA1 at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal. java:1180) at java.lang.Double.valueOf(Double.java:172) at java.lang.Double.<init>(Double.java:244) at Programa.main(Programa.java:4)

Este texto indica el error o Excepción que ha ocurrido al ejecutar la clase. Analicemos un poco la excepción para saber cómo solucionarla:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10

El texto destacado ArrayIndexOutBoundsException indica qué ha ocurrido. En este caso (y solo bastaría utilizar un diccionario de Inglés-Español) podemos darnos cuenta que nos dice: Excepción de Índice Fuera del Rango del Arreglo. Tenemos identificado cuál es el error (que obviamente era el que predijimos al escribir el programa). Pero ¿dónde y por qué ocurrió?. Bueno, continuemos el análisis.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10

Bueno, ahora es un poquito más grande que en el ejemplo anterior, pero es analizable. Paso 1: Tomemos la línea que indica el tipo de excepción:
Exception in thread "main" java.lang.NumberFormatException: ALFA1

Esto nos indica que la excepción es NumberFormatException o traducida Excepción de Formato Numérico (o de Número). ¿Por qué?. El valor que viene a continuación “ALFA1” es el problema, puesto que (como pueden ver) no es numérico. Ese es el problema. Paso 2: Veamos el resto de la excepción para ver si logramos obtener donde ocurrió:
at java:1180) at at at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal. java.lang.Double.valueOf(Double.java:172) java.lang.Double.<init>(Double.java:244) Programa.main(Programa.java:4)

Este pequeño numerito casualmente coincide con el valor del rango que queríamos sobrepasar. Bueno, no es casualidad, porque en este caso ese valor indica la posición del arreglo que hemos querido asignar o referenciar y que está fuera del rango. El rango en este caso terminaba en la posición 9 y queríamos acceder a la 10. Por eso obtuvimos el error. Siguiendo:
at UnArreglo.main(UnArreglo.java:4)

Esta línea nos indica dónde ocurrió. En general esta línea no es una, sino varias, dependiendo cuántos métodos estemos llamando. Pero lo que indica es que en el método main de UnArreglo (esto lo dice en la parte UnArreglo.main) fue la excepción. Más específicamente, en la línea 4 del archivo UnArreglo.java. Ahora que sabemos todo, sinteticemos nuestro análisis: 1. 2. 3. 4. Tenemos una asignación fuera del rango de un arreglo. Tratamos de poner o referenciar la posición 10 del arreglo. El error está en el método main de la clase UnArreglo. La línea es la 4 del archivo UnArreglo.java.

Lo que anteriormente habíamos dicho se cumple, pues ya no es una línea, sino que son 4 líneas. Pero es sencillo descubrir donde está el error, pues buscamos aquellos programas que hemos hecho para buscar el error, en este caso, Programa.java es nuestro (los demás ni siquiera sabíamos que existían). Esta última línea nos dice nuevamente que el error está en el método main de la clase Programa, en la línea 4 del archivo Programa.java. Sencillo ahora que sabemos cómo hacerlo.

Sintaxis
Identificar Excepciones en Java
Las excepciones en general pueden ser de 2 tipos: • • Errores de Programación: Aquellos errores en donde el programador puede evitarlo porque es un error al codificar el programa Errores de Datos: Aquellos errores que el programador puede evitar, o simplemente no puede hacerlo, ya que son problemas en la interacción programa-usuario.

Con esta información es fácil corregir el problema. Analicemos otro problema algo más complejo:
public class Programa { static public void main (String[] args) { double[] ar = new double[10];

161

162

Veamos el siguiente ejemplo: public class Archivo { static public void main (String[] args) throws Exception { BufferedReader br = new BufferedReader( new FileReader (”archivo. esto quiere decir.close(). pero s e leen los 3 como enteros.io. } public int leeEntero() throws NumberFormatException { return Integer.in)).FileNotFoundException must be caught. ¿Cómo se hace? Ya hemos utilizado una forma de control de esto en archivos.java:6: Exception java.out. pues al utilizarlos no deberían existir. continua el programa br. FileNotFoundException { BufferedReader br = new BufferedReader( new FileReader (”archivo.close(). or it must be declared in the throws clause of this method. continua el programa br.ClassNotFoundException class java. ^ Archivo. or it must be declared in the throws clause of this method. System. Se muestra una lista completa de excepciones.io.zip.. // .print("Ingrese un Entero?").txtá)).security.security.txt")).txtá)).lang. Pero solo en el caso especial de los archivos se obliga poner un throws en la firma del método.parseInt(lector. pero en el método padre (llamador) main(String[] args) se indica que es Exception la que debe manejar. } } public class Lector { static public void main (String[] args) throws Exception { Datos l = new Datos(). se está indicando que captura la excepción NumberFormatException. } } Veamos otro ejemplo.ServerCloneException class java. int r = l.util.acl.java:10: Exception java.Java: del Grano a su Mesa (Versio n 1. Aquí ocurre algo muy interesante. Aquellas que se encuentran marcadas son las que comunmente les podría ocurrir.awt.EOFException class java. el compilador nos da el error: Archivo. Si no pusiéramos este handler. enviará un NumberFormatException al ingresar el real.leeEntero(). Java provee una forma de atrapar los errores de datos y poder controlar así los programas evitando que el usuario utilice mal el programa o simplemente no pasen imprevistos como falta el archivo.FileNotFoundException 18 De esa forma (y solo en este caso) el compilador nos indica cuáles son las excepciones que debe manejar el método.io.close(). ¿Por qué?. System..out..io. en el cuál no es necesaria una cláusula throws pero si se pueden controlar excepciones de otro tipo: class Datos { private BufferedReader lector.IOException class java. new FileReader ("archivo.lang.. public Datos () { lector = new BufferedReader( new InputStreamReader(System. También. A diferencia de los programas tradicionales. pues en el método leeEntero(). es por eso que podríamos poner: public class Archivo { static public void main (String[] args) throws IOException.DigestException class java. En este caso y si el usuario ingresa lo que le piden.DataFormatException class java. br.io.rmi. este método posee una sentenc ia adicional en su firma que dice throws Exception. } } Este sencillo código nos muestra como utilizamos un archivo de texto (visto en clases anteriores).readLine()). int e = l. // .server.Exception class java.3) Capi tulo XVII: Excepciones y Control de Errores Es claro que los primeros son muy graves.io.rmi. En realidad la razón fue solamente por comodidad. Sin embargo estos errores no son los más comunes. Las demás son para que conozcan todas las excepciones que existen 163 164 .lang. ^ 2 errors En este caso (y como se puede ver) se piden 3 valores distintos.leeEntero().AclNotFoundException class java. no tiene permisos para escribir o que se haya cerrado el puerto. } } y también está correcto.AWTException class java.IOException must be caught.CharConversionException class java.print("Ingrese un Real?"). pues Exception es una superclase de todas las excepciones 18: class java.AlreadyBoundException class java. que maneje (handle) las excepciones que ocurran.3) Capi tulo XVII: Excepciones y Control de Errores Java: del Grano a su Mesa (Versio n 1.CloneNotSupportedException class java.

lang. El otro punto importante es que.rmi.IntrospectionException class java.lang.security.ConnectException class java.security.net.security.UnexpectedException class java.rmi.net.StringIndexOutOfBoundsException class java.zip.lang.sql.security.BindException class java.3) Capi tulo XVII: Excepciones y Control de Errores class java.UnknownHostException class java.ArrayIndexOutOfBoundsException class java.rmi.util.UnknownHostException class java. al capturar una excepción dentro de un método.TooManyListenersException class java.io.IllegalArgumentException class java.rmi.rmi.ProtocolException class java.ExportException class java.lang.lang.StreamCorruptedException class java.sql.io.rmi.ParseException class java.MalformedURLException class java.IllegalThreadStateException class java.server.ServerNotActiveException class java. Sin embargo.io.awt.SQLWarning class java.InstantiationException class java.Java: del Grano a su Mesa (Versio n 1.security.NoSuchFieldException class java.rmi.ArithmeticException class java.io.security.InvalidObjectException class java.server.util.net.InterruptedException class java.ConnectException class java.ServerRuntimeException class java. 165 166 .io.InvocationTargetException class java.acl.ServerException class java.UTFDataFormatException class java.rmi. Por eso es requerido que el main tuviera el throws en su firma.net.lang.rmi.rmi.ProviderException class java.lang.ArrayStoreException class java.SQLException class java.RemoteException class java.rmi.rmi.IllegalComponentStateException class java.UnknownServiceException class java.KeyManagementException Java: del Grano a su Mesa (Versio n 1.InvalidClassException class java.InterruptedIOException class java.lang.rmi.lang.net.security.rmi.ObjectStreamException class java.MissingResourceException class java.NotOwnerException class java.SkeletonMismatchException class java.WriteAbortedException class java.util.NoSuchObjectException class java.awt.io.SocketSecurityException class java. todos los llamadores deben traspasar el control de ella hasta el método main (o al principal).lang.IllegalStateException class java.security.UnsupportedFlavorException Entonces.NotBoundException class java.io.UnsupportedEncodingException class java.ClassCastException class java.lang.RMISecurityException class java.net.sql.SyncFailedException class java.NoSuchMethodException class java.NoSuchElementException class java.lang.lang.io.NullPointerException class java.SkeletonNotFoundException class java.LastOwnerException class java.reflect.StubNotFoundException class java.rmi.IllegalMonitorStateException class java.3) Capi tulo XVII: Excepciones y Control de Errores class java.security.lang.rmi.rmi.lang.IndexOutOfBoundsException class java.PropertyVetoException class java.SocketException class java.NoSuchProviderException class java.server.NoSuchAlgorithmException class java.lang.NoRouteToHostException class java.io.beans.NegativeArraySizeException class java.SecurityException class java.lang.KeyException class java.util.ConnectIOException class java.AccessException class java.InvalidParameterException class java.server.net.IllegalAccessException class java.text.SignatureException class java.server.io.DataTruncation class java.MarshalException class java.io.NumberFormatException class java.InvalidKeyException class java.ServerError class java.util.rmi.lang.rmi.RuntimeException class java.security.NotActiveException class java.rmi. uno puede atrapar todas las excepciones utilizando la clase Exception.ZipException class java.beans.lang.io.OptionalDataException class java.lang.net. no es estrictamente esa sentencia la que se debe usar (veremos otra).lang.datatransfer.EmptyStackException class java.UnmarshalException class java.NotSerializableException class java.acl.

otras cosas) sin que el programa se caiga.txtá)). y no el molesto stack de excepción indicando qué ocurrió. public Datos () { try { lector = new BufferedReader( new InputStreamReader(System. pues por razones de distintos errores pueden ocurrir las 2 excepciones. 167 168 .close()... por supuesto.out. Las Exception1 .. el resultado si archivo.close()..out.. reales. } catch (NumberFormatException e) { System. } } public class Lector { static public void main (String[] args) { Datos l = new Datos().println (”No ingreso enteroá). try { int e = l.out. y dependiendo del tipo de error que ocurra. la ejecucion cuando ocurre Exception1 la ejecucion cuando ocurre Exception2 la ejecucion cuando ocurre ExceptionN Cuando existe una sección crítica. } } public int leeEntero() throws NumberFormatException { return Integer.. continua el programa } } Este nuevo código permitiría que el usuario nunca ingresara un valor distinto a un entero (es decir letras.out.Java: del Grano a su Mesa (Versio n 1. catch. Si ejecutan este código. // . Una sección critica es línea o trozo de código que pueden “caerse” por causa de una excepción. // .3) Atrapar y Controlar Excepciones Capi tulo XVII: Excepciones y Control de Errores Java: del Grano a su Mesa (Versio n 1.. boolean entero = false. Una sección crítica se delimita con la sentencia try.leeEntero().out.exit(0). } catch(Exception e) { System.println (”Imposible abrir entradaá). while (!entero) { System. Su sintaxis es: try { // Codigo que se quiere } catch (Exception1 <var1>) { // Codigo que reemplaza } catch (Exception2 <var2>) { // Codigo que reemplaza } . continua el programa br. el “handler” cambia.print("Ingrese un Entero?"). ExceptionN son los nombres de las excepciones que ocurren.. } } } Esta es la versión más simple.parseInt(lector.println(”Ha ocurrido un errorá)..println(”Ahora si fue un enteroá).readLine()).in)). } catch(FileNotFoundException e) { System. } catch(IOException e) { System.txtá)).out. } catch (Exception e) { System.println(”Error al leer el archivoá). los catchs indican las excepciones que pueden ocurrir en cualquier nivel de éste.3) Capi tulo XVII: Excepciones y Control de Errores br. Un ejemplo es: public class Archivo { static public void main (String[] args) { try { BufferedReader br = new BufferedReader( new FileReader (”archivo.out. entero = true. catch (ExceptionN <varN>) { // Codigo que reemplaza } evitar una excepcion En este segundo caso.txt no existe es “Ha ocurrido un error”.println(”No existe el archivoá). } } System. System. Pero se puede dividir también en distintas excepciones: public class Archivo { static public void main (String[] args) { try { BufferedReader br = new BufferedReader( new FileReader (”archivo. se despliega el mensaje adecuado. Veamos otro ejemplo: class Datos { private BufferedReader lector.. } } } Lo siguiente que veremos es la forma en que se puede atrapar una excepción y evitar que el programa se caiga por ello (lo que siempre hemos deseado).

Java: del Grano a su Mesa (Versio n 1.3)
Ahora, ¿para qué sirve la variable e que posee el catch?.

Capi tulo XVII: Excepciones y Control de Errores

Java: del Grano a su Mesa (Versio n 1.3)
Error: 8.5 Ingrese un Entero?6 Ahora si fue un entero

Capi tulo XVII: Excepciones y Control de Errores

La variable que va definida en el catch a un costado del tipo de excepción es una referencia a un objeto del tipo de esa excepción. Sirve para obtener mayor información de ella: • • String getMessage(): Obtiene un corto mensaje descriptivo del error que ocurrió. void printStackTrace(): Imprime en la salida de error (estándar) el stack de excepción de la que ocurrió.

Algo mucho más limpio y ordenado.

Lanzar Excepciones
Java provee además la posibilidad de lanzar excepciones propias. Esto se hace a través de la sentencia throw (si, parecido a un throws pero sin la s final). Por ejemplo:

Por ejemplo, si miramos el main anterior (último ejemplo):
static public void main (String[] args) { Datos l = new Datos(); boolean entero = false; while (!entero) { System.out.print("Ingrese un Entero?"); try { int e = l.leeEntero(); entero = true; } catch (Exception e) { System.out.print (”Error: ”); System.out.println (e.getMessage()); e.printStackTrace(); } } System.out.println(”Ahora si fue un enteroá); }

class Datos { private BufferedReader lector; public Datos () { try { lector = new BufferedReader( new InputStreamReader(System.in)); } catch (Exception e) { System.out.println ("Imposible abrir entrada"); System.exit(0); } } public int leeEntero() throws NumberFormatException { String linea = ""; try { linea = lector.readLine(); } catch (IOException e) { } if (linea.length() <= 0) throw new NumberFormatException(); return Integer.parseInt(linea); } } public class Lector { static public void main (String[] args) { Datos l = new Datos(); boolean entero = false; while (!entero) { System.out.print("Ingrese un Entero?"); try { int e = l.leeEntero(); entero = true; } catch (NumberFormatException e) { System.out.println ("No ingreso entero"); } } System.out.println("Ahora si fue un entero"); } }

En este caso, si ocurre el error, se puede saber qué ocurrió. Un ejemplo de ejecución:
Ingrese un Entero?A Error: A java.lang.NumberFormatException: A at java.lang.Integer.parseInt(Integer.java:409) at java.lang.Integer.<init>(Integer.java:544) at Datos.leeEntero(Lector.java:11) at Lector.main(Lector.java, Compiled Code) Ingrese un Entero?8.5 Error: 8.5 java.lang.NumberFormatException: 8.5 at java.lang.Integer.parseInt(Integer.java:418) at java.lang.Integer.<init>(Integer.java:544) at Datos.leeEntero(Lector.java:11) at Lector.main(Lector.java, Compiled Code) Ingrese un Entero?6 Ahora si fue un entero

Si no pusiéramos el método printStackTrace() el programa queda:
Ingrese un Entero?A Error: A Ingrese un Entero?8.5

169

170

Java: del Grano a su Mesa (Versio n 1.3)

Capi tulo XVII: Excepciones y Control de Errores

Java: del Grano a su Mesa (Versio n 1.3) Crear Excepciones

Capi tulo XVII: Excepciones y Control de Errores

Este programa obliga al sistema a enviar una excepción de tipo NumberFormatException cuando es ingresado por el teclado un string vacío. Nótese que es muy importante poner la sentencia throws para que la excepción lanzada sea capturada por el método llamador. Es muy interesante este punto de vista, ya que, mezclado con la sentencia try... catch puede ser una herramienta útil al momento de controlar errores que antes no podíamos. Veamos otro ejemplo:
public class Selector { static public BufferedReader b = new BufferedReader ( new InputStreamReader(System.in)); static public String leeOpcion() throws Exception { String op; try { op = b.readLine(); } catch (IOException e) { op = ”á; } if (op.length() <= 0) throw new Exception(”Debe ingresar una opcionó); if (!op.equals(”Aá) && !op.equals(”Bá) && !op.equals(”Cá)) throw new Exception(”Las opciones son A, B, Có); return op; } static public void main (String[] args) { while (true) { System.out.print(”Ingrese A, B o C?á); String op = ”á; try { op = leeOpcion(); break; } catch (Exception e) { System.out.println(e.getMessage()); } } } }

El problema que hay con utilizar Exception directamente, es que a veces ocurren otras excepciones y se pierde saber qué ocurrió. Es por eso que podemos crear propias excepciones que se ajusten al nivel del programa. Veamos el mismo ejemplo, pero algo modificado:
public class Selector { static public BufferedReader b = new BufferedReader ( new InputStreamReader(System.in)); static public String leeOpcion() throws OptionException { String op; try { op = b.readLine(); } catch (IOException e) { op = ”á; } if (op.length() <= 0) throw new OptionException(); if (!op.equals(”Aá) && !op.equals(”Bá) && !op.equals(”Cá)) throw new OptionException(); return op; } static public void main (String[] args) { while (true) { System.out.print(”Ingrese A, B o C?á); String op = ”á; try { op = leeOpcion(); break; } catch (OptionException e) { System.out.println(e.getMessage()); } } } }

La salida de este programa sería:
Ingrese A, B o C? Debe ingresar una opcion Ingrese A, B o C? 34 Las opciones son A, B, C Ingrese A, B o C? sdf Las opciones son A, B, C Ingrese A, B o C? A

Cambiamos la excepción por una llamada OptionException. ¿De dónde salió?. Pues la idea es que implementemos esa clase para que se pueda utilizar como excepción igual que las otras:
public class OptionException extends Exception { public OptionException { super(”Opcion invalida. Las opciones son A, B o Cá); } }

Como podemos notar, ahora solo permitimos lanzar excepciones de tipo Exception pero con mensaje personalizado.

Ahora, el programa impide que se ingrese algo distinto de A, B o C lanzando una excepción OptionException y todo queda solucionado.

171

172

Java: del Grano a su Mesa (Versio n 1.3)

Capi tulo XVII: Excepciones y Control de Errores

Java: del Grano a su Mesa (Versio n 1.3)
} }

Capi tulo XVII: Excepciones y Control de Errores

Problemas
Se quiere crear un visor de archivos de texto. Para ello se le pide: (a) Construya una clase que manipule los archivos de texto encapsulando la clase BufferedReader y controlando las IOException que puedan ocurrir (No existe el archivo, Fin de Archivo inesperado, etc.)

Nótese que en esta segunda versión ya no se usa el NULL como fin de archivo. (b) Escriba un programa (main) que simule el siguiente diálogo:
Bienvenido al Visor 1.0

Solución
Versión sin crear una Excepción:
public class Visor { private String nombre; public Visor (String nombre) { this.nombre = nombre; } public String leeArchivo () throws IOException { BufferedReader lector; lector = new BufferedReader ( new FileReader(this.nombre)); String texto = ”á; String linea = ”á; while ( (linea = lector.readLine()) != null) texto = texto + ”\ná + linea; lector.close(); return texto; } }

Ingrese el Nombre del Archivo: tarea.java No existe el Archivo Ingrese el Nombre del Archivo: tarea4.java [INICIO DEL ARCHIVO] ... // Aquı aparece el archivo de texto lınea a lınea [FIN DEL ARCHIVO] Posee 57 lıneas y 453 caracteres Ingrese el Nombre del Archivo: Se utilizo el programa 2 veces 1 archivos leıdos 1 archivos no existıan

Solución
Utilizando la versión sin crear una Excepción:
static public void main (String[] args) throws IOException { BufferedReader in = new BufferedReader ( new InputStreamReader (System.in)); System.out.println(”Bienvenido al Visor 1.0á); // Variables que se leen al final int siL = 0; int noL = 0; // Ciclo de Lectura while (true) { System.out.print(”Ingrese el Nombre del Archivo: ”); String nombre = in.readLine(); if (nombre.length() <= 0) break; // Leemos el arhivo y controlamos la excepcion Visor v = new Visor(nombre); try { String texto = v.leeArchivo(); // Si ocurrio una excepcion, no continua System.out.println(”[INICIO DEL ARCHIVO]á); System.out.println(texto); System.out.println(”[FIN DEL ARCHIVO]á); // Contamos las lıneas y los caracteres int ls = contarLineas(texto); int cs = texto.length(); System.out.println(”Posee ” + ls + ” lınea y ” + cs + ” caracteresá); siL++;

Versión usando Exception:
public class Visor { private String nombre; public Visor (String nombre) { this.nombre = nombre; } public String leeArchivo () throws Exception { BufferedReader lector; try { lector = new BufferedReader ( new FileReader(this.nombre)); } catch (FileNotFoundException e) { throw Exception(”El archivo no existeá); } String texto = ”á; try { while (true) texto = texto + ”\ná + lector.readLine(); } catch (EOFException e) { } lector.close(); return texto;

173

174

Java: del Grano a su Mesa (Versio n 1.3)

Capi tulo XVII: Excepciones y Control de Errores
} catch (FileNotFoundException e) { System.out.println (”No existe el archivoá); noL++; } } // Fin del programa System.out.println(”Se utilizo el programa ” + (siL + noL) + ” vecesá); System.out.println(siL + ” archivos leıdosá); System.out.println(noL + ” archivos no existıaná); }

Java: del Grano a su Mesa (Versio n 1.3)

Capi tulo XVII: Excepciones y Control de Errores

Y ahora el que cuenta líneas
static public int contarLineas (String texto) { int total = 1; for (int i=0; texto.indexOf(”,á, i) > 0; i = texto.indexOf(”,á, i) + 1) total++; }

Utilizando la versión con Exception:
static public void main (String[] args) throws IOException { BufferedReader in = new BufferedReader ( new InputStreamReader (System.in)); System.out.println(”Bienvenido al Visor 1.0á); // Variables que se leen al final int siL = 0; int noL = 0; // Ciclo de Lectura while (true) { System.out.print(”Ingrese el Nombre del Archivo: ”); String nombre = in.readLine(); if (nombre.length() <= 0) break; // Leemos el arhivo y controlamos la excepcion Visor v = new Visor(nombre); try { String texto = v.leeArchivo(); // Si ocurrio una excepcion, no continua System.out.println(”[INICIO DEL ARCHIVO]á); System.out.println(texto); System.out.println(”[FIN DEL ARCHIVO]á); // Contamos las lıneas y los caracteres int ls = contarLineas(texto); int cs = texto.length(); System.out.println(”Posee ” + ls + ” lınea y ” + cs + ” caracteresá); siL++; } catch (Exception e) { System.out.println (e.getMessage()); noL++; } } // Fin del programa System.out.println(”Se utilizo el programa ” + (siL + noL) + ” vecesá); System.out.println(siL + ” archivos leıdosá); System.out.println(noL + ” archivos no existıaná); }

(c) Propuesto. Construya un applet que utilice el Visor construído en (a) para que funcione gráficamente.

175

176

x++) { String nombre = ”pá. BufferedReader bf = new BufferedReader( New FileReader(nombre)). String linea. es decir siempre ocurre que: • • • • • • Auxiliar 1 corrige Pregunta 1 Auxiliar 2 corrige Pregunta 2 Auxiliar 3 corrige Pregunta 3 Auxiliar 4 corrige Pregunta 1 Auxiliar 5 corrige Pregunta 2 .doubleValue().in)).out. // Se inician notas en 1 y auxiliaries en 0 for (int x=0.close(). while( (linea=bf.substring(0. int codigo = Integer. Veamos como se resolvería con lo que sabemos: public class NotasControl { // Lector de la Entrada Estandar BufferedReader in = new BufferedReader( new InputStreamReader(System.parseInt( linea. Lo más simpático es la correspondencia de corrección. p<3. } double prom = suma / 3. } // Ya tenemos leido todos los datos.println(”Promedio = ” + prom). y++) { Podemos ver que la solución no es para nada difícil de realizar. double suma = 0.out.readLine()). nombre += nn.3) Capi tulo XVIII: Tipos y Estructuras de Datos notas[x][y] = 1. nombre += x. Veremos que las Estructuras de Datos nos permiten realizar o almacenar objetos y cualquier tipo de elemento que se nos ocurra utilizando una clase la cual almacena la información que nosotros queremos manipular. if (nn < 10) nombre += ”0á. el promedio del control y el código del auxiliar que le corrigió. nn++.. sin embargo se están utilizando 2 arreglos para almacenar los valores.substring(3. } } } Se pide construir un programa que permita leer TODOS LOS ARCHIVOS de las 3 preguntas del control 2. System. p++) { System. esquemas. 177 178 . 3) ). notas[cod][x] = nota. 3)). x++) { for (int y=0. double nota = new Double( linea. } } Capítulo XVIII: Tipos y Estructuras de Datos Motivación Con todo lo que ya hemos visto hasta ahora podemos resolver un sin número de problemas computaciones aplicando los conceptos.3) Capi tulo XVIII: Tipos y Estructuras de Datos Java: del Grano a su Mesa (Versio n 1. static public void main (String args[]) { // Arreglos que almacenaran las notas y // el codigo del auxiliar que corrigio double[][] notas = double[1000][3]..out.0. almacenándolas en memoria. for (int x=0. ¿Podría haber sido solo uno?. for (int p=0. y<3. Se les ha pedido que cada vez que corrijan construyan un archivo llamado “pX-auxNN” en donde X indica el número de la pregunta y NN el número del auxiliar (numerado entre 01 y 18). x<3.println(”Pregunta ” + (p+1) + á = ” + notas[codigo][p] + ” (Aux: ” + aux[codigo][p] + ”)á). patrones de programación e instrucciones que utiliza Java. System. int[][] aux = int [1000][3]. Suponga que hay un máximo de 1000 alumnos (de 000 a 999) y que la estructura de los archivos es: • • Código interno del alumno (3 caracteres) Nota del alumno en la pregunta (3 caracteres con . } bf. Veamos un problema: Los auxiliares de CC10A corrigen las preguntas de un grupo de mechones de todas las secciones por separado.Java: del Grano a su Mesa (Versio n 1. // Veamos el ciclo de consulta de notas.println(”Tus notas son: ”). en medio) ¿Por qué no podríamos resolver este problema? Es bastante sencillo pues tenemos toda la información posible.readLine()) != null ) { int cod = Integer. x<1000. // Ciclo lector de las preguntas int nn = 1.out. aux[x][y] = 0.parseInt(in. nombre += á-auxá. while(true) { System. para luego que un alumno ingrese su número interno muestre las notas de las 3 preguntas. aux[cod][x] = nn. suma += notas[codigo][p].print(”Codigo de alumno?á).

j<nMax. Pero ¿para qué sirve?. this.compareTo(a[j+1]) > 0) { Tenista auxiliar = a[j]. ya que la cantidad de puntos es un valor entero y los otros 2 campos son Strings. public Tenista (String nombre. j++) { if (a[j]. int nMax) { // Version Recursiva de BUBBLESORT if (nMax <= nMin) return. Pero no es tan sencillo. } Unos dirían: “esto es una matriz”. this.pais = pais. si pensamos un poco. nMin. } } Entonces. utilizar una clase que permitiera que los objetos se compararan: EsComparable. String pais) { this. } } Con esto hacemos ahora que nuestra clase Tenista sea Comparable: public class public public public Tenista implements Comparable { String nombre. podemos modificar nuestro ordenamiento y ahora permitir utilizar esta comparación: void bubbleSort (Tenista[] a. } Concepto Tipo de Dato Abstractos Se denominará Tipo de Dato a una clase que será construida para almacenar un elemento especial. j<nMax.Java: del Grano a su Mesa (Versio n 1. Por ejemplo nos gustaría modelar el ranking de la ATP sabiendo que: • • • Todo tenista posee un nombre También una nacionalidad Y un cantidad de puntos Todo está bien EXCEPTO por la línea destacada en la cual se comparan los elementos.ganarPuntos(1000). se han adelantado a esto y la interface Comparable ya existe es: public interface Comparable { public int compareTo (Object obj). ¿Cómo mezclamos esto? Sencillo.puntos ú ((Tensita) obj). nMax-1). String pais. String pais. int nMin. Sin embargo.3) Capi tulo XVIII: Tipos y Estructuras de Datos Java: del Grano a su Mesa (Versio n 1.. Esta definición nos abre la mente para trabajar en forma más genérica de lo que hemos estado haciéndolo hasta ahora.nombre = nombre. this. for (int j=nMin. . this. y tenemos un nuevo tenista en la ATP con 1. a[j] = a[j+1].puntos. ahora bastaría crea solo 1 arreglo de tipo Tenista y cargar todo allí de la siguiente forma: Tenista ranking[]. Nos permitirá modelar estructuras combinados con otros tipos u objetos de clases de Java. a[j] = a[j+1]. Para solucionar esto. String pais) { this. j++) { if (a[j] > a[j+1]) { Tenista auxiliar = a[j].puntos = 0. int nMin. ¿cuál sería la utilidad al momento de querer ordenar el arreglo? Analicemos este no tan sencillo problema y démosle una solución.3) Capi tulo XVIII: Tipos y Estructuras de Datos // Version Recursiva de BUBBLESORT if (nMax <= nMin) return. Una sencilla clase que define por completo al tenista. int puntos. Ahora.. public Tenista (String nombre.puntos = 0. } public int compareTo(Object obj) { return this. Bueno. a[j+1] = auxiliar. podemos definir todas aquellas funcionalidades que pueden ser útiles como ganarPuntos(int puntos) agrega la cantidad de puntos al tenista. usaremos lo que en la última clase quedó como problema. for (int j=nMin. void bubbleSort (Tenista[] a.nombre = nombre. Además. } } bubbleSort (a.pais = pais. int puntos. ranking[37] = new Tenista(”Marcelo Rıosá. y gracias a los creadores de Java. ya que claramente se trata de comparar 2 objetos de tipo Tenista en donde no está definido el comparador > (mayor que) directamente. a[j+1] = auxiliar.000 puntos. int nMax) { 179 180 . ranking[37]. Definamos el tipo de dato Tensita: public class public public public Tenista { String nombre. ”Chileá). Si observamos un poco el constructor que se ha declarado es la idea de un nuevo tenista que recién entra al ranking.

El Tipo de Dato String es comparable por definición. nMin. // Cambiar Tensita por Comparable . Sintaxis Pilas y Colas Estas estructuras de datos tienen algunas características especiales y pueden ser representadas a través de arreglos de valores. Por ejemplo: Si ponemos un CD sobre otro CD y así sucesivamente hasta llegar a 20 CD’s apilados.. ya que si miramos bien bastaría cambiar el método compareTo de la clase Tensita para cambiar la forma de ordenamiento y NO el método de ordenamiento. <= y ==.pila = new Comparable[n]. // PILA VACIA this. si ahora generalizamos un poco más la firma del método: void bubbleSort (Comparable[] a. } public Comparable pop() { if (this. nMax-1). p. Un ejemplo de utilización de la pila puede ser: Pila p = new Pila (100). Veamos otras estructuras de datos que son útiles y que se implementan usando tipos de datos conocidos. public Pila (int n) { this. pero ellos tienen comparadores >.n = 0. >=. Además. ya que este fue el último que puse en la pila de CD’s. <.. protected int n. Luego veremos tipos nuevos con los cuales se podrían implementar las estructuras: La definición estándar de pila indica que debe tener 2 métodos: uno para poner al tope de la pila (push) y otro para sacar del tope de la pila (pop).length) return. de tarros de salsa o de objetos). Tenista t1 = new Tenista(”Marcelo Rıosá.n == this.3) Capi tulo XVIII: Tipos y Estructuras de Datos } } bubbleSort (a. } public void push(Comparable obj) { if (this.. this.n--. // PILA LLENA this. 181 182 . En el caso del tipo de dato String funciona perfectamente. Su implementación puede ser hecha a través de un arreglo 20 (con un margen máximo) encapsulada dentro de una clase Pila (la haremos de objetos que son comparables.pila[this.. p. ”Chileá). un arreglo es una Estructura de Datos. Solo en el caso de los tipos numéricos nativos no funcionaría este método. this. Tenista t2 = new Tenista(”Boris Beckerá. Por la definición. } Java: del Grano a su Mesa (Versio n 1. ya que es comparable): class Pila { protected Comparable[] pila.Java: del Grano a su Mesa (Versio n 1.3) Capi tulo XVIII: Tipos y Estructuras de Datos ¡Hemos creado un ordenador de objetos genéricos! Si. } } Tendremos un método que puede ordenar CUALQUIER clase de Tipos de Dato que sean Comparable19. Estructura de Datos Una Estructura de Datos es una combinación de elementos de un mismo Tipo de Dato tradicional o abstracto. Su característica principal está dada por la sigla con la cuál se les llama LIFO (“Last In First Out”) que significa que el último que llega a una pila es el primero que sale. Más adelante se ven otras formas de implementar una Pila y una Cola.pila.n == 0) return null. int nMin.n] = obj.push(t1).pila[this. return this. ”Alemaniaá). Sin embargo ambos son encapsulados para convertirlos en estructuras. 19 20 No es la única forma de representación. de papeles. Interesante.push(t2). Esta definición de lo que son las Estructuras de Datos nos permite ampliar el espectro de los que son los Arreglos de Datos a otras estructuras más comeplejas. solo podremos VER y/o SACAR el de arriba sin afectar a los demás. entrará en esa posición de la pila. ya que nos permite almacenar un montón de elementos del mismo tipo en una misma variable.n]. } Pila (LIFO): Es una estructura lineal que se asemeja a las torres de cosas (de platos. int nMax) { . que puede ser referenciado con variables y que posee algunas características que la hacen especial y diferente a otras estructuras de datos conocidas.n++. El constructor solo crea la pila con un máximo número de elementos y luego pone el tope en 0 para indicar que el siguiente elemento que puede entrar.

en el fondo es una cola FIFO. Al igual que en el caso de las pilas. manos a la obra. una Lista Enlazada es la estructura que es formada por un conjunto de Nodos enlazados entre sí. public Nodo(Object o) { this. Esta sencilla definición es para declarar tipos de datos dinámicos que nos permitas ir combinando las propiedades de los arreglos.3) Capi tulo XVIII: Tipos y Estructuras de Datos Tenista t2 = new Tenista(”Boris Beckerá. Una lista con enlace simple se vería como: La definición estándar de pila cola que debe tener 2 métodos: uno para poner al final de la cola (put) y otro para sacar del inicio de la cola (get).end). etc. this.sgte = null. end. paso a embarazadas y ancianos. public class Nodo { Object info. Un ejemplo de utilización de la cola puede ser: Cola p = new Cola (100). Su característica principal está dada por la sigla con la cuál se les llama FIFO (“First In First Out”) que significa que el primero que llega a una cola es el primero que sale (que se atiende).cola[this.3) Capi tulo XVIII: Tipos y Estructuras de Datos Java: del Grano a su Mesa (Versio n 1. return this.full = false. Aunque aquí ocurren algunas singularidades.cola = new Comparable[n]. la fila del colegio o fila de fichas de dominó). protected boolean full. // COLA LLENA this. full = (this. this. Pero la mejor forma de entender estas cosas es practicando. // COLA VACIA this.end) return null. } public void put(Comparable obj) { if (full) return. El constructor solo crea la cola con un máximo número de elementos y luego pone el final en 0 para indicar que el s iguiente elemento que puede entrar.end = 0.info = o. this.beg++. es decir. Info Info Info Info 183 184 .cola[this. Tenista t1 = new Tenista(”Marcelo Rıosá. protected int beg. } public Comparable get() { if (this. Lista Enlazada (2): Estructura de Datos que permite almacenar un número variable de Nodos y que puede estar restringido SOLO por la cantidad de memoria del procesador que está almacenando la lista. pero en forma más dinámica y crecida.Java: del Grano a su Mesa (Versio n 1. Nodo sgte.beg-1]. Cola (FIFO): Es una estructura lineal que se asemeja a las filas o colas en la vida real (la cola de un banco. En forma rápida y sencilla. this. las colas tienen una representación en Java a través de un arreglo circular que se encapsula en una clase llamada Cola: class Cola { protected Comparable[] cola.beg == this. public Cola (int n) { this. p.beg = 0. así que. } } Este ejemplo. p. this. El ejemplo más clásico es el de los bancos. por ejemplo. a diferencia del de Pilas (aunque parezcan iguales) pone a Marcelo Ríos en el final de la cola dejando a Boris Becker para salir antes que Marcelo de la fila. ya que el que llega primero a la fila siempre sale primero del banco. Punteros: Enlace a otro (s) elemento(s) del mismo tipo de dato. Un Nodo se compone genéricamente de: • • Campo de Información: Almacena la información asociada al Tipo de Dato que define el Nodo. } } Gráficamente se vería como: INFO Enlaces Lista Enlazada (1): Conjunto de Nodos que permiten simular un arreglo dinámico. ”Alemaniaá). Este ejemplo pone a Marcelo Ríos en el tope de la pila dejando a Boris Becker para salir después de Marcelo.put(t2).end] = obj.beg == this. ”Chileá).end++. el inicio en 0 porque la cola está vacía y un indicador booleano que dirá cuándo estará llena la cola. que puede crecer con el tiempo. Listas Enlazadas Nodo: Tipo de Dato Abstracto que permite almacenar elementos con cierta estructura y que se pueden enlazar con uno o más elementos del mismo tipo.get(t1).

// Ingreso de nombres: while(true) { System. y el resto se recorre siguiente los punteros al siguiente elemento de la lista (es como caminar de Nodo en Nodo)..print (”Nombre? ”).3) Capi tulo XVIII: Tipos y Estructuras de Datos Para poder referencias esta estructura de datos se requiere de una Cabeza Lectora que apunta al inicio de la lista enlazada.3) Capi tulo XVIII: Tipos y Estructuras de Datos Inserción Al Final de la Lista: Paso 1: Recorremos la lista hasta el elemento último con un iterador q.readLine).. } } Veámoslo en Java con el ejemplo de insertar STRINGS a la lista: // La lista esta vacıa Nodo cabeza = null.sgte = cabeza.out. // Creamos el nodo con su nombre Nodo p = new Nodo(in. } else { // Lista vacıa cabeza = p. // Ingreso de nombres: while(true) { System. // Creamos el nodo con su nombre Nodo p = new Nodo(in.sgte. Veamos gráficamente cómo se insertan en los siguientes 2 casos: Ummm. } Pero esta solo es una forma de insertar un nuevo Nodo a una lista enlazada. cabeza X Info Info Info p X Veamos como se implementan estas líneas en lenguaje Java con el mismo ejemplo anterior: // La lista esta vacıa Nodo cabeza = null. // Luego lo ponemos en la lista if (q != null) { q.sgte = p. Se puede ver que este caso es un poco más complejo que el de insertar al inicio de la lista. // Luego lo ponemos en la lista p. p cabeza X Info Info Java: del Grano a su Mesa (Versio n 1. Inserción al Inicio de la Lista: Veamos gráficamente cómo funciona este caso: Paso 1: Creamos un nuevo NODO y lo apuntamos por p.out. en medio y al final. Pero veámoslo de verdad cómo funcionan.Java: del Grano a su Mesa (Versio n 1.sgte != null) q = q. p X cabeza Info Info Paso 3: Apuntamos el siguiente de q a lo que apunta el p.readLine). cabeza Info Info q p X Paso 2: Apuntamos el siguiente de p a lo que apunta la cabeza. En general existen 3 casos de cómo insertar un elemento: Al inicio de la lista (lo visto anteriormente). // Iteramos hasta que llegamos al final Nodo q = cabeza while (q != null && q. cabeza = p. pero se asemeja más al caso general que viene en seguida: 185 186 . cabeza Info Paso 3: Permitimos que la cabeza ahora referencie como primer elemento de la lista a p.print (”Nombre? ”). cabeza Info Info q Paso 2: Creamos un nuevo NODO y lo apuntamos por p.

sgte. // Iteramos hasta que llegamos al punto de insercion Veamos como se implementan estas líneas en lenguaje Java con el mismo ejemplo anterior: Nodo p = cabeza. p = null.sigte. cabeza = p. cabeza X Info Info Paso 4: Apuntamos el siguiente de q a lo que apunta p. cabeza Info Info Veamos como se implementan estas líneas en lenguaje Java con el mismo ejemplo anterior: // La lista esta vacıa Nodo cabeza = null. cabeza Info p X Info q Info Nos falta ver como eliminar de una lista enlazada en sus 3 casos también.readLine).Java: del Grano a su Mesa (Versio n 1. // Creamos el nodo con su nombre Nodo p = new Nodo(in.sgte = q. } } Paso 2: Creamos un nuevo NODO y lo apuntamos por p. } else { // Lista vacıa cabeza = p. cabeza Info p X p Info q Info p X Info Info Paso 2: Apuntamos la cabeza de la lista al siguiente de p. Eliminación Al Inicio de la Lista: Paso 1: Apuntamos p a la cabeza de la lista.print (”Nombre? ”). En general se puede o no hacer el null para liberar la variable ya que Java posee un Garbage Collector que limpia cada cierto tiempo la memoria de variables que apuntan a nada.sgte.out. q. // Luego lo ponemos en la lista if (q != null) { p.sgte = p.3) Capi tulo XVIII: Tipos y Estructuras de Datos Nodo q = cabeza while (q != null && <condicion de insercion>) q = q. cabeza Info Info q X p Info Paso 3: Se destruye lo apuntado por p. cabeza Info Info q Info Java: del Grano a su Mesa (Versio n 1.3) Capi tulo XVIII: Tipos y Estructuras de Datos Inserción En Medio de la Lista: Paso 1: Recorremos la lista hasta antes de la posición donde debe ir con un iterador q. // Ingreso de nombres: while(true) { System. cabeza Paso 3: Apuntamos el siguiente de p a lo que apunta el siguiente de q. 187 188 .

while(p != null && p. } else if (p != null) { // Es el primero o el ultimo if (p == cabeza) { cabeza = p. Hay que tener cuidado con los casos de borde (primero y último elemento): Nodo p = cabeza.sgte.sgte != null && CONDICION PARA ENCONTRARLO) { p = p.sgte.sgte = null. } Veamos como se implementan estas líneas en lenguaje Java con el mismo ejemplo anterior. cabeza Info Info Veamos como se implementan estas líneas en lenguaje Java con el mismo ejemp lo anterior: Nodo p = cabeza. cabeza Info Info Info Info Paso 3: Se destruye solito el nodo (por el GC 21). } if (p != null && p.sgte = null. 21 Esta definición bastante rara es una forma genérica con la cual se definen los árboles. } else if (p != null) { // Es el unico caso especial cabeza = null.3) Capi tulo XVIII: Tipos y Estructuras de Datos Java: del Grano a su Mesa (Versio n 1.sgte != null) { p. } } Árboles Arbol: Estructura de datos que permite almacenar información y organizarla de tal forma que tengas sucesores o elementos siguientes como hijos en forma de ramas de un árbol. cabeza Info p Info X Paso 2: Apuntamos el siguiente de p al siguiente del siguiente de p.sgte.3) Capi tulo XVIII: Tipos y Estructuras de Datos Eliminación En Medio de la Lista: Eliminación Al Final de la Lista: Paso 1: Apuntamos p al anterior del elemento de la lista a eliminar. while(p != null && p. } if (p != null && p.sgte. Garbage Collector: Se preocupa de limpiar la memoria inútil del computador convirtiéndola en memoria útil. Paso 1: Apuntamos p al penúltimo elemento de la lista.Java: del Grano a su Mesa (Versio n 1.sgte != null) { p = p.sgte. } else { p.sgte = p.sgte.sgte != null) { p.sgte != null && p. cabeza Info p Info X cabeza Info p Info X Info Paso 2: Apuntamos la cabeza de la lista al siguiente de p. cabeza Info p Info X Paso 3: Se destruye solito el nodo (por el GC). 189 190 .

der = null. HOJAS del árbol son todos aquellos nodos que estén dentro del árbol pero que NO tengan ningún hijo. se inserta.der = p. 5 5 5 5 3 3 9 3 9 8 Vemos rápidamente que TODO lo que está a la derecha es mayor a 5 y lo que está a la izquierda es menor a 5.. es decir. else q = q. 9 y 8. El árbol binario es una clase especial de árboles genéricos que solo posee 2 hijos. Nodo f = null. pues este “enlace” se hace a nodos que no son “correlativos”. this. 3.raiz = p.raiz = null. public Nodo(int o) { this. 2. uno izquierdo y otro derecho. de entre los cuales mencionaremos los más comunes. } if (f == null) this. y los hijos derecho son siempre MAYORES que el nodo que los contiene. veamos gráficamente como quedaría un árbol si vamos leyendo los datos en el siguiente orden: 5. n hijos. 4.3) Capi tulo XVIII: Tipos y Estructuras de Datos // Version iterativa del insertar public void insertar(int x) { Nodo p = new Nodo(x). Árboles Binarios: Son árboles que poseen 2 nodos hijos. Como podemos ver. Preguntar si donde estoy va. la representación del Nodo es igual a la representación de una lista doblemente enlazada.der.info > x) q = q. if (q.info > x) f.izq = null. der. 6 y 4.info = o. Pues bien. Por ejemplo. this. while (q != null) { f = q. NODO INTERNO son todos aquellos nodos que no son ni raíz ni hojas. Intenta completar esto metiendo los número 2. public Arbol() { this.Java: del Grano a su Mesa (Versio n 1. lo que va haciendo en su forma general es: 1. es decir. pero no es limitante. Los hijos izquierdos son los nodos menores al intervalo.izq = p. es decir. Nodo q = this.. ALTURA es la cantidad de nodos que hay que recorrer para llegar desde la raíz del árbol hasta la hoja más alejada de la raíz. Si va. public Nodo izq. usemos árboles con número que cumplan la siguiente propiedad: • • Cada nodo almacenada la información de un intervalo de enteros. la “cabeza” del árbol siempre será la raíz. La diferencia está en el momento de realizar el enlace. Si no va. 3. con 2. Árboles Genéricos: Son árboles que pueden tener un número de hijos no definidos.raiz. else { if (f. } 191 192 . También se define como la máxima distancia que hay entra la raíz y todas las hojas del árbol. } } Java: del Grano a su Mesa (Versio n 1. Un ejemplo de árbol puede ser aquél que va almacenando número enteros dependiendo del orden de ingreso de los valores (no requiere se ordenado como los arreglos o las listas): class Nodo { public int info.3) Capi tulo XVIII: Tipos y Estructuras de Datos Algunas definiciones útiles para comprender la nomenclatura es: RAIZ es el primer nodo del árbol y es por donde se accede a él. 7. } } } Si analizamos el insertar.izq. Existen varios tipos de árboles. 3. se busca por el lado en que debería ir El insertar visto aquí es solo un ejemplo para entender cómo se va llenando el árbol. else f. los hijos izquierdo son siempre MENORES que el nodo. En general se utilizan para indicar orden dentro de los elementos del árbol. Implementemos el problema de insertar números ordenadamente: class Arbol { protected Nodo raiz.

der. public Nodo izq. el número de hijos es variable. 2 3 8 10 // Recuerda que el tipo puede cambiar // Los nodos hijos Como podemos ver en el ejemplo. Así que los árboles permiten ir seleccionando un Nodo (un estado) que indica la posición del tablero. es: // Creacion del nuevo nodo Nodo p = new Nodo(x). para insertar en el árbol.info > p. Es por eso que utilizan profundidad y evalúan la mejor jugada según un mini-árbol de altura n con el cual puede jugar. else { // Si en f tenemos una hoja if (f. Los hijos centrales son los nodos que están dentro del intervalo. Pero esto árboles ya son difíciles de trabajar.info) // Si va a la izquierda de la hoja (f) 193 194 . Los hijos derechos son nodos mayores al intervalo. // Inicio del recorrido del arbol hasta el lugar (f) donde va. y es mucho en un juego de ajedrez. Y ¿para qué sirven estos árboles? En el fondo.raiz. else // Criterio para que vaya por la derecha q = q.izq. } // Insercion if (f == null) // Si es la raız del arbol (arbol vacıo) this.raiz = p.Java: del Grano a su Mesa (Versio n 1. Nodo q = this.3) Capi tulo XVIII: Tipos y Estructuras de Datos Es decir: Primera Decisión Entonces. un árbol como este quedaría así: 2 5 Profundidad 2 Posibles Jugadas -1 0 1 3 3 4 5 9 12 13 ¿Interesante no?. this.der. Propuesto: Implemente el tipo Nodo que permita crear este tipo de árboles.3) Capi tulo XVIII: Tipos y Estructuras de Datos • • • • Los hijos izquierdo-centrales son nodos que intersectan el intervalo por la izquierda. Definiremos entonces un Nodo para un árbol binario de la siguiente forma: class Nodo { public Object info. ¿pero eso significaría que el computador siempre sabe cómo ganar? Por supuesto que no. o tal vez un criterio de decisión de cuál va a la derecha o izquierda de otro. Estas posiciones pueden ser MILLONES y sería bastante difícil realizar una búsqueda en un arreglo o listas de millones de datos para encontrar la mejor movida. if (q. Entonces.der = null. esto le tomaría a la computadora más rápida unos días.info = o. las hojas del árbol de decisión son los posibles términos del juego. Los hijos derecho-centrales son nodos que intersectan el intervalo por la derecha. } public Nodo(int o) { // Constructor para crear un nodo this. this. ya que si analizara el camino más corto para llegar a una hoja. en su forma genérica.izq = null. por lo que nos centraremos en los árboles binarios como nuestra nueva estructura de datos. ¡Hey!. lo que hace un computador con un juego de ajedrez es analizar una serie de movidas prefabricadas dependiendo de la posición en la que se encuentre el tablero.info > p. Además. Nodo f = null. Java: del Grano a su Mesa (Versio n 1. pero entre 0 y 5.info)// Criterio para que vaya por la izquierda q = q. } Esta forma básica cumple con lo mínimo que es necesario para tener un nodo de árbol. por lo que se le puede agregar cosas como que sean comparables. while (q != null) { f = q. y sus Hijos (que pueden ser muchos) que representan las posibles movidas que tiene el computador en ese momento.

Comparar el 7 con el nodo de la derecha de la raíz (9). // Luego se pone el lado derecho. malo. // Se guardan los hijos del que vamos a eliminar Nodo qi = q. ¡OJO QUE QUEDA PENDIENTE BORRAR LA RAIZ! (Propuesto). Veamos un ejemplo: Dado el siguiente árbol: Buscar el número 7 costaría solo pasar por 3 nodos: 1. Pero si vamos al caso del 11.info <> x) { f = q. Nodo f = null. Comparar el 7 con el nodo de la izquierda de (9).. Malo. } if (hi != null) // Si existe la rama izquierda hi. y en la lista enlazada 6 nodos. if (q. Como es menor. } // Eliminamos if (q != null) { // Si fuera null. Esta versión iterativa de la inserción se basa en que los nodos son valores comparables como los números. // Se elige cual de los dos va a colgar del padre de q // En este caso elegiremos el arbol derecho pero // Podrıa haber sido al reves. es bastante sencillo insertar. // Guardaremos el padre del que vamos a elimina r.izq.izq.info)// Criterio para que vaya por la izquierda q = q. Veamos todos los casos: // Recorrido para encontrar el valor x Nodo q = raiz. 2 9 4 2. while(q != null && q. el tamaño de la lista.Java: del Grano a su Mesa (Versio n 1. Nodo r = qd. Pero ¿a qué se refiere con “ordenado”?. en la hoja mas a // la izquierda de qd. Ahora bien. sin embargo. el problema viene cuando hay que eliminar.info > p. en el árbol nos cuesta 3 nodos. Veamos como quedaría el algoritmo de búsqueda de un nodo en un árbol ABB: // Suponemos x como valor para buscar // Para recorrer Nodo q = raiz while (q != null if (q. Nodo hi = null. } Menor que Mayor que Esto permite que las búsquedas se reduzcan bastante. ¡BINGO! 7 11 8 Si lo hubiésemos dispuesto en una lista enlazada.izq = qi. malo.izq. que no permiten duplicados y que sirven para realizar búsquedas en un tiempo O(Log n) en un conjunto de datos “ordenados”. ya que en el caso promedio NO se debe recorrer el árbol completo para encontrar el valor buscado. Pero es fácil transformarlo para que funcione con otros tipos de datos. significa que no esta.info q = else q = && q. nos iremos por la derecha. } // Si va a la derecha de la hoja (f) Java: del Grano a su Mesa (Versio n 1.izq = p.3) Capi tulo XVIII: Tipos y Estructuras de Datos Gran parte de la utilidad de los árboles binarios y en especial de los ABB es que los nodos que se van insertando en el árbol. ésta quedaría ordena da de la siguiente forma: 2-4-7-8-9-11. q. Como es mayor. La condición de que un árbol sea ABB es que el subárbol hijo izquierdo es siempre MENOR que el nodo y el sub-árbol hijo derecho es siempre MAYOR que el nodo.der. 195 196 . siempre van quedando en forma “ordenada”.izq. r = r. Árboles de Búsqueda Binaria: Los árboles de búsqueda binaria (ABB) son aquellos que sus hijos cumplen una condición de orden con sus padres. es decir.der. else f.der.. Como es el 7. Comparar el 7 con la raíz del árbol (4). porque si eliminamos un nodo interno ¿qué hacemos con sus hijos?. while(r != null) { hi = r. Nodo qd = q.info <> x) { > x) q. else // Criterio para que vaya por la derecha q = q. nos vamos por la izquierda. 3. Casualmente es la misma cantidad de nodos.der = p.3) Capi tulo XVIII: Tipos y Estructuras de Datos f. f = qd. else f = qi.

length() > 0) { 197 198 .info = x. retorna null.. else q = q. p. } // Insercion del nuevo nodo if (f == null) this.7 Ingrese valor? ú1 Ingrese valor? 8.info) q = q. Para ello debe imitar el diálogo: Ingrese valor? 3. p. public Nodo eliminar (double x) { // PENDIENTE } // Para buscar un valor x en el arbol // Sera semi-recursivo public Nodo buscar (double x) { return buscar(x. // Se busca donde va el nuevo nodo Nodo q = this.der). while (q != null) { f = q.der. } private Nodo buscar (double x.Java: del Grano a su Mesa (Versio n 1. // Ingresamos los valores System. public Nodo (double x) { this.print(”Ingrese Lectura?á). else f.raiz = p.3) Capi tulo XVIII: Tipos y Estructuras de Datos } if (q == null) // NO LO ENCONTRAMOS else // LO ENCONTRAMOS y esta en q Java: del Grano a su Mesa (Versio n 1.info == x) return p.5 Lectura encontrada!! La solución sería bastante sencilla (main): public class Lecturas { public static BufferedReader bf = new BufferedReader( new InputStreamReader(System.out. Nodo p) { // Casos base if (p == null) return null. else return buscar(x. Ahora veamos una representación de árbol con las 3 operaciones básicas: Insertar un elemento. public ABB() { this.info > x) return buscar(x. // En caso de no encontrarlo. // No esta if (p.2 .7 No esta la lectura!! Buscar Lectura? ú3. ya que lo único que hace es ir decidiendo que rama coger para continuar la búsqueda. // Lo encontramos // Paso recursivo if (p.. Ingrese valor? (SOLO ENTER) . public Nodo izq.info > p. // Inicializa el arbol de busqueda binaria.raiz = null.izq = p. } } // Para eliminar un valor x del arbol. this.der = p. public void insertar (double x) { // Creacion del nuevo nodo Nodo p = new Nodo(x).. } // Para insert