Está en la página 1de 387
ao ClO Java 7 Sea rca Ceea tie Rica Peat oe en at Cereus Dictate Narre oe eee cen Incas Nee ree ecw) enfoque actual, a través de la Perea eit) PIP cake eeeate tie eres ene Ruud OMT eect ea kG acto ee eee atic 1) Cee erie Re tt anmery Oca icc) Peataeecn eran Bee eee ceric variedad de ejemplos practicos, Pree tet ete an aca er eeu na Ete ees ace! Ponte our AOR eri ac) e Pee Cold MARK ALLEN WEISS (eerie nee BPAY. Caracteristicas Ce eu ered Cee ame rake ac) entidad, cuyo cédigo original Peer eit euler NE Rc) y revisado por un programador cael eae tes MEE) eer Mec enue e Ce Seca m rien amen ted Pearce eek AUC} (ue See a ecu PCS ie ue cca BeOS cae acs? al final de cada capitulo para Peg teu eid es eee ete set iy eee ee es cuces asec ae entre los distintos capitulos. Nea COMM ele Me Mae Runa Cur University. Se doctoré en Ciencias de la Computacién en la Universidad de eee ae en RR eeu eel om eee les PCE restated catch aru cect Peer ace mane iis ie kt Cuca R Ck Ol ie lenguajes estructurados mas modernos, que se ha materializado en diversos —__ Secrets ER Met erage RSet a eae kel) ER hee Ce ie eit ea eee ee Reem eee eee TSBN a4 035-4 9 il il bere ESO NN Secon A Contenido Prélogo | ce . _ . XIX Un enfoque novedoso. were: “: ns wae XX Prerrequisitos.... cone 2 — XX Java.. . ce 7 ce = ‘XXI Organizacién del libro: —e . a ee XXII Organizacién del libro por capitulos........ suanmeeewe XXII Dependencias entre capitulos . woe ce . XXIV Partes independientes xe - — 2 XXIV Fundamentos matemiaticos ae ane ws . XXV Organizacién del curso....... XXV Ejercicios ne XXVI Detalles pedadégice . XXVI Disponibilidad del cédigo.. eons XXVL Gufa del profesor 0 eonaitiniitss., SOMME Agradecimientos . XXVIT Prélogo a la edicién en espafiol...... a wees XXIX, PRIMERA PARTE Un recorrido por Java 1. Java bésico. 3 1.2. El primer programa 5 1.2.1. Comentarios 5 1.2.2. main a e 6 Le Salida por pantalla 6 1.3.1. Los tipos primitivos . 6 1.3.3, Declaracidn e inicializacin de tipos primitivos .... z 1.3.4. Entrada y salida por terminal 8 a 1.4. Operadores basicos... ‘ 8 1.4.1. Operadores de asignacién 8 1.4.2, Operadores aritméticos binarios 9 1.4.3. Operadores unarios. 10 14.4. Conversiones de tipo o 10 1.5, _Instrucciones condicionales.. 1.5.1. Operadores relacionales y de igualdad u 15.2, Operadores l6gicos ul 15.3. La instruccién i£ 12 15.4. La instruccién white 13 155. La instruccién for. Fete nes ae 1.56. La instruccién do... TERRES . 15 15.7. break y continue... . i 15 1.5.8. La instrucein switch Fe — 16 1.5.9. El operador condicional ce ee _ - 17 1.6. Métodos 18 1.6.1. Sobrecarga de los nombres de los métodos . . 18 1.6.2. Clases de almacenamiento o cnn Fipiaeean 19) Resumen...... ce 19 Elementos del juego sexepuaistie - croncares OO) Errores comunes...... ss ce . nnmmacieess Bl En Internet 2 Ejercicios. 2 Bibliografia.... 2 4 2. Referencias 25 2.1, Qué es una referencia?.... 25 2.2. Nociones bisicas sobre objetos y referencias. 1 2.2.1, El operador punto (.) 28 2.2.2. Declaracién de objeto: 28 2.2.3, Recogida de basura 29 2.24. El significado de =........ 29 2.2.5. Paso de parémetros . 30 2.2.6. El significado di 31 2.2.7. Sobrecarga de operadores para objetos 31 2.3. Cadenas de caracteres . ce 31 2.3.1. Conceptos bisicos de la manipulacién de Strings... 32 2.3.2. Concatenacién de cadenas 32 2.3.3. Comparando cadenas......... ‘ sts le 33 2.34. Otros métodos del tipo String... . gczateroeats! 38 2.3.5. Conversidn entre cadenas y tipos primitivos.............. cee BB 24. Vectores. . 34 24.1. Declaraci6n, asignacin y métodos. 4 2.4.2. Expansién dinémica de vectores 36 24.3. Vectores multidimensionales .... 3 sities cia? 37 2.4.4. Argumentos de la linea de comandos. r 39 2.5. Manejo de excepciones 39 2.5.1. Procesamiento de excepciones. 39 2. La cléusula finally... 2.5.3. Excepciones mas comunes 4, Las cléusulas throw y throws .. 2.6. Entrada y salida.. 26.1. Operaciones bisicas de E/S 2.6.2. El objeto StringTokenizer.... 2.6.3. Ficheros de acceso secuencial .. Resumen Elementos del juego Errores_comunes En Internet... Ejercicios z Referencias seimewsrenarnaense Objetos y clases SI 3.1, {Qué es la programacién orientada a objetos? si 3.2. Un ejemplo sencillo 33 3.3. Javadoc : 34 34, Métodos 37 3.4.1, Constructores " 37 3.4.2. Métodos modificadores y de acceso 37 34.3. Salida y toString... cece cecceesseceseteetesesesseeeseeees 58 344. equals... 58 3.4.5. Métodos static....... 59 3.46. main.. 60 3.5. Paquetes 60 3.5.1, La directiva import 60 3.5.2. La instrucci6n package 61 3.5.3. La variable de entorno CLASSPATH. nei 62 3.54, Reglas de visibifidad amistosa dentro de un paquete 63 5. Compilacién separada 64 3.6. Construcciones adicionales 64 3.6.1, La referencia this. 64 3.62. La abreviatura this para constructores. 65 3.6.3. El operador instanceof . ha 65 3.6.4. Atributos estaticos... i 65 3.6.5. Inicializadores. estéticos 66 Resumen 67 Elementos del juego 68 Errores_ comunes 69 En Internet... 69 Ejercicios 70 Bibliogratia 1 Retenclalsa2 gcncsarvras mere eee us B 4.1. (Qué es la herencia? 3 4.2. Sintaxis basica de Java...... . . ‘caendectbitin a 76 4.2.1, Realas de visibilidad Tec RETR lscaeaa eee 16 4.2.2. El constructor y super 4.2.3, Métodos y clases finales .... 4.2.4. Sobreescribiendo un método 4.2.5. Métodos y clases abstractos 4.3. Ejemplo: extensidn de la clase Figura...... 4.3.1. Disgresién: una introducci6n a ta ordenacién... 44. Herencia miltiple 45. El interfaz revere 4.5.1. Especificacién de una interfaz 4.5.2. Implementacién de una interfaz 4.5.3. Varios inferfaces....... 4.6. Implementacién de componentes genéricas. Resumen... Seance ei Elementos del juego..... vee Errores_ comunes En Internet Ejercicios......, Bibliografia.... SEGUNDA PARTE Algoritmos y fundamentos de programacién Analisis de algoritmos 5.1. {Qué es el andlisis de algoritmos? 5.2. Ejemplos de tiempo de ejecucién de algoritmos 5.3. El problema de la subsecuencia de suma maxima 5.3.1. El algoritmo O(N‘) obvio 5.3.2. Un algoritmo mejorado O( 5.33. Un algoritmo lineal 54, Reglas generales para la notacién O 5.5. Logaritmos 5.6. Problema de la bisqueda estética 5.6.1, Buisqueda secuencial 5.6.2, Baisqueda binaria 5.6.3, Buisqueda interpolada... 5.7. Comprobar el andlisis de un algoritmo cis 5.8. Limitaciones del andlisis 0 eae zi Resumen - Elementos del juego......... on RoR 7 Errores comunes. En Internet Ejercicios. Bibliografia Estructuras de datos 6.1. {Por qué necesitamos estructuras de datos? . 6.2. Las pilas 6.2.1. Las pilas y los lenguajes de programacién... 7. 8. 63. Las colas . 6.4. Listas enlazadas 6.5. Arboles generales sepazn 6.6. Arboles binarios de biisqueda........ 6.7. Tablas hash 6.8. Colas de prioridad Resumen... spat SEEREBIRES . Elementos del juego... Errores_ comunes pounce Eli INCRE cercecearversvexsnananaeta Ejercicios Bibliografia Recursion...... eens ensisSSRTEHER TA. (Qué es la recursién?. 7.2. Fundamentos: demostraciones por indu 7.3. Recursién basica oe . 73.1, Impresién de ntimeros en cualquier base we 7.3.2. (Por qué funciona? .........606+ 7 7.3.3. Cémo funciona na 7.34. Demasiada recursi6n puede ser pairs 8 7.3.5. Ejemplos adicionales 74. Aplicaciones numéricas 74.1. Aritmética modular... 7.4.2. Exponenciacin modular : 7.4.3, Maximo comiin divisor ¢ inversos multiplicativos . 7.4.4. Bl sistema de criptografia RSA 7.5. Algoritmos divide y vencerds 7.5.1. El problema de la subsecuencia de suma méxima... 7.5.2. Anilisis de un algoritmo divide y vencerés sencillo 1 Uina cota superior general para los tiempos de ejecucidn de fos algoritmos di- vide y venceris 7.6. Programacién dinémica 7.1. Algoritmos de vuelta atris Resumen Elementos del juego Errores. comunes En Internet Ejercicios. : Bibliograffa Algoritmos de ordenacién 8.1. {Por qué es importante la ordenacién? 8.2. Preliminares. 83. Andlisis de la ordenaci6n por insercin y otras ordenaciones simples. 8.4, Shellsort.. 8.4.1. Rendimiento de Shellson 165 165 166 170 170 172 174 175 176 180 181 181 183 185 188 188 190 195 197 201 205 205 206 207 207 2u 213 213 215 215 217 219 10. 8.5. Mergesort 8.5.1. Mezela lineal de vectores ordenados.. 8.5.2. El algoritmo mergesort 8.6. Quicksort 5 8.6.1. El algoritmo quicksort 8.6.2. Andlisis de quicksort.. 8.6.3. Seleccionando el pivote. 8.6.4. Estrategia de particién 8.6.5. Elements iguales al pivote 8.6.6. Particién con Ia mediana de tres 8.6.7. Vectotes _pequefios... 8.6.8. Rutina de quicksort en Java 8.7. Seleccién répida..... 88. Una cola inferior para la ordenacién Resumen... Elementos del juego... Errores comunes. sesame — En Internet ea — = . Ejercicios.... Bibliografia Nameros aleatorios 249, 9.1. {Por qué son necesarios los ntimeros aleatorios? . coe 249 9.2. Generadores de niimeros aleatorios 2 9.3. Niimeros aleatorios no uniformes....... 9.4. Generacién de una permutaci6n aleatoria 9.5. Algoritmos aleatorios... i oman 9.6. Test aleatorio de primalidad. Resumen - Elementos del juego. Errores comunes En Internet... Ejercicios Bibliografia.... TERCERA PARTE Aplicaciones Juegos y diversién 23 10.1. Sopas de letras a : foe 2B 10.1.1. Teorfa.. . womens 10TH 10.1.2. Implementacién en Java oxragy, 276 10.2. El juego de las tres en raya 281 10.2.1. Poda alfa-beta. ... 281 10.2.2, Tablas de transposicién 282 10.3. El ajedrez 285 Resumen . 287 Elementos del juego 287 12. 13. Errores comunes.. En Internet . Ejercicios Bibliografia Las pilas y los compiladores ............2.....202- 11.1, Anatizador de simbolos equilibrados 11.1.1, El algoritmo basico 11.1.2. Implementacién 11.2. Una calculadora sencilla 11.2.1, Méquinas postfijas 11.2.2. Conversién de notacién infija a posttija 11.2.3, Implementacién 11.2.4, Arboles sintécticos de expresiones.. Resumen... Elementos del juego Enrorescomunes. vo En Internet... ee Ejercicios Bibliografia. . Utilidades . 12.1, Compresién de ficheros 12.1.1. Cédigos sin prefijos. 12.1.2. Algoritmo de Huffman... 12.1.3. La fase de codificaci6n.. 12.1.4, La fase de decodificacién 12.1.5. Consideraciones précticas 12.2. Generador de referencias cruzadas. 12.2.1, Tdeas bisicas .... 122.2. Implementacién en Java Resumen... Elementos del juego Errorescomunes. En Internet Ejercicios Bibliograffa.... Simulacién 13.1. El problema Josephus 13.1.1. La soluci6n simple....... 13.1.2. Un algoritmo mis eficiente 13.2. Simulacién dirigida por eventos. 13.2.1. Ideas basicas 13.2.2. Bernt: simulacién de un banco de médems . Resumen Elementos del juego - 15. 16. Errores comunes. En Internet Ejercicios.. Grafos y caminos 14.1. Defin : 14.1.1. Representacin 14.2. Problema del camino minimo sin pesos. 142.1. Teorfa 14.2.2. Implementacién en Java. 14.3. Problema de los caminos minimos con pesos positivos. 143.1, Teorfa: algoritmo de Dijkstra...... 143.2. Implementaci6n en Java 3 te 14.4. Problema del camino minimo con costes negativos...- 14.4.1. Teorfa 144.2. Implementacién en Java 14.5. Problemas de caminos en grafos aci 14.5.1, Ordenaci6n topoldgica . I Teoria del algoritmo de caminos minimos con un grafo acielico 14.5.3. Implementaci6n en Java 1454. Una uplicacién: anilisis de caminos eriticos.. Resumen... Elementos del juego. Errores comunes..... En Internet...... Ejercicios . fe [BIB grat en-aumneawsicsanicurceveri Seen, (CUARTA PARTE Implementaciones Plas y COO ie recrssnsanenemsconens soanttnizialc ceceeeee 395 15.1. Implementacién dinémica de vectores .. 15.1. Pilas . 15.1.2. Colas 15.2. Implementaciones con listas enlazadas 15.2.1. Pilas 15.2.2. Colas 153. Comparacién de los dos métodos. 15.4, Colas dobles Resumen “ Elementos del juego. Errores comunes 412 En Internet a 413 Ejercicios..... nn 13 Listas enlazadas 4s 16.1. Ideas basicas..... 4s 6.1.1. Nodos cabecera.. ' . 417 7. 18. 16.2. 16.3. 164. 16.1.2, Implementacién en Java... Listas doblemente enlazadas y listas enlazdas circulares. Listas enlazadas ordenadas Resumen Elementos del juego... Errores comunes En Internet.....- Ejercicios Clases iteradoras generales.... Definiciones Implementacién . Una aplicacié: binarios. y recursi6n Recorrido de arboles: clases iteradoras .. Arboles... 17.1, Arboles 11d 171.2. 17.13. 17.2. Arboles 17.3. Arboles 174, 174.1 17.4.2. 17.43. 1744. Resumen Elementos del juego Errores. comunes En Internet Ejercicios... Recorrido en postorden - Recorrido en orden simétrico Recorrido en preorden....... Recorrido por niveles Arboles binarios de busqueda 18.1 18.2. 18.3, 184. 18.5. 18.6. Ideas bisicas..... 18.1.1 18.1.2. Baisqueda por posicis 18.2.1 Analisis de las operaciones de los arbotes binarios de basqueda Las operaciones. Implementacién en Java. n en el orden. Implementacién en Java. Arboles AVL 18.4.1. Propiedades 18.4.2. Rotacién simple 18.4.3. Rotacién doble 18.4.4. Resumen de la insereién enun frbol AVL Arboles. rojinegros 18.5.1, Insercién ascendente . 18.5.2. Arboles rojinegros descendentes 18.5.3. Implementaci6n en Java... 18.5.4. Eliminacién descendente AA-Arboles .. 18.6.1. Insercién 18.6.2. Eliminacién 418 419 426 428 430 431 431 431 432 435 435 435 437 437 441 448. 450 453 457 458 459 461 461 462 462 463 467 467 468 470 477 477 481 484 485 487 490 492 493 495 497 503 505 506 509 19. 20. 18.6.3. Implementacién en Java.........cccececeeeeeee 509 18.7. B-Arboles “. 2 walt L 512 Resumen 7 : 519 Elementos del “juego . . La . eee 520 Errores comunes .. 521 En Internet . eee sees wai 521 Ejercicios — a sine S22 Bibliogratia 524 Tablas hash... 19.1. Ideas basicas 19.2. Funcién de localizacién. 19.3. Exploracién lineal 19.3.1. Anilisis de la exploraci6n lineal .. 19.3.2. Lo que sucede realmente: la agrupacién primaria 19.3.3. Analisis de la operacién buscar 19.4. Exploracién cuadratica 19.4.1. Implementacién en Java... 19.4.2. Anilisis de In exploracién cuadrética 19.5. Hashing enlazado Resumen Elementos del juego... Errores comunes.. En Internet Ejercicios.. Bibliogratta Una cola de prioridad: el monticulo 553 20.1. Ideas basieas 553 20.1.1. Propiedad estructural st 554, 20.1.2. Propiedad de ordenacién de los monticulos. 555 20.1.3. Operaciones permitidas. ‘ 556 20.2. Implementacién de las operaciones baSiCaS............2.00 = srs 559 20.2.1, insertar . 559 20.2.2. eliminarMin = 562 203, arregLartonticulo: construccién en tiempo lineal del monticulo S64 20.4. Operaciones avanzadas: reducirClave y mezclar. nse 568 20.5. Ordenacién interna: método del monticulo . - 568 20.6. Ordenacién externa... - tease sil 20.6.1. Por qué necesitamos nuevos algoritmos 2.0.2... asda 572 20.6.2. Modelo de ordenacién externa... : - 52 20.6.3, El algoritmo sencillo.. 572 20.64. Mercla multiaria arenes cols nates STE 20.6.5. Mezcla multifase exdtcticdadst ex OS 20.6.6. Selecci6n del reemplazo............. Bid oo . 516 Resumen... cece ceceeeee coe . TEN AM STS Elementos del juego. . eats ee 578 Errores comunes BBs 579 21. 22. 23. En Internet Ejercicios vies 3 < Bibliografia. .. . Tas QUINTA PARTE Estructuras de datos avanzadas Arboles de ensanchamiento...... aa cosas weaned 21.1. Auto-ajustamiento y anélisis amortizado . 21.1.1. Cotas de tiempo amortizadas 311.2 Una estrategia simple de auto-ajustamiento (que no funciona) 21.2. Arboles bisicos de ensanchamiento ascendente . 21.3. Operaciones basicas de los drboles de ensanchamiento........ i 21.4. Analisis del ensanchamiento ascendente .. 21.4.1. Demostracién de fa cota de ensanchamiento 21.5, Arboles de ensanchamiento descendent 21.6. Implementacién de los drboles con ensanchamiento descendente 2U7 Comparaciones de los arboles de ensanchamiento con otros drboles de bisqueda.. Resumen . Elementos del juego. Errores_comunes En Internet..........+ Ejercicios....... were Bibliografia. Colas de prioridad con mezcla.. 22.1. Los monticulos sesgados 22.1.1. La mezcla es importante 22.12, Mezcla simple de drboles con ordenacién de monticulos 22.1.3. El monticulo sesgado: una modificaci6n sencilla. 22.1.4. Analisis del monticulo sesgado... 22.2. Los monticulos de emparejamientos . 22.2.1. Operaciones del monticulo de emparejamientos y teoria. 22.2.2. Implementacién del monticulo de emparejamientos. 22.2.3. Aplicacion: el algoritmo de Dijkstra para la obtencién de caminos minimos. Resumen Elementos del juego Errores_ comunes En Internet... Ejercicios.. Bibliografia Estructura de particién 23.1. Relaciones de equivalencia .. 23.2. Equivalencia dinamicas y dos aplica 23.2.1. Aplicacién #1: arboles de recubrimiento minimo : 332.2, Aplicacién #2: el problema del antecesor comiin ms prOximo.- 579 580 583 587 587 588 589 591 593 594 597 613 613 613 614 615 616 618 618 620 626 629 629 630 630 630 631 633 633 634 635 637 V—— 233. El algoritmo de bisqueda répida.... 23.4, El algoritmo de unién répida 23.4.1. Algoritmos de unién inteligentes . 23.4.2. Compresién de caminos 23.5. Implementacién en Java. . Caso peor de la unién por rango y la compresién de caminos 23.6.1. Resumen Analisis del algoritmo unir/buscar. Elementos del juego Errores comunes. En Internet, Ejercicios.... Bibliografia APENDICES A. Plataformas para Java... A.l. Estableciendo el entorno. ALL Al2, Instrucciones para Unix Instrucciones para Windows95/NT..... A2. IDK de Sun A3. Entomos de desarrollo visual ABL. A32. B. Operadores... Symantec Café... Microsoft Visual J+ + CC. Algunas rutinas de librerias C.l. Clases del paquete java.lang CLI. Character C12. Integer. 5 C13. object C14. string C15. StringBuffer. C16. system C7. Thread. ‘ C18. Throwable C2. Clases del paquete java.io C.2.1, BufferedReader C22, File... C23. PileReader. C24. InputStreanReader C25. PushbackReader C3. Clases del paquete java.util C31. Random... C32. stringTokenizer C33. vector En Internet... 641 642 643 645 647 648 649 654 655 656 656 656 658 663 663 663 664 665 667 671 679 681 681 681 682 683 684 685 687 688 689 689 689 690 691 691 691 692 692 693 694 694 D. Interfaces gréficas de usuario. ... Dl. El Abstract Window Toolkit D2. Elementos bisicos del AWT D.2.1, Component D22. container D23. Ventanas de alto nivel.. D24. Panel D.25. Componentes importantes de la E/S. D3. Principios basicos del AWT 3.1. Configuraciones... D3.2. Grificos D3.3._ Eventos D34. Resumen: encajando las piezas. Da. Animaciones y hebras DS. Applets... D.S.1. Lenguaje de hipertexto D.5.2. Pardmetros.... D.53._Limitaciones de los applets : D.54. Conversién de una aplicacién en un applet. D.5.5. Applets con animacién.........+.260++ Resumen Elementos del juego Errores. comune: En Internet jer Bibliogratia Indice analitico. .. 695 695 696 697 697 698 700 701 705 705 708 10 13 713 715 716 719 719 720 722 724 724 126 21 728 730 7Bl Prdlogo ‘a versin original de este libro se disef6 para utilizarla en un curso de infor- mitica de dos semestres de duracién, comenzando por lo que se conoce ha- bitualmente como Estructuras de Datos. EI contenido de dicho curso ha ido evolucionando a lo largo del tiempo. Mien- tras que hay un cierto consenso general con respecto a los temas a cubrit, todavia hhay mucho desacucrdo en relacién con los detalles. Un tema uniformemente acep- tado lo constituyen los principios del desarrollo de software, y mas en concreto los ‘conceptos de encapsulaci6n y ocultamiento de la informacién. Todos los cursos de ‘estructuras de datos ticnden a incluir una introduccién al anélisis de! tiempo de @jecucién, Ia recursiGn, los algoritmos basicos de ordenacton y las estructuras de ‘datos elementales. En muchas universidades se ofrecen cursos avanzados que cu- tren a un nivel superior conceptos de estructuras de datos, algoritmos y ani del tiempo de ejecucién. El material de este libro se ha disefiado con la intencién de ser usado en cursos de ambos niveles, eliminando asf la necesidad de adquirir tun segundo libro de texto. ‘Aunque los debates mis enconados en este terreno se centran en torno a la cleccién del lenguaje de programacién mis apropiado, hay otras decisiones funda ‘mentales a tomar, incluyendo las siguientes: se debe 0 no introducir pronto el diseio orientado a objetos y/o el diseno basado en objetos + El nivel de rigor matemético que se va a mantener, + El equilibrio adecuado entre la implementacién de las estructuras de datos y su utilizaci6n, * Detalles de programaciGn relacionados con el lenguaje elegido (por ejemplo, silas GUI deberian usarse pronto 0 no). Mi objetivo a la hora de escribir este libro es proporcionar una introducciéa priictica a las estructuras de datos y los algoritmos desde el punto de vista del pen- ‘Samiento abstracto y la resoluciéa de problemas. Intento cubrir todos los detalles importantes concernientes a las estructuras de datos, st andlisis y sus implementa: ‘ciones en Java, aunque evitando aquellas estructuras que si bien son interesantes desde un punto de vista te6rico, no se utilizan con asiduidad. Es imposible cubrir din tan Cid Seti eee tepeaeaieetamer Gn tame: einihtenaees bi aed Sie tal, Cluyendo sus usos y andlisis. Por ello, he disefiado el libro para permit una cierta flexibilidad a los profesores a Ia hora de fijar su temarie, Cada profesor tendré que decidir el equilibrio adecuado entre teoria y prictica, y clegit en consecuencia aquellos temas que mejor encajen en su asignatura, Como indico mis adelante en este prefacio, el texto esti organizado procurando minimizar las dependencias en: tte los distintos capitulos, Un enfoque novedoso EL libro adopta un enfogue novedoso separando la presemtacin de cada estructura de daios en su especificacign (a través de una intefaz Java) ¢ implementacin. Es- te enfoque proporciona varios beneficios, ene ellos la promocisn del pensamien to abstracto. Antes de conocer la implementaci6n se presenta la interfaz de la cla se, obligando asf al estudiante a pensar desde el principio sobre la funcionalidad y eficiencia potencial de las distintas estructuras de datos. Por ejemplo, los estudian: tes vern programas que usan las tablas hash cientos de pigines antes de imple- ‘mentarlas. Las interfaces de las estructuras de datos se describen en un sinico capt twlo de la Parte Il. En la Parte Il se describen también las téenicas bisicas de andlisis, la recursin y el problema de la ordenacidn, La Parte Ill contiene una co: leccivn de aplicaciones que usan las distinas estructuras de datos. La implementa- iG de las estructures bésieas no se estudia hasta la Parte IV, una ver. se han ust do dichas estructuras, Puesto que todo el cddigo que aparece en el libro esti disponible (véase Disponibilidad del eddigo en ta piigina XVI), los estudiantes, pueden diseiar proyectos de programacin de cierta envergadura bastante pronto, usando el software existente. Las herramientas de desarollo de software en todos tos lengusjes vienen junto eon grandes librerfas,y la mayor parte de las estructu Fas de datos interesantes formarin parte de estas librerfs mis tarde © mas terupra no. Preveo que en los cursos de estructuras de datos se produciri un eventual des- plazamiento del énfasis de la implementacién al uso, Muchos profesores preferiran un enfogue mis tradicional en el que cada es- tnuctura de datos se define primero, Inego se implementa y por tiltima se usa Puesto que no hay dependencias entre las partes Illy TV, se puede también ense: far Ficilmente siguiendo el metodo tradicional utilizando este libro, Prerrequisitos Los estudiantes que vayan a usar este libro deberfan tener previamente conoci rientos sobre algun lenguaje de programacion mosiular u orientado a objetos. Se suponen conocimientos sobre las earactrfsticas bsicas. incluyenda tipos primiti- vos, operadores, estructuras de control, funciones (métoxos) y entrad sada (pero ‘no necesariamente de vectores y clases). Los estudiantes que hayan asistido aun curso de Java pueden comenzar con el Capitulo 3 (0 quiz més adelante), Los estudiantes que heyan usado ous lengua jes deberian empezar con el Capitulo 1, Ellos también deberian usar los apéndices. autocontenido y normalmente se estudia en cursos superiores. ‘© Apéndices (Més Java): el material sobre GUI del Apéndice D puede estu: Giarse en cualquier momento tras ef Capitulo 4, segdn resulte conveniente, Fundamentos mateméticos He intentado mostrar los resultados con el rigor matemitico necesario para satisfa- cer las expectativas de aquellos cursos de Estructuras de Datos en los que se hace Enfasis en la teorfa, y para los cursos superiores, que incluyen més anilisis. Sin ‘embargo, este material se separa del texto principal presentindose en forma de teoremas separados y. en algunos casos, secciones separadas (0 subsecciones). De ‘este modo, puede prescindirse de élen los cursos en los que se decida no conceder tanta importancia a los resultados tedricos, En cualquier caso, no es necesario entender Ia demostracidin de un teorema pa- ra comprender el resultado en sf, Esta 5 otra muestra de la distincién entre una interfaz. (el enunciado de un teorema) y su implementacibn (su demostracion), Asi, parte del material inherenterente matemético, como ta SecciGn 7.4 (Aplica cciones numéricas de la recursi6n), puede evitarse sin que ello afecte a la compren- si6n del resto de cada capftulo, Organizacién del curso Un aspecto fundamental a la hora de ensefiar el contenido de este libro es decidir ‘emo emplear el material contenido en las Partes TI Hy TV. El material de la Par te Tha de ser explicado con detenimicnto, y el estudiamte deberfa realizar varios Programas que muestren cémo debe realizarse el disefio, la implementacién. la prueba de clases (incluyendo las genéricas), y quizés el disefio orientado a objetos ‘empleando herencia. El Capitulo 5 discute la notacién O. Un ejercicio adecuado para comprobar si el estudiante ta ha comprendido es hacerle escribir un pequeio programa, pidiéndole que compare su tiempo de ejecucién con los resultados obte hidos en os anilisistesricos. Dentro de Ia metodologia de separacidn entre especificacién ¢ implementa. idn, el concepto clave del Capitulo 6 es que diferentes estructuras de datos sopor tan distinios esquemas de acceso con eficiencias diferentes. Un posible ejercicio es pedir a los estudiantes que escriban una estructura de datos ineficiente, para probarla después con uno cualquiera de los casos de estudio (a exeepeidn del algo- ‘htmo tres en raya, que emplea recursién). Asi, los estudiantes podrian comparar su ‘ente con una rutina de libreriaeficiente (pueden conse- fip andnimo, tl y como se explicaré més tarde). Siguicndo este esquema, pueden probarse toxos los casos de estudio (silvo el juego de las tres en raya), estudiando el comportamiento de cada estructura de datos. De este modo, el estudiante pouria yer las distntas interfaces y su ulizacidn, pero no emo se im- ‘slamenten de Seana cficiaate, .Viendo:len.cosen de enta, Gorma incrementenns la capacidad de los estudiantes para pensar de forma abstracta. También se les podea pedir que extendiesen el caso de estudio, pero, de nuevo, para ello no es nevesario {que conozcan cada detalle de las correspondientes estructuras de datos La implementacién de las estructuras de datos puede ser discutida posterior ‘mente, y la recursién se introducira siempre que el profesor lo considere adecua- do, teniendo en cuenta que debe haberse hecho antes de estudiar los doles bina- rios de brisqueda. Los detalles de los algoritmos de ordenacién pueden explicarse ‘en cualquier momento tras haber introducido Ia recursién, En este punto, el curso Puede continuar examinando los mismos casos de estudio, pero modificando las implementaciones de las esiructuras de datos. Por ejemplo, se pueden realizar di- ‘versas prucbas empleando los distintos tipos de daboles binarios de busqueda equi- ibrados, Aquellos profesores que opten por una aproximacién mis tradicional, pueden imitarse a discutir un caso de estudio de la Parte TIL explicando despues una im- plementaci6n de una estructura de datos de las que se encuentran en la Parte IV. Insistimos en que los capftulos del libro estin disefiados de forma tan indepen- diente como ha sido posible, Ejercicios Los ejercicios presentados son de cuatro tipos diferentes. Las cuestiones breves se reducen a contesiar pequeflas preguntas o simular sobre el papel algén algoritmo escrito en el texto. La seccién de problemas tedricos incluye cuestiones que re- quieren algdn anilisis matemético, y preguntas acetca de soluciones a problems, relevantes desde un punto de vista tedtico. La parte de problemas précticos con- tiene cuestiones sencillas sobre programacin, incluyendo preguntas de sintaxis © sobre truces cmpleados en la coificacién. Por hime, ta seccion de prdcticas de rogramacién contiene ideas para realizar ejercicios mas complicados y sugeren- cias para desarrollar applets de Java. Detalles pedagégicos * Las notas all margen se emplean para destacar conceptos ¢ ideas importantes. * La seccién Elementos del juego enumera los términos ms importantes junio. con sus definiciones, * La seccién de Errores comunes, que se encuentra al final de coda capftalo, muestra una lista de los errores mds habituales. * Al final de cada capitulo también se suministra una secciGn de Bibliogroffa para encontrar aclaraciones y ampliaciones de los temas estudiados. Disponibilidad del cédigo El cddigo inciuido en el libro es completamente funcional y ha sido probado en st versin original sobre JDK 1.1 de Sun. Dicha versién (en inglés) puede obtenerse mediante fip anénimo en ew.com, y s¢ encuentra en la Word Wide Web en cep s//www.aw.com/cseng/titles/0-201-54991-3/ (a partir de aaef deben seguirse los enlaces indicados en cada caso). La seccién En Internet, que se en- ‘cuentra al final de cada capitulo, enumera los nomibres de los ficheros del cédigo del capitulo correspondiente. Guia del profesor Se encuentra disponible una guia del profesor (correspondiente al texto original en inglés) que ilustra los distintos usos posibles del material. Incluye ejemplos de cuestiones de examen, pricticas a proponer a los alumnos y programas altemati- vos de asignaturas en las que se desarrolle parte del contenido del texto. También pueden encontrarse en ella soluciones de ejercicios seleccionados. Los profesores interesados en obtenerla deben contactar con su representante local de ventas de Addison-Wesley para una mayor informaci¢n. Agradecimientos En la preparacién de este libro ha participado una gran cantidad de gente, Mucha de ella ya fue reconocida en el trabajo anterior, Algorithms, Data Structures, and Problem Solving with Cs-+, sobre el que se basa este libro. Otra gran cantidad de gente, demasiado numerosa para ser citada aquf, ha enviado mensajes electrSnicos sefalando errores e inconsistencias, que he intentado arteglar en esta versicn (en. inglés). En esta ocasién, me gustaria mostrar mi agradecimiento a todos mis eolabora- dores de Addison-Wesley: mi editora, Susan Hartman, y editora asociada, Katheri- ne Harutunian, que me han ayudado en las decisiones més delicadas sobre la orgs: nizaciGn del material Java y que han contribuide a que este libro se realizase. Los distintos revisores han sugerido la introducci6n de numerosos cambios que han contribuido a mejorar el texto. Ellos son: Laura K. Michaels, Phyllis Coyne y So- rah Hallet-Corey. Por otra parte, Syndi Hirsch realiz6 un diseno fantastico para la portada del libro y. como siempre, Tom Ziolkowski ha desarrotlado una labor extraordinaria en el departamento de marketing. Agradezco especialmente a Pat Unubun, mi editora de produccidn, sus constantes esfuerzos en la coordinacion completa del proyecto. ‘También doy las gracias al resto de mis revisores, quicnes realizaron valiosos ‘comentarios, muchos de los cuales he inireducido en el texto: John Chenoweth, Rob Clark, John France, Susanne Hupfer, Steven L. Jenkins, Josephine DeGuz- man Mendoza, Viera K. Proulx y Amr Sabry. Parte del material empleado en el texto es una adaptacién del gue aparece en mi libro Efficient C Programming: A Practical Approach (Prentice-Hall, 1995) y ha sido empleado con el consentimiento de su editor. He intentado incluir las oportunas referencias a otros textos al final de cada capitulo. i pigina en la World Wide Web, beeps / /www.co .fiu.edu/-weiss, con- tiene cédigo fuente actualizado, una lista de erratas y un enlace para poder comu- nicarme otros fallos detectados (en el original en inglés), Prdélogo a la edicién en espanol [ presente texto realiza un estudio exhaustive de las estructuras de datos ma- terializadas en el marco de la programacién orientada a objetos. Para ello, se utiliza un lenguaje moderno como Java, que reine unas caracterist muy atructivas para usuarios, tanto de gustos mis académicos como de un perfil ‘ms aplicado, No repetiremos aqui la descripeidn del texto que de forma eymerada y muy detallada realiza el autor en su prélogo: sin embargo. sf consideramos opor- ‘uno recalear cudles son los principales objetives cubiertos por el mismo, tanto en el marco académico, como en el profesional, Comenzando por este titimo, el pro- udor en Java, o aquél interesado en conocer las posibilidades de este lengua- je, en cuanto a estructuracién de datos se refiere, encontrari en el texto una pr ‘SentaciGn detallada de ls implementacion y modo de aplicaciGn de las estructura, de datos mas utilizadas, asf como de algunas otras mis sofisticadas, Por su parte, los profesores y alumnes de disciplinas de Estructuras de Datos encontrarin en es- te texto una presentacion de las mismas que hace hincapié en los principios de en- ccapsulacidn y ocultamiento, hasta de las estructuras estudiadas, partiendo de la descrips para més adelante el estudio de su implementacién. ‘Como quiera que, en buena medida, el énfasis se pone en los detalles técnicos de las implementaciones y aplicaciones, el marco ideal de uso del texto serfa el de in Laboratorio de desarrallo y uso de Estructuras de Datos; bien el de una asig- natura més general de estudio de dicha materia, soporiada por la realizaci6n de Dricticas sobre el computador. Es cierto que, en este ultimo caso, si el profesor desea incluir un estudio tebrico de les Tipos Abstractos de Datos, deberfa comple- tar su bibliograffa con un texto que cubra dicha materia, Por tltimo, remarcaremos el interés que tiene el soporte que el autor da a los lectores a través de la red, pues a través del mismo no sdlo se pueden conseguir kas Versiones originales (en inglés) de todos los programas que aparecen en el texto, ‘sino que se tiene acceso a eventuales versiones mejoradas y, en general, a diverso ‘material de actualizacién y complemento del texto, sin tener que esperar a even tuales segundas ediciones revisacas. Al respecto, confiamos en que los lectores de ‘esta version traducida sepan aceptar como ineludible la consulta de dicho material en su versin original, pues al enorme trabajo que supondirfa el mantenimiento ae twalizado de una versiGn aducida de dicha pagina electronica, se une el hecho de que se trata de una paigina personal del autor. Por el c I plantearnos ttaduceién del texto hemos considerado may descable, y por tanto asi lo hemos hecho, traducir por completo el texto de los programas en el mismo. Con ello en- tendemos que se facilita enormemente la labor de comprensién de los mismos por Parte de nuestros lectores, aun a pesar de la molestia que pealrfa suponer el tener {que mancjar las versiones oniginales. Por otra parte. y sin que ello suponga asumir ‘inguna responsabilidad sobre posibles consecuencias de errores en las versiones traducidas, sf hemos hecho un enorme esfuerzo en este sentido, procurando que las versiones traducidas se comporten exactamente igual que las originales, siendo Por tanto mutuamente reemplarables (lo que es de hecho un ejemplo de le doctr nna de encapsulamiento y ocultacién aplicada en ef texto), haciendo por supuest excepcion de la necesidad de traducir los cortespondientes identificadores. que aparecen en las interfaces de las estructuras, Por otra parte, y a pesar de que los programas originales estaban inicialmente con- cebidos para la versi6n 1.1 de Java, &tos han sido recopilados y ejecutades sin ningcn problema en la nueva plataforma de Java 1.2, también Hamada Java 2, grax is al exfuerzo del autor en usar Io maximo posible el coraz6n de Java. Por este ‘ulumo motivo es de esperar que los programas sigan siendo compatibles con ver siones futuras de Ja Los traductores y revisores téenicos Madrid, marzo 2000 ruc Un recorrido por Java CAPITULO ] Java basico 1 objetivo principal de este libro es estudiar téenicas de resolucivn de pro ‘blemas que permitan la construccién de programas sofisticados y eficientes Précticamente todo el material utilizadlo se puede aplicar en cualquier len: uaje de programaciOn, Se podria argumentar que para ensefar los conceptos bas- ta con una descripcidn suficientemente amplia en pseudocddigo de estas tecnicas. Sin embargo, creemos que ¢> de vital importancia trabajar con e6digo real No hay escasez de lenguajes de programacion disponibles. En et momento en ‘que s2 escribid este libro. C++ era el lenguaje mas usado tanto acadéi comercialmente, Sin embargo, en 1996, Java icrumpié en la eseena como un con tendiente viable La promocién publicitaria masiva sobre Java se debe en gran medida a su uso como lenguaje en el que se escriben applets. Los applets son programas Java eje- cutados por un navegador de la World Wide Web, como Netscape Navigator. Ac- tualmente, la mayor‘a de las paginas Web contienen animaciones. muchas de las cuales son applets de Java. Aunque los applets son fantésticos, ellos 00 son la ra- 26n por la que nosotros usamos Java, De hecho, en este libro solamente se estu- dian los applets en un breve apéndice Java proporciona también soporte para 1a programacién concurrente, donde varios procesos se ejecutan en paralelo comunicéndase entre sf de forma primiti- va. Esta caracterftica es importante en programacién mis avanzada, pero no $6 usa en este libro, E principal atractivo de Java es que se trata de un lengusje seguro y portable que soporta las construcciones de la programacién moderna orientada a objetos. Muchas construcciones de C++ que confunden a los principiantes no existen en Java, Compando con C+, Java detecta muchos de los errores comunes de pro ‘gramacidn, ya sea en tiempo de compilacidn 0 de ejecucién. Java tiene un meca- nismo de excepeiones que obliga al programador a tratar de forma explicita 10s cerrores y un modelo relativamente simple que distingue entre tipas primitivos (como me) y tipos definides por el usuario. Java carece de un tipo puntcro explicito. Java es portable: por ejemplo, un entero tiene e! mismo rango de valores en todas lus implemeataciones de Java, independientemente de la arguitectura subys- cente de la computadora, Java proporciona también una herramienta de interfae ‘iitiin te: cea Cit cee eee tn caiin sn ida Brenan’ través de formularios. Aunque no estudiamos esia heramienta en el texto princi: Pal (vase Apéndice D), es bestante sencilla de ilar. Lo més importante es que tambign es portable a cualquier implementacin de Java, La filosofia de Java es soveribe una vez, ejecta en todas pares En Jos primeros cuito capflos estadiremos ls cracterticas de Java que ‘se usan a lo largo del libro. Por el contrario, las caracterfsticas y aspectos técnicos aque no se van a utiliza, 9 se cubren. Quienes deseen una mayor informacion sobre Java, la encontraran en los mul- tiples libros de Java disponibles, ‘Comenzamos discutiendo Ta parte del lenguaje scmejante ala de un lenguaje de programacisn de los setenta como Pascal 0 C. Esta incluye Ios tiposprimitivos, operaciones bisias, consracciones condiciones y de repetcion, elequivalen- {© on Java de las funciones, En este capitulo, estuiaremos: * Algunos conceptos bisicos de Java, incluyendo los elementos Iéxicos simples. © Los tipos primitives de Java, incluyendo algunas de las operaciones que pueden Hlevarse a cabo con las variables de tipo primitivo. + © Cémo se implementan en Java las instrucciones condicionales y los bucles. * El método estético; el equivalente en Java a la funcién y el procedimiento, 1.1 El entorno general {Cémo se escriben, se compilan y ejecutan los programas Java? La respuesta, por supuesto, depende de la plstaforma particular sobre la que se encuentra instalado el compilador de Java. En el Apéndice A se describen algunos de los sistemas de desarrollo més populares El codigo fuente de Java se guarda en ficheros con nombres acabados en el su- fijo java. El compilador local, javac. compila el programa y genera ficheros re: 2 ates 2 b: Py) C= ate + seb: ry System.out.printin( ast t+ bets +e dy ae a7) Figure 13. Programa que llusra al uso de los operaciores, ‘Otro operador de asignaciOn es +=, cuyo uso se muestra en la nea 18 de le figura. El operador += aiiade el valor situado en el lado derecho (del operador de asignacién +=) a la variable del lado izquierdo, Por tanto, en la figura, el valor de © pasa de ser 6, antes de la Iinea 18, a ser 14. Java proporciona otros operadores de asignacién como - que modifi ccan el valor de la variable situada en el lado izquicrdo del operador via sustrac- in, multiplicacién y divisin, respectivamente. 1.4.2 Operadores aritméticos binarios En la linea 20 de la Figura 1.3 se muestra uno de los operadores aritméticos bina: ros tipicos de todos los lenguajes de programacién: el operador de suma (+). El ‘operador + have que los valores de b y c se suimen: b y c no suften ningdn cam: bio. E1 valor resultante se asigna a a. Otros operadores aritméticos tipicos usados ‘en Java son -, *, / y que se usan respectivamente para restar, multiplicar, divi dir y obtener el resto de una divisi6n entera. La division entera devuelve sola mente la parte entera y descarta el resto, ‘Como es habitual, la suma y la resta tienen la misma precedencia, y dicha pre cedencia es menor que Ia del grupo formado por los operadores de multiplicacién, divisién y resto; en consecuencia 14243 se evaliia a 7. Todos estos operadores asocian de iequierda a derecha (Iuego 3-2-2 se evallia a 1), Todos los operado- res tienen prevedencia y asociatividad, La tabla completa de operadores se en: prebrenper rye 1.4.3. Operadores unarios Ademds de los operadores aritméticos binarios, que requieren dos operandos, Java proporciona peradores urariox, que requieren un solo operando. El mis familiar de estos operadores es el menos unario, que se utiliza para cambiar el signo del ‘operanddo. Asf, -x dewuelve el valor de x cambiado de signa, Java proporciona también el operador de autoincremento, para afadir 1 a una variable, denotado por ++, y el operador de autodecremento, para restar 1 a una variable, denotado por --. El uso mds benigno de esta caracteristica se muestra en las lineas 22 y 23 de la Figura 1.3. En ambas lineas, el operador de autoineremen- to ++ ahade [al valor de la variable. En Java. sin embargo, un operador aplicado a tuna expresién produce una expresién que tiene un valor. Aunque se garantiza que 1a variable sent incrememtada antes de la ejecucion de la siguiente instruccidn, sur ‘ge una pregunta: {cual es el valor de la expresién con autoineremento si se usa dentro de una expresién mayor? En este caso, la posicin de ++ tiene una importancia crucial. La semdntica de ++% es que el valor de la expresién es el nuevo valor de x. Esto recibe el nombre (8 incremento prefijo. Por el conirario, x++ hace que el valor de la expresicn sea “el valor original de x. Esto recibe el nombre de incremento postfijo. Esta propie- dad se muestra en la linea 24 de la Figura 1.3. Tanto a como b se inerementan en | mientras que c se obticne sumando el valor original de a con el valor ineremen- tado de b. 1.4.4 Conversiones de tipo El operador de conversién se usa para generar una entidad temporal de un tipo nuevo. Considere, por ejemplo, double coeiente; int x int y= 10; cocient. ty // yProbablemente mai! La primera operacidn es la divisién, y puesto que xe y son enteros, el resultado es ‘su divisiGn entera, obtenigndose por tanto 0. El entero 0 se convierte entonces de forma implicita al tipo double para que pueda ser asignado a cocionte. Pero ‘nosotros pretendiamos asignar a cocieate el valor 0,6. La solucidn es generar ‘una variable temporal para 2 0 para y, de forma que la division se lleve a cabo ‘usando las reglas del tipo double. Esto se haria de la siguiente manera: cociente = double) x /y: ‘Observe que ni x ni y se modifican. Se crea una variable temporal sin nombre, Ccuyo valor se usa para efectuar a divisi6n. El operador de conversién de tipo tiene ‘mayor precedencia que la divisin, luego la eonversién de tipo se efeetia sobre el valor de x y después se Heva a cabo Ia division (en lugar de efectuarse la conver- ia Chale We VANE det eines Ue es ck 1.5 Instrucciones condicionales En esta seccidn sc estudian instrucciones que afectan al flujo de control: instruc iones condicionales y bucles. Como consecuencia, se introducen nuevos opera dores. 1.5.1 Operadores relacionales y de igualdad 1 test bisico que podemos realizar sobre los tipos primitivos es la comparacin Esta se Teva & cabo usando operadores de igualdad y desigualdad, asi como los ‘operadores relacionales (menor que, mayor que, et.) En Java, los operadores de igualdad son == y 1=. Por ejemplo, exprizda == exprpcha se evaliia a true si exprtzda y exprDeha son iguales; en caso contrario, se eva: lia a false. Andlogamente, exprizda != exprDcha se evallia a crue si exprizda y exprdena son distntas; en caso contrario, se evalia a fase. Los operadores relacionales son <, <=, > y ~~. Tienen un significado natu- ral para 1os tipos predefinidos. Los operadores relacionales tienen mayor prece dencia que los operadores de igualdad. Ambos tienen menor precedencia que los ‘operadores aritméticos pero mayor precedencia que los operadores de asigna- ‘ci6n, de modo que el uso de paréntesis no suele ser necesario. Todos estos ope- radores asocian de iquierda a derecha, pero este hecho no es de gran utilidad: en la expresién 2 < & < 6, por ejemplo, el primer < genera un valor de tipo boolean y el Segundo es ilegal porque < no esti definido para los valores de ese tipo. En la siguiente seccién se describe la forma correcta de evar a cabo esta comparacicn 1.5.2 Operadores légicos Java proporciona operadores légicos que se usan para simular los conceptos Y. © y NO del algebra de Boole. Estos se conocen con el nombre de conjuncién, disyuncién y negacién respectivamente, y los operadores comespondientes son 8, [ly 1. El test de Ia seccién anterior se implementa adecuadamente como a-ak b «6, La precedeneia de la conjuncién y la disyuncién es lo suficiente- mente baja como part que no sea necesario utilizar paréntesis. El operador as tie re mayor precedencia que el operador | |, mientras que ! se agrupa con los demas ‘operadores unarios. Los argumentos y resultados de estos operadores ldgices son valores de tipo bootean, En la Figura 1.4 se muecsiran los resultados de aplicar ‘fee cheeenicnen Uclens cee Sede ton eruthtes welenen Seneirada, x x | sex xiit & false false false false eeue false trie false true true ere fall false true False = eeue true exue false Figura 1.4 Resutado de los operadores lbgicos. ‘Una regia importante es que && y || son operadores con evaltacién de ciclo como. La evaluacién de ciclo corto consiste en que cuando el resultado de un ope- rador légico se puede determinar examinando la primera expresisn, entonces no se ‘evalia fa segunda. Por ejemplo, en Demis x si x5 0, entonces la primera mitad es false. Automdticamente el resultado de! ‘Y debe ser fa1.se, por lo que no se evalia la segunda mitad. Esto es acertado pues 1a divisién por cero producirfa un comportamiento erréneo. La evaluacién de ciclo corto nos evita tener que preocuparnos por la divisiGn por cero! 1.8.3 Lainstrucci6n if La instrucci6n if es la principal herramienta para tomar decisiones. Su forma bé- sica es if ( exoresion) ingtruceiéa siguiente instruccién Si expresion toma el valor true, entonces se ejecuta instruccién; en caso Contrario, no se ¢jecuta. Cuando se completa la ejecucién de la instruccidn { ¢ (sin nningin error sin tratar), el control pasa a la siguiente instruccisin. Opcionalmente, se puede usar una instruccion if-else, como la siguiente: A£( expresién) instrucciénl dastrucesén2 Siguiente instruccién ‘damente) ars en os que es preferile no wa a evaluacin de ciclo cert. En ales cases, os operaderes Po Boole, faratizan qu anos argumenios se eval, insiso ange el resllado de la operiicn pda ‘Primer argumenso. En este caso, si expresin se evalda a true, entonces se cjecuta instruceisnt; ‘en caso contrario se ejecuta instruccién2. En cualquier caso, el control pasa después a la siguiente instruceidn, como en System. out .print (“1/xes* if (xt=0) System.out-print(1/x); else System. out print ( *Indefinido ) System.out .printin( ) Recuerde que se permite a lo sumo una instruccion en cada una de las cldusu- independientemente del sangrado. A continuacién se puede obser- 0): //:es 1a instruccién vacia (y cuenta) System.out print ( x es0"); else System.out print ( *x e Syetem-out printia( x )7 // Dos instrucciones El primer error es la inclusion del ; al final del primer 1£, Este punto y coma ‘cuenta como la instruccién vaefar como consecuencia, este fragmento no podré ‘compilarse (ya no hay ningin ££ con el que se asocie e15e). Una vez ameglado ese error, tenemos un error ldgico: la ultima linea no es parte del else, incluso aun- ue el sangrado lo sugiera, Para areglar este problema, tenemos que usar un blo- que, en el cual encerramos una secuencia de instrucciones entre un par de Haves: ie (x==0) ‘System.out -printia( "x es cero" }; else « System.out print ( “x es ‘System. out .println( x); £0 els: La instruccién 1 puede formar parte también de una eléusula igual que otras instrucciones de control que estudiaremos mis adelante en este ca- pitulo. En el caso de instrucciones ‘£-eis0 anidadas, la clivsula else est aso- cciada con la ekfusula i¢ mds intema que esté sin emparejar. Sera necesario afadir Ives en el caso de que no sea ése el significado pretendido. 1.5.4 Lainstruccién while Java proporciona tres formas bisicas de bucle: la instrucciGn while, la instruc- cién for y la instrucein do. La sintaxis de la instruccidn whi le es la siguiente wndle( expresién) instruccién Observe que al igual que en la instruceién i, no hay punto y coma en la sintaxis ‘Si esti presente, se interpreta como la instrucci6n vacia. Mientras que expresicn tiene el valor true, se ejecuta instruced dni en consecuencia, expresicn esté continuamente reevaludndose, Si expresién vale inicialmente false, instruccién ao se ejecutari nunca, En general, inet ruccién Hleva a cabo alguna aceién que potencialmente puede alterar el va- lor de expresidn; en caso comtrario, el bucle pourfa ser infinito. Cuando el bucle wade termina (con normalidad), el control pasa a la siguiente instrucci¢n, 1.5.8 La instruccién for La instruceién while es suficiente para expresar todo tipo de repeticién. Aun asi, Java proporciona otras dos formas de bucle: la instruccién for y la instrucci6a do, La instruccién for se usa principalmente para la iteracién simple. Su sintaxis for( inicializaciém tests actualizacién) siguiente instruccién Aqui, inicializacién, test y actualizacién son expresiones, siendo las tues opcionales. El valor por defecto de test, cuando no aparece, es true. No hay punto y coma tras el paréntesis cerrado. Al ejecutar la instruccién for, lo primero que se lleva a cabo es la inicializacion. Entonces, mientras test valga true, s¢ Hevan a cabo las si- guientes acciones: se ejecuta instruccién, y se produce la actualizaciéa, Si se omiten inicializacién y actualizacién, enionces la instruccién for se ‘comporta exactamente igual a una instrucci6n whi le. La ventaja de la instruccién for es la claridad en el tratamiento de las variables contador (0 iteradoras), ya que la instruccién for permite ver fécilmente cual es el range del contador. El si- 2uiente fragmento produce los 100 primeros enteros positivos: for( int i= 1; i<=100; i++} Systen.out .printIn( i}: Este fragmento ilustra 1a técnica habitual de declarar un contador en la parte de inicializacién del bucle. El Ambito del contador es solamente el interior del bucle. Tanto inicializacién como actual izacién pueden usar una coma para permitir varias expresiones. El siguiente fragmento ilustra esta técnica habitual- ‘mente utilizada: for(i=0, guna =0; i<=n; ier, guna s=n) ‘System.out.printin( i+*\t* + sum); Los bucles se anidan de la misina forma que las instrucciones 1, Por ejemplo, podemos encontrar todos los nimeros pequefios cuya suma es igual a su producto Melheeetineilil en eee ie for{ inva W110; 460) for( ant j=1; 4 <+10 ig(isgecits) Gyetem.out-printin(i+*, "+5 )1 Sin embargo, como veremos més adelante, cuando anidamos bucles podemos ‘crear fécilmente programas cuyos tiempos de ejecucién crecen ripidamente 1.5.6 Lainstruccién do La instruccién white Heva a cabo un test repetidamente. Si el test se evalia @ Erve. entonces se ejecuta el cuerpo del bucle. Sin embargo, sie! test tiene inicial- mente el valor fase, el cuerpo del bucle no se ejecuta nunca. Ahora bien, en al- ‘gunos casos nos gustaria garamizar que el cuerpo del bucle se ejecuta al menos tuna vez. Esto se puede conseguir usando la instruccién do. La instruccién do es {déntica a la instruccién whi le, excepto por el hecho de que el test se realiza tras la ejecucidn del cuerpo del bucle, La simaxis es ao istruccién while( exprosién )+ siguiente instruccién Observe que la instruccisn do incluye un punto y coma. En el siguiente fragmento cen pseulocddigo se muestra un uso Uipico de la instruceiGn do: o ‘ Pedir dato al usuarios Leer valo: } while ( el valor no es bueno}: La instruccién do es la menos usada de las tes formas de bucle. Sin embargo, ‘cuando tenemos que hacer algo al menos una vez. y por alguna razén un bucle for no es Jo mis adecuado, entonces la instrucciGn do se convierte en nuestra eleccisn 1.5.7 break y continue Las instrucciones for y while offecen una oportunidad de terminaci6n antes de volver a cjecutar ef cuerpo del bucle, La instrucciéa do ofrece una oportunidad de terminacidn tas la ejecucin del cuerpo. Ocasionalmente, podsfamos querer tr rminar la ejecucién en mitad del cuerpo (instrccidn compuesta) del bucle. La ins- ‘ruccién nzeak, formada por la palabra reservada break seguida de un pusto y ‘coma, se puede usar para conseguir, Normalmente una instrucién it precede a ‘iainie iene diene while{ ...) ‘ if( algo) break; La instruccién break provoca Ia salida del bucle mis intemo en el que esti contenida (también se usa en conjuncién con la instruccién switch, que se estu- dia en la siguiente seccicn). Si hay varios bucles de los que deseamos salir, Ia ins- truceién break no funcionari adecuadamente: ademis, lo més probable en tal ca: 80 es que su programa esté pobremente diseado, Aun asf, Java proporciona una instruccién break etiquetada. Para utilizar dicha instruccién, se comienza por po- ner una etiqueta a un bucle, de forma que la instrucci6n break se pueda aplicar a ese bucle, independientemente de cuantos bucles anidados haya. A continuacion se muestra un ejemplo: it (desas break exterior; // Salta hasta después de exterior ) 7/ #1 control salta hasta agui al salir de! bucle exterior A veces. queremos abandonar la ejecucién del cuerpo del bucle en la iteracién ‘actual y saltar a la siguiente iteracin. Esto se puede realizar con la instruccién continue. Al igual que la instrucciGn break, la instruccién continue incluye ‘un punto y coma y se aplica solamente al bucle mis interno. Fl siguiente fragmen- to produce los 100 primeros enteros, con la excepcién de los divisibles por 10: for(int i=1; 1 <=100; ise) ‘ i£( 4810220) continue; System.out .printin( 4); ? Por supuesto, en este ejemplo hay otras alternativas al uso de la instruccién continue. No obstante, continue se usa a menudo para eviter patrones if-else ‘complicados dentro de los bucles. 1.8.8 Lainstruccién switch La instruccién switch se usa para elegir entre varios valores enteros pequefios, Consiste en una expresin y un blogue. El blogue contiene una secvencia de ins- ‘ucciones y una coleccidn de exiquetas, que representan posibles valores de la ex- indian Seated Dae Meabniis Mitare ands Medien Sinn dines ac ina on ee ‘encaja con cualquier valor no representado por las demas. Si no hay ningiin caso aplicable al valor de la expresién owiteh, Ia instrucsién ayit.ch finaiza su eje- cucidn; en caso contrario, el control pasa la etiqueta apropiada y se ejecutan to- das las instrucciones desde ese punto en adelante. Se puede usar una instrucciGn break para forzar la terminacién de I insruccidn switch uilizéndose casi siem- pre para separar logicamente los distintos casos. En la Figura 1.5 se muestra un ejemplo de esta estructura tpica smwtten( alguncaracter ) « 1 2 3 case's 4 case's 5 case's 6 // Cédigo para procesar los simbolos de apertura 7 breaks a 9 0 a " i 12 //Céaiga para procesar los simboles decierre 13 breaks “4 1S cate \n's % Saigo para tratar el carécter de fin de linea 7 breaks 6 19 dofauit: 2 // Cdigo para tratar otros casos 21 breaker 2d Figura 1.5. femplo de unc insttuccion switch. 1.5.9 El operador condicional El operador condicional ?: se usa como abreviatura de una instruccion if-else simple. La forma general es expriest ? exprsi 1 exprNo Primero se evala exprrest, seguida por exprsi 0 expzNo, produciendo ast el resultado de la expresi6n completa. Si oxpr7ect se evaliia a true entonces se evalda exprsi;en caso contrario, se evalia exprio, La precedencia del operador condicional se encuenira justo por encima de la de los operadores de asignacii Esto nos evita tener que usar paréntesis cuando asignamos a una variable el resul- tado de un operador condicional. Como ejemplo, para asignar el mfnimo entre x © vy tla Variable val1in harfamos lo siguiente: gelinttin am cuse-te sews. 1.6 Métodos Lo que en otros lenuajes se conoce como funcidn 0 procedimiento, en Java se Hama ‘método. En el Capitulo 3 se proporciona un tratamiento mis completo de los méto. dos. Esta seecidn presenta algunos conceptos bisicos para escribir funciones del es- tilo de C, como main, de forma que podames escribir algunos programas simples. La cabecera de un método consiste en un nombre, una lista (posiblemente va- cia) de pardmetros y e1 tipo del resultado. El cédigo que realmente implementa el método, a veces llamado el cuerpo de! méiodo, es formalmente un blogue. La de- claracién de un métedo esta formada por una cabecera y un cuerpo. En la Fig ra 1.6 se muestra un ejemplo de un métedo y una rutina iain que lo invoca. Colocando delante de un método las palabras public static, podemos imi- tar una funci6n global del estilo de C. Aunque en algunos ejemplos es una técnica Util, no debe sobreutiizarse, El nombre del método es un identificador. La lista de parimetros consiste en ‘cero 0 més pardmetros formales, cada uno de ellos con un tipo. Cuando se Hama a tun método, los argumentas reales se pasan a los pardmetros formales usando asig- nacién normal, Esto significa que los tipos primitivos se pasan siempre usando pa: {So de pardmetros por valor. Los argumentos reales no pueden ser modificados por 1a funcién. Como en ta mayorta de los lenguajes de programacién modernos, las declaraciones de los métodos pueden aparecer en cualquier orden 1 public class tiatest 2 26 eaten 3 public static votamain( String [ 1 args) af - 5 6 7 8 Systen-out printin( min( a,b) )s ° ) 10 u // betinicion de tuncin 12 public static int min( int x, int y) 3 € u return x Figuia 16 Declarocién y lomada ds un método. La instruccién reeuen se usa para devoiver un valor al punto de Hamada, $i €l tipo del resultado es voi a, entonces no se devuelve ninguin valor, escribiéndose return; en tal caso. 7 1.6.1 Sobrecarga de los nombres de los métodos ‘Supongamos que necesitamos escribir una rutina que devuelva el méximo de tres valores de tipo ine. Una cabecera razonable para el método seria int max( int a, int b, int) En algunos lenguajes, esto puede ser inaceptable si max se ha declarado previ: ‘mente, Por ejemplo, podrfamos tener también int max( inta, int b) Java permite la sobrecarga de nombres de los métodos. Esto significa que va- ties metcdos pueden tener el mismo nombre y declararse en el mismo émbito de clase mientras sus signaturas (es deci, 1s tipos de la lista de parimetros) sean diferentes. Cuando se produce uns Hamada max, el compilador puede deducir cuil es e| méiodo que se pretende aplicar en base a la lista de argumentos reales. Des signatures pueden tener el mismo nimero de pardmetros, siempre que el tipo ‘de alguno de ellos sea distin. Observe que el tipo de! resultado no estéincluido en la signatura. Esto signifi- ‘e4 que no esté permitido tener dos métodos dentro de! mismo dmbito de clase ‘cuya tnica diferencia sea el tipo del resultado, Métodos que se encuentren en ém- bitos de clase distinios pueden tener el mismo nombve, signatura e inctuso tipo del resultado: esto se estudia en el Capitulo 3 1.6.2 Clases de aimacenamiento Las entidades declaradas dentro del cuerpo de un método son variables loca- les y solamente se puede acceder a ellas a través de su nombre, dentro del cuerpo del método. Dichas entidades se crean cuando se ejecuta el cuerpo del método y desaparecen cuando el cuerpo del método termina. Una variable declarada fuera del cuerpo de un método es global a la clase. Es. similar alas variables globales en otros lenguajes si se usa la palabra static (lo cual es bastante probable si se desea permitir el acceso a ta entidad por parte de métodos estiticos). Si se usan las palabras static y final. se trata de constantes, simbdlicas globales. Por ejemplo, static final double Pr = 3.1415926535897932, Observe Ia convencién habitual de usar nombres en maytisculas para los nom- bres de constantes simbolicas. Si el nombre esta formado por varias palabras, s¢ separan mediante el caricter de subrayado, como en ¥at_TNT_VALUE. se omite la palabra static, entonces Ia variable (© constante) tiene un sig nificado diferente, que se discute en la Seccién 3.4.5. Resumen En este capitulo se han estudiado las caracterfsticas bisicas de Java, tales como los. {pos primitivos, los operadores, las instrucciones condicionales, los bucles y los métodos, las cuales se encuentran pricticamente en cualquier lengua. ‘Cualquier programa no trivial requeriré el uso de tipos no primitivos, Hamados tipos referencia, de 10s que se habla en el siguieme captulo. la oq los Pe a La oe a Elementos del juego Dlogue Secuencia de instrvcciones entre Haves ‘cabecera de un método Consiste en el nombre, tipo del resultado y lista de pard- metros. ‘cédigo-j Cédigo intermedio portable generado por el compilador de Java. ‘comentarios Hacen el cddigo mis legible pero no tienen significado semntico Java admite tres formas de comentarios. constante de tipo cadena Constante consistente en una secuencia de caracteres encerrados entre dobles comilas. ‘constantes enteras en octal y hexadecimal Las constanies enteras se pueden re presentar en notacién decimal, octal o hexadecimal, La notacién octal se indi- ca afladiendo un 0 delante del ndmero: la hexadecimal se indica afadiendo 0x © 0x delante del mimero. declaracién de un método Consiste en una cabecera y un cuerpo. enfidad seatic ¢inal Constante global ‘entrada estindar Sc trata del teclado, a menos que se redirija, También hay cana les para la salida estandar y el error estindar -evaluacién de cielo corto Proceso por el cual, siel resultado de un operador légi- 60 s¢ puede determinar a partir del primer operando, entonces no se evakia el segundo operando. identificador Usado para nombrar una variable o un método, instruccién break Instruccién que provoca la salida de! bucle més interno o de la instruccién switch més interna. instruccién break etiquetada Instruccién break usada para salir de bucles ani dados. instraccién continue Insiruccién que salta a la siguiente iteraciGn del bucle mas interno. instruccién do Construccion de bucle que garantiza que el cuerpo del bucle se ejecuta al menos una vez instruccién for Construccién de bucle usada principalmente para la iteraci6n simple. instraccién 4¢ La construccién principal para tomar decisiones, instraccién return InstrucciGn usada para devolver informacién al punto de Ia mada, instraccién ewiteh Instruccién usada para elegir entre varios enteros pequefios. {instraccién vaefa InstrucciGn que consiste en un punto y coma. instraccién white La forma mas hisica de bucle. Java Iniétprete de Java. Javac Compilador de Java; genera e6digo-j ‘main Funcisn especial que se invoca al ejecutarse el programa, ‘método El equivalente en Java a una funcién ‘eétodo estitico Método equivalenie 4 una funcién global ‘operador condicional (?:) Operador usado como abreviatura de instrucciones if-else simples ‘operador de conversion de tipo Operador usido para generar una variable tem- poral sin nombre de un tipo nuevo. ‘operadores aritméticos binarios Se usan para realizar operaciones atitméticas bésicas. Jave proparcidus vatios, eatve ellos «,~;*, /- © operadores de asignacién En Java se usan para modificar el valor de una varia: ble. Estos operadores incluyen =, + operadores de autoincremento (++) y autodecremento (-~) Operadores que su- ‘man y restan 1, respectivamente. Hay dos formas de incrementar y deeremen- tar: prefija y posttja. ‘operadores de igualdad En Jav != se usan para comparar dos valores: de- welven true 0 faise (segtin corresponda). operadores logicos Son &, || y |, ¥ se usan para simular los conceptos Y, Oy NO del dlgebra de Boole operadores relacionales En Java son <, <=, > y >=, y se usan para decidir cus es ‘el mayor 0 el menor de dos valores; devueiven true 0 false. ‘operadores unarios Requieren un operando. Se definen diversos operadores uns fios, entre los que se encuentran el menos unario (~) y les operadores de ‘autoincremento y autodecremento (++ y ~~). paso de pardmetros por valor Mecanismo de paso de parimetros de Java en el ‘que Ios argumentos reales se copian en los parémeiros formals. secuencia de escape Se usa para representar algunas constantes de tipo cardcter. signatura Combinacién del nombre de! método y les tipos de la lista de parime- 110s. El tipo del resultado no forma parte de la signatura, sobrecarga del nombre de un método Consiste en permitir a varios métoxlos, tener el mismo nombre mientras los tipos de la lista de parémettos sean dis- Uintos. tipos enteros byte, char, short, int y lon tipos primitives En Java soa los enteros, nin ccaracteres. Unicode Conjunto internacional de caracteres que contiene mis de 30,000 earac- teres distintos, los cuales cubren los principales lenguajes escrito, os en coma flotante, bookeanes y Errores comunes 1. _Afiadir un panto y coma innecesario produce errores I6gicos, pues el pun to y coma representa la instruccién vacfa, Esto significa que un punto y coma a continuacién de una instrucciéa for, while 0 if puede pasar inadvertide y estropear el programa. 2. En tiempo de compilacidn, Java es capa de detectar algunos casos en les ‘que un método que se supone que devuelve un valor. falla al hacerlo. Pero cen Gltimo lugar, es su responsabilidad el recordar devolver un valor. 3. Uno delante de un ndmero convierte una constante entera en octal; Luego 037 es equivaleate al decimal 31 4. Usar cs y || para las operaciones légicas: & y | no evalian en ciclo corte. 5. Lacliusula ese se asocia a la cliusula if mis intema sin emparejar. Es habitual olvidar incluir las Haves necesarias para asociar un else con un ££ alejado. 6 Cuando se use una instruccién switch, es habitual olvidar la instruccién break entre los casos légicos. Cuando esto sucede, el control pasa al si- guiente caso; lo que, en general, no es el comportamiento deseado. 7. Las secuencias de escape comienzan con la barra inclinada hacia atras \, ‘cenit Aes deeiianetitie Saakes iid 2 8. _Llaves sin emparejar pueden dar lugar a respuestas errSaeas 0 engaiiosas. Usar conprobarSqui Librados, descrito en la Seccidn 11.1, para com- probur si ésta es la causa de un mensaje de error del compilador. 9. El nombre del fichero que conticne el eédigo fuente del programa debe ser igual que el nombre de ta clase que se esta compilando. Java En Internet Indicamos a continuaci6n los ficheros disponibles correspondientes a este capftu- Jo, Todos ellos son autocontenidos. y no serdn posteriormente utilizados en el tex- to. Los programas se encuentran en el directorio Chapter. FirstProgramjava Nuestro primer programa. que aparece traducido en la Figura 1.1 MinTest,java Para ilustrar el uso de los métodos, que aparece traduci- do en la Figura 1.6. OperatorTest.java Demostracién del uso de varios operadores. Aparcce . traducido en ta Figura 1.3 Ejercicios Cuestiones breves 1. {Qué extensiones se usan para los ficheros fuente y compilados en Java? Descritu los tres tipos de comentarios usados en Java, {Cases son 1os ocho tipos primitives en Java’? {Cuil es Ia diferencia entre los operadores * y *=7 Explique las diferencias entre los operadores de is fijo. 1.6. Deseriba los tes tipas de bucle en Java 1.7. Deseriba todos los usos de una instruccién break 1.8. {Qué hace ln instruccién do? 1.9. {Qué es la sobrecarga de métodox? 1.10. Deserta el paso de pardmetos por valor. sremento prefijo y post- Problemas tedricos 1.11. Supongamos que b tiene el valor $y ¢ el valor 8, ;Cusil es el valor de a ¥ © después de la ejecucién de cada una de las Vineas del siguiente frag~ ‘mento de programa’? a= bes sors; a=be + tte: ae seb seus a= stb + sc; SP. eteisremnaties ARCOM Ai irae ttn ae ° 1.13. Busque un ejemplo en el que el bucle fox de la izquierda no sea equiva lente al bucle whi le de la derecha: for( inic; test; actual) while( test) i H instrucciones instrucciones actual; E ) ) L.14, :Cu‘les son las posibles salidas de este programa? public class QueEsx c public static void f(int x) (7* cuerpo desconocido */ } public static voidmain( string [ } args) ‘ int x= 0; f(x); system.out.printIn| x): Problemas practicos 1.15. Escriba una instruccién white que sea equivalente al siguiente fragmento for. {Para qué podria ser esto dil? for(::) instruccién 1.16, Escriba un programa para generar las tablas de suma y maltiplicacién de ‘iimeros de un s6lo digito (las tablas que los estudiantes de la escuela ele- ‘mental estén acostumbrados a memorizar).. 1.17. Presente dos métodos estéticos, el primero de los cuales debe devolver el maximo de tres enteros, mientras que el segundo devolvera el maximo de ‘cuatro enteros. 1.18, Escriba un método extético que tome un aiio como parimetro y devuelvs exue cuando el alto sea bisiesto. Prdcticas de programacion 1.19, Escriba un programa que produzca todos los pares de enteros positives, la BY talec me ac hc 1000 v (a +h + 1)(ad) sea entero. 1.20. Escriba un método que dado un nimero entero, muestre su representaciéa fen mimeros romanos. En particular, si el dato es 1998, Ia salida serfa MCMLXLVITT. 1.21. Supongamos que quefemos mostrar nimeros cnire corchetes, con el siguiente formato: (1 (2) [3]. etc. Escriba un método que tome dos pa- rimetros: cuantos y longl.inea. Fl método debe mostrar los nimeros de linea desde 1 hasta cuantos en el formato antes mencionado, pero no debe mostrar més de longtinea caracteres en cada linea Ademés, no debe empezar con el correspondiente a un nuevo mimero a menos que pueda escribir en 1a misina Iinea el comespondiente. 1.22, Enel siguiente puzzle aritmético, se asigna un digito a cada una de las di- ferentes letras. Escriba un programa que encuentre todas las soluciones po- sibles, a comtinuacién mostramos una de ellas. MARK Re BaS 9147 + ALLEN L=6 Ke7 1=8 Meo + 16653, 25800 Bibliografia Una parte del material en el estilo de C ussdlo en este capitulo se ha tomado de [5]. La especificacién completa del lenguaje Java se puede encontrar en [4]. En [3] se listan algunos paquetes de librerfas y se proporcionan ejemplos completos. Algu- ‘nos libros introductorios de Java son {1] y [2 1. G. Comell y C. S. Horstmann, Core Java, 3.* ed. Prentice-Hall, En _glewood Cliffs, NJ (1998), 2. J. Lewis y W. Loftus, Java Sofiwure Solutions: Foundations of Program Design, Addison-Wesley, Reading, Mass, (1997). 3. D, Flanagan, Java in a Nutshell, 2. ed., O'Reilly and Associates, Sebasto- pol. Calif. (1997) 4. J. Gosling, B. Joy. y G, Steele, The Java Language Specification, Ad- dison-Wesiey, Reading, Mass, (1996) 5. M.A. Weiss, Efficient C Programming: A Practical Approach, Prentice- Hall, Englewood Cliffs, NJ (1995). ta posible sogenda edison de ene texts wilisarian ag ‘ep le pesentactn on slgaos ponon, La wfereace [1 del Tengu oe pan se Bw wy CAPITULO 2 Referencias nel Capstulo | hemos estudiado los tipos primitivos de Java. Todos los ti [Pos que no sean ninguno de fos ocho tipos primitivos de Java son tipos refe- rencia, incluyéndose en estos siltimos entidades tan importantes como las cadenas de caracteres, los vectores y los canales de E/S. En este capitulo veremos: © Qué es un tipo referencia y qué es un valor. ‘© En qué se distinguen los tipos referencia de los tipos primitivos, ‘+ Ejempley de tipos referencia, incluyendo las eadenay de caracteres, los vec~ tores y los canales de E/S. '* Cémo se emplean las excepciones para detectar comportamientos erréneos, 2.1 gQué es una referencia? EL Capitulo 1 describe los ocho tipos primitivos, junto con algunas de las opera iones que se pueden realizar con sus elementos. Todos los demas tipos de Java son tipos referencia, incluyendo las cadenas de caracteres, los vectores y los fiche- ros. Pero, (qué es una referencia? Una variable referencia (0. simplemente referencia) en Java es una variable que guarda la direccién de memoria en la que se almacena un objeto, Por ejemplo, en la Figura 2.1 hay dos objetos de tipo Punto. Supongamos que estos abjetos estin almacenados en las posiciones de memoria 1000 y 1024, res- pectivamente. Para ambos existen tres referencias: puntol, puntod y punto3. Puntol y punto3 referencian al objeto situado en la posicion 1000 y punto2 re- ferencia al objeto situado en la posicién 1024. Observe que las direcciones de los ebjetos, como 1000 y 1024, son asignadas por el compilador de forma arbitraria (Siempre que encuenire memoria disponible), por lo que estos valores no son atiles externamente como mimeros. Sin embargo, el hecho de que punto y punto} ‘almacenea valores idénticos es Wil: significa que estin referenciando al mismo objeto. Una referencia siempre contiene la direceién de memoria en la que un objeto ‘esté guardado, a menos que no referencie a ningdn objeto. En este caso, almacena la referencia nula, i211. Javea 20 pormile sefeseacias a variables primitives. oo [70.07 = coo rors | (5.12) — (ae 100) sz0y | pointz = 1924 sooo | pine = 1000 pina aie 3124 | points = 1000 (ae 1028) pines Figura 21 Represeniacion gratica de una refetencia: el objeto de tipo Punto ‘imacenado en ia poscién de memoria 1000 es referenciado por puntol ¥ punto3. El objeto de tipo Punto almacenado en la post ‘clén de memoria 1024 es referenciado per punt.o2. Las pesiciones de memoria donde se guarcion las variables son orbitrarias Existen dos amplias eategorfas de operaciones que pueden a bles referencia. Una de elas nos permite examinar © manipular el valor referencia. Por ejemplo, si modificamos el valor almacenado en puntot (1000) pasariamos a estar referenciando a otro objeto. También podemos comparir pantol y punto3, y determinar si estin referenciando al mismo objeto. La otra categoria de opera ‘ciones se aplica al objeto referenciado; es posible examinar o cambiar el estado interno de uno de los abjetos de tipo Punto. Por ejemplo, podemos averiguar las ‘coordenadas.x ¢ y de algunos Puntos. ‘Antes de describir qué puede hacerse con referencias, vamos a ver lo que no esti permitido, Considéreve la expresién punto1*punto2. Como los valores al ‘macenados por punt.o1 y punto2 son 1000 y 1024, respectivamente, su producto deberia ser 1024000, Sin embargo. éste es un eélculo sin sentido que no tendria ninguna utilidad. Las variables referencia almacenan direeciones de memoria, y no puede asociarse ningtin significado Kégico al producto de dos direcciones de memoria, Andlogamente, punt.o1 ++ no tiene sentido en Java; esta expresidn sugiere que unto1 —1000— deberia incrementarse a 1001, pero en ese aso podria no refe- ‘enciar a un objeto vélido de tipo Punto. Muchos lenguajes de programacién defi- nen el puntero, que se comport como una variable referencia. Por cl contrario, los ppunteros de C++ son mucho mas peligrosos, pues se permiten operaciones aritmé- ticas sobre las direcciones de memoria almacenadas. Asien C++, puntot ++ tie- ne sentido, Adcmés, C++ permite punteros a tipos primitives, por lo que s¢ debe ser cuidadoso al distinguir entre calculos con direcciones de memoria y céleulos con los objetos referenciados. Esto se hace explicitamente desreferenciando el panicro. En la préctica, os inseguros punteros de C++ causan numerosos ertores de programacién En Java los tinicos operadores permitidos para manipular los tipos referencia (con una tinica excepeisn en el caso de los Strings) son las asignaciones via =, y ts Gietinines Bb eaidel teal ne La Figura 2.2 ilustra el operador de asignacién para variables referencia. Asig- nando a puntos el valor almacenado en punto? se consigue que punto3 referen- cie al mismo objeto que punto? estaba referenciando, Ahora punto2==punto3 es true ya que punto? y punto3 almacenan el valor 1024, y por lo tanto, refe- rencian al mismo objeto, punvol !=punto2 es también cieto ya que puntol y punto? referencian objetos distintos, La otra categoria de operaciones maneja el objeto que estd siendo referencia- do, Sobre él s6lo pueden realizarse tres acciones basicas: 1. Realizar una conversién de tipes (Seecién 1.44), 2. Acveder a un campo interno o invocar a un método, empleando el opera- dor punto (..) (Seccién 2.1). Emplear el operador instanceof para comprobar que ¢l objeto almace- nado es de un tipo determinado (Secci6n 3.6.3). La siguiente seccin muestra con mis detalle las operaciones con referencias mas comures, 1000 | (0,0) = on 5.12) wana tt 7 (de 1000) s200 | poine2= 1028 340 | poinei = 1000 oink si2s | poinea = 1028 = (de 1024) POIRES Figura 2.2 £ resultado de punto} =punto2: chore punto’ referencia el mmo cbjeto que punto?, 2.2 Nociones bdsicas sobre objetos y referencias En Java, un objeto es un elemento de cualquiera de los tipos no primitives. Los objetos son tratados de forma diferente a los valores de los tipos primitives. Los tipos primitivos. como hemos visto. se manipulan por valor. es decir, los valores supuestos para las variables primitivas se almacenan en dichas variables y son co- plados de unas a otras en fas asignaciones. Como se ha explicado en la Sec cin 2.1, las variables referencia guardan referencias a objetos. Fl objeto actual se almacena en aletin lugar de la memoria, y la variable referencia guards la posicién de memoria del objeto, Asf, una variable referencia representa simplemente un geen fin cones thes On: ta itaaie ins dain atkins wees en cual tect las variables referencia se comportan de forma diferente. Esta seceién estudia con ‘més detalle dichas diferencias ilustra las operaciones permitidas con variables referencia. 2.2.1. El operador punto (.) El operador punto (.) se emplea para seleccionar un método y aplicarlo a un obje- to, Por ejemplo. supongamos que se tiene un objeto de tipo Cixculo, en el que se define el método arcs. $i eiCixculo referencia a un Cixculo, eatonces pode- mos cakcular e! érea del circuo referenciado (y guardarta en una variable de ti- po double) haciendo lo siguiente: double elArea = elCirculo,area( }; Es posible que ezcixcule contenga la referencia nul. En este caso, el empleo del operador punto generard una tiuitpointerSxception cuando el programa se ejecute. Generaimente, esto causaré Ia terminacién anormal del programa. ~ El operador punto también puede emplearse para aceeder 3 las componentes individuates de un objeto, suponiendo que se han hecho los preparativos neces rios para hacerlas observables. El Capitulo 3 muestra cémo se realizan dichos pre- Parativos, Se explica ademas Ta raz6n de por qué es generalmente preferible no Permitir acceso dinecto a las componentes individuales 2.2.2 Deciaraci6n de objetos ‘Ya hemos visto la sintaxis adecuads para declarar variables primitivas. En el caso de los objetos existe una diferencia importante. Cuando se declara una variable re- {erencia, simplemente estamos indicando un nombre que puede emplearse para re- ferenciar un objeto almacenado en memoria, Sin embargo, I declaracién. por si misma, no genera exe objeto, Por ejemplo, supcngamos que existe un objeto de tipo Button que descamos afadir en un Pane p dado, empleando para ello el método ad (todo ello definido en las librerfas de Java). Para hacerlo uuilizarfamos las instrucciones Battonb: // epuede referenciar aun objeto de tipo Button b.settabel ( *No* }; // La etiqueta del botén bes p-2d8(b); // bse nade al panel p ‘Todo parece estar bien hasta que recordamos que b es el nombre de un objeto de tipo Button, pero que atin no se hut creado ninguno de ellos. Como resultado, después de la declaracién de b el valor almacenado por la variable referencia b es nil, indicando que b todavia no apunta a ningtin objeto vilido de tipo Button, Como consecuencia, 1a segunda linea es incortecta ya que esti intemtando alte- ‘ar un objeto inexistente. En este contexto, el compilador detectars el error, indi- cando que © no esti inicializada. En otros casos, el compilador no detectard el fa- Wo y se produciré un error durante la ejecucion, obtenigndose el criptico mensaje WLicterkbevcion. " Una forma de almacenar un objeto (la dnica comin a todos los tipos referen- cia) es emplear la palabra reservada new. new se utiliza para construir un nuevo objeto, Un modo de hacerlo es el siguie' Button by b puede referenciar aun objeto de tipo Button b=newButton|); // Ahorabreferencia a un objeto creado b.setLabel( "No" }; // Lact iqueta del boténbes 'No” p-add(b): 1)» #e-ahade 21 panal p Obsérvese que se necesitan los paréntesis tras el tipo del objeto. También es posible combinar la declaracién y In construccién de un objeto, ‘como en Button b-newButten! 7 b.setiabel( "No" }; // La etiqueta de botén bes “No p.adé( b}: bse afade al panel p Muchos objetos pucden construirse dandoles un valor inicial. Por ejemplo, el objeto de tipo Button puede consiruirse con un String que sea su etiqueta: Button b= new Button "Not }; p.add(b): // se afiade al panel p 223 Recogida de basura Como todos los objetos deben construirse, podriamos suponer que cuando uno ya no se vaya a emplear mis, debemos destruirlo explicitamente. En Java, evando un objeto creado no es referenciado por ninguna variable referencia, la memoria que consume es reclamada automaticamente y pasa a estar disponible. Esta técnica se eonoce como recogida de basura. 224 Elsignificado de = ‘Supongamos que se tienen dos variables primitivas 1 2q y 2der, donde emplea- mos 112q y 1der para denotar los lados izyuierdo y derecho, respectivamente. Entonces, la instrucci6n de asignaci lizg= Ider: tiene un sencillo significado: el valor almacenado en 1dex es copiado en ta variable primitiva 14.24. Los cambios posteriores en alguna de las vaciables no afectan a kt otra En los objetos, cl significado de - es el mismo: los valores almacenados se co- pian, Si 1i2q y Ider son referencias (de tipos compatibles), después de fa in- struceién de asignacin, 1 2q seftalari el mismo objeto al que Laer apunta, Aqui lo que se copian son las dirceciones. El objeto al que 12q referenciaba dejard de fer refesenciado por esta variable. Si 1izq era la Unica referencia a ese objeIo, top sen ore et bie Jon rect on ost veut cute see 1g esp ink sig feta, oh entonces dicho objeto se encuentra ahora desteferenciado por lo que serd incluide cn la préxima recogida de basura. Observe que los abjetos no se copian, ‘Yeamos algunos ejemplos. En primer lugar, supongamos que se quiere tener ddos objetos de tipo But ton. Intentamos lograrlo comenzando por crear noBot on, Después creamos ¢: Boton modificando noBoton del modo siguient Button noBoton = new Button( Wo"); Button sipoton = noBoton; siBoton.setLabel | *Si* ); p.ada( noBoton }: P-add( siBoton }; Esto no funciona ya que s6lo ha sido creado un objeto de tipo Button, De este ‘modo, 1a segunda instruccion simplemente indica que si8oton es otf nombre para el botén creado en Ia primera linea. Dicho botén tiene ahora dos nombres. En la tercera linea, cl objeto de tipo Button construido ha cambiado su etiqueta Or Si., pero esto significa que el tinico objeto Button, identificado por dos nom- bres, se etiqueta ahora con $i. Las dos dltimas Kineas aifaden al Pane? p el objeto “sutton dos veces, EL hecho de que siBoton nunca consulte su propio objeto carece de importan- cia en este ejemplo. El problema es la asignacién, Considere Button noBloton = now Button( *o* Button sigoton = new Button( ); siBoton = nokoton, siBcton.cottabel ( "Sit } p-aca( nosoton }; -add( sigoton }: Las consecuencias son exactamente las mismas. Ahora s{ han sido generados dos ‘objetos Button, pero al final de la secuencia el primer objeto esti referenci Por noBoton y si8oton, mientras que el segundo objeto est sin referenciar, A primera visia, el hecho de que los objetas no puedan copiarse parece una limitacién importante. En realidad no lo es, aunque cuesta un poco acostumbrarse (Para ser exactos algunos objetvs s{ necesitan ser copiudos. Para ellos, si esta dis~ ponible un método cione. debe usarse. clone invoca a new para obtener una ré- plica del objeto. Sin embargo, clone no se utiliza en este libro.) 2.2.5 Paso de parametios A causa del paso de pariimetos por valor, los parmetros actuales se pasan en Iu- ‘gar de los parimetros formales empleando la asi un tipo referencia, entonees ya sabemos que Ia asignaciGn significa que el pardme ‘so formal ahora referencia al mismo objeto que el parimetro actual. Cualquier ‘método aplicado al parémetwo formal se aplica también al parimetro actual, En ‘otros lenguajes esto se conoce como paso de pardmetros por referencia, Emplear esta terminologia en Java podria provocar equivocos, pues harfa pensar que et paso de pardimetros es diferente. En realidad el paso de pardmetros no ha cambia- do en su lugar, son les parimetros los que han variado, pasando de corresponder a tipos no referenciales a corresponder a tipos referencia 2.26 El significado de == En los tipos primitives, == ¢s verdadero cuando los valores almacenados son idén ticos. En los tipos referencia su significado es diferente, aunque totalmente consis- tente con la discusién previa Dos variables referencia son iguales via == si ambas apuntan al mismo objeto (0 bien son las dos nu), Consideremos, por ejemplo, la siguiente secuencia de asignaciones: Button a=newButton( ‘Sit ); Button b= new Button( “Si ); Buttonc=b: Aqui se han generado dos objetos. El primero es accesible mediante el nombre a, ‘mientras que cl segundo se accede con cualquiera de los dos nombres, b y c. En consecuencia b==c es true. Sin embargo, aunque a y b estén referenciando obje- tos que parecen tener el mismo valor. a==b eS false. ya que apuntan a objetos dlistinios, Para != s¢ aplican reglas similares. En algunas ocasiones es importante conocer si los objetos referenciados son idénticos. Todos los objetos pueden compararse mediante equals, pero para mu cchos (incluyendo los de tipo Buc ton) equals devuelve false a menos que am- bas referencias estén apuntando al mismo objeto (en otras palabras, para algunos ‘objetos equals noes otra cosa que el test ==). En la Seceidn 2.3, donde se estudia 1 tipo String, veremos un ejemplo en cl que equais resulta muy stil 22.7 Sobrecarga de operadores para objetos Salvo para la excepciGn descrita en la seccién siguiente, los operadores no pueden definirse para ser aplicados sobre objetos. Asi, no existe ningtin operador < dispo- nible sobre ningiin tipo de objetos. En su Tugar, deberiamos definir para realizar cesta funcién un métode con identificador, como por ejemplo, menorQue. 2.3 Cadenas de caracteres Las cadenas de caracteres en Java se manipulan mediante el tipo string. El len- ‘guaje hace aparecer a String como un tipo primitivo ya que define la + y cl ope- rador += para la concatenacién de cadenas. Pero éste es el tinico tipo referencia para el que la sobrecarga de operadores esté permitida. Por lo demés, el tipo ‘String se comport como cualquier otro tipo no primitivo. kak os pu em soa sab) rete oot te et cue 2.3.1 Conceptos basicos de a manipulaci6n de strings Exxisten dos reglas fundamentales sobre el tipo Sting. En primer lugar, se con porta como cualquier otro tipo no primitivo, a excepein de lo que hace referencia it los operadores de concatenacin. En segundo lugar, el tipo Seeing es inmuta ble, Esto significa que, una vez que un objeto sexing sc ha creado, su contenido no puede modificarse, ‘Como un String es inmutable, siempre es seguro emplear el operador == con A Aat w atctng pode declare del rma gum String vacia ane Stringmensaje = “Hola String repeticion =mensa: Después de estas declaraciones, se ha creado dos objetos String. El primer de ellos es la cadena vacia, referenciada por vacia. El segundo es el String *Hola*, referenciado por mensaje y repeticion. En otros casos la doble re- ferencia mediante mensaje y repeticion podria generar algin problema. Sin embargo, como los Strings son inmutables, Ia comparticién de objetos de tipo String es segura a la vez que eficiente. El tnico modo de modificar el valor que repeticion esti referenciando es crear un nuevo String y hacer que repeticion lo referencie. Esto no tiene efecto alguno sobre el String que refe- rencia mensaje. 2.3.2 Concatenacién de cadenas Java no pemnite la sobrecarga de operalores para tipos referencia, Sin embargo, tenemos una excepciéa en ta concatenacidn de cadens, El operador + realiza la concatenacién cuando, al menos, uno de los operandos. €8 Un String. El resultado es una referencia al objeto de tipo String recién construido, Por cjemplo, ste" +"aquel* —// Ganera "esteaquel* ‘abe +5 / Genera “ate! 5+ "abet 1/ Genera "Sabe* tats this ter / Genera "abe Las cadenas de un solo caricter no deben reemplazarse por caracteres indi dusles; el Ejercicio 2.5 pide explicar el porqué. Observe que el operador + es aso- , <=, >=) no estén definidos para el tipo string. Mas atin, == y t= ticnen cl significado usual para las variables referencia. Asi, para dos objetos de tipo String, liza y 1der, Lizge=ider es true solo cuando ambos referencian al mismo objeto String. De modo que. si referencian dos objetos distintos con el mismo contenido, 1izq==1der es fase. Para {~ valen rizonamientos similares. Para comparar la iguaklad de dos objetos String empleamos equals. Lizq-equals (Ider) es true si Lizg y Ider referencian Strings que almace- nan valores idéaticos. Una comprobacién més general puede realizarse con el método conpareto. Lizq.compareTo (Ider) compara dos objeios String, 1izq y Ider. Se devuelve un niimero negativo, cero 0 un niimero positivo, segdn 1 zq sea menor, igual o mayor que ier. respectivamente. 2.3.4 Otros métodos del tipo String ‘La Tongitud de un objeto string (la cadena vacfa tiene longitud cero) puede obte- rerse con el método Length. Como Length es un método, es necesario emplear aréntesis. Se tienen definidos dos métodos para acceder a los caracteres individuales de un String, El método charat obtiene un solo cardcter, especificando pposicién (la primera posicién es 1a posicién 0). El método substring devuelve tuna referencia a un nuevo String. La llamada se realiza especificando la posicién de inicio y la primera posici6a no incluida. ‘Veamios a continuacion un ejemplo de estos tres métodos: String caludo = *hola; (/rones 7ehes *0° String eub=saludo.cubetring( 2, 4)7 //eubes ‘la 23.5 Conversion entre cadenos y tipos primitivos El método tastring puede emplearse para convertir cvalquier valor de tipo pri- itivo en un objeto de tipo scring, Por ejemplo, toString(45) devuelve una referencia al recién creado String 745°. Muchos tipes tienen implementado el método toString, De hecho, cuando el operador + tiene un solo argumen- to String, el argumento que no lo es se convierte aulométicamente en una ca~ dena aplicando tostring. Para los tipos de enteros, una forma alternativa de toString permite la especificacién de ln base de Ia representaci6n. Asi System.out .printin( Integer -tostring( 55,2) 1: ‘Leiba la temncimabaasies Woniie te: Para cock rec mote com coat ote abe ene met cha sub resp, cos ble ble sez El valor de tipo ine representado por un String puede obtenerse Hamando al método Integer. parseint. Este méwdo genera una excepcin siel string no representa un valor de tipo int. Las excepciones se estudian en la Seccién 2.5 Para obtener un valor double a partir de un string es necesario mis trabajo. Aqui se muestran algunos ejemplos: int x= Integer-parseint ("75"); double y = Double.valueot ( ~3.14~ ) .doublevalue( ) 2.4 Vectores Un agregado es una coleccién de entidades almacenadas en una unidad. El vector «sel mecanismo bisico pars almacenar una coleccidn de entidades del mismo ti po. En Java el vector no es un tipo primitivo, pero se comporta de forma muy si- milar al testo de los objetos. Asi, muchas de las reglas de los objetos pueden apli- cease también a los vectores ‘Cada entidad en el vector puede ser aecedida mediante el operador de indexa- + cid de vectores | ). Decimos que el operador [ } indexa el vector en el sentido ‘de que especifica qué objeto debe ser accedido. A diferencia de C y C+, el che- «queo de los limites se realiza automiticamente En Java, los vectores se indexan comenzando siempre en cero. Asi, un vector a de tres elementos almacena a{0),a(1) y a2). El mimero de elementos que puede ser almacenado en un vector 3 se obtiene con a .1engtth. Observe que en esta oca- sign a0 hay paréntesis. Un bucle tipico para revorer un vector se basarfa en for (int 4 = 2: i Figura 2.3. Una simple mucstia de vectores. Esto significa que as variables representadas por el vector indexado son moxki bes. Este serd siempre e caso. Notese tambien que una inruccign como vectorFormal = new fat (20 1; no tiene ningin efecto sobre vectorActual. Finalmente, como les nombres de Jos vectores no son otra cosa que referencias, pueden devolverse como resultados. 2.4.2, Expansi6n dinémica de vectores ‘Supongamos que queremos leer una secuencia de nimeros y almacenarlos en un ‘vector para su procesamiento. La propiedad bisica de un vector es que debemos especificar su tamaio para que el compilador pueda reservarle la cantidad de me~ ‘moria adecuada. Ademis debemos realizar su declaracion antes del primer acceso al vector. Si no tenemos idea a priori de cusintos elementos deheremos manejar, es dificil realizar una elecci6n razonable de dicho tamaho. Esta secciGn muestra c6- ‘mo expandir vectores si su tamafo inicial resulta ser al final demasiado pequetio Esta téenica recibe el nombre de espansién dinimica de vectores y nos permite almacenar en memoria vectores de cualquier tamaio, agrandindolos © empedue: fieciéadolos durams in ejecuci6n ée! programa. El método de almacenar vectores en memoria que hemos visto antenormente es int (]aenew int (1017 Suponga que después de las declaraciones, observamos que necesitaremos 12 valores de tipo int en lugar de 10. En tal caso podemos emplear la siguiente es- trategia int [1 origina: 1, Se guarda una referenciaaa a=new int (121 // 2. Sa exea una referencia con més memoria for (int 4=0; 1 < 10; i##) //3. Secopian los datos antiguos, alilsoriginall il: Examinando detenidamente el cédigo anterior legamos a la conclusién de que ésta es una operacién costoxa, Esto es debido a que se copian todos los elementos de original en a. Si, por ejemplo, esta expansidn se produce como respuesta una entrada de daios, serfa ineficiente aumentar el vector cada vez que se lean uunos pocos datos. Por esta razéa, cuando se implementa la expansidn de vectores, Jo hacemos de modo que el tamato aumente segdin una constante multiplicativa Por ejemplo, en cada paso podemos expandirlo duplicando su longitud, De esta forma, cuando alargamos un vector de N elementos a 2 elementos. el coste de N ‘copias puede distribuirse sobre los siguientes N elementos, que pueden ser inserta- dos en el vector sin necesidad de expanditlo. ara mayor detalle, la Figura 2.4 muestra un programa que lee una cantidad itimitada de enteros de Ia entrada estindar y almacena el resultado de la lectura en un vector que se expande dinmicamente. La rutina reajustar realiza la expan: sidn del vector (0 su contraccién), devolviendo una referencia al nuevo vector. De forma andloga, el metodo 1eezEnteros devuelve una referencia al vector donde se almacenan los datos, 'Al principio de leerint eros, elon-eidos se inicializa a 0-y se comienza la Iectura con un vector de cinco elementos. La lectura reiterada de Tos datos se reali- za en las Kineas 28 y 30. Si el vector est Ileno, hecho que se comprueba en la tinea 31, el vector se expande llamando a rea3justar. En las lineas 44 a SO el vector se agranda aplicando la estrategia comentada. En la linea 33, ¢1 dato que acaba de ser leido se inserta en el vector y el contador de datos introducidos se incrementa. Si se produce un error en la lectura, se detiene la ejecucién del programa. Por dltimo, cn la linea 38 se reduce el tamafo det vector part ajustario al ndmero de datos leidos. 2.4.3 Vectores multidimensionales En algunas ocasiones es necesario acceder a un vector a través de varios indices. Un ejemplo tipico son las matrices, Un vector multidimensional es un vector en el ‘que el acceso a un elemento se realiza empleando mas de un indice. La cantidad ‘de memoria que se le reserva se determina al especificar el tamatio de sus indices. ‘Accedemos a cada clemento colocando cada {ndice entre su propio par de corche- tes. Por ejemplo, la declaracion int |) (} x=newdnt (21031; ggeee nul our bu g un vat smport java.to public class Les c public atatic void min( string [ int (] vector = leerEnteros( ) for( int i = 0; 1 < vector.length; iss ) Systen.out.printin( vector! £1) 1/ da exrorea; devuelve un int { } public static int [ ] leermnteros( ) //BatferedReader se estudia en BufferedReader in 1 2 3 4 5 6 7 8 ° 10 Ml // tee una cantidad ilimitada de ints sin recuperacién 2 3 “ 15 Seccién 2.6 6 new BufferedReader( new v ‘InputstreanReader( systen.in ) ) ant entradavar int [ ] vector new int{ 5] 2» int elembeidos = 0. a String unabineas 2 B Systen.out.printIn( "Introduce una cantided cualquiera’ + ry "de enteros. une por linea: * ) 5 ey 2% ‘ 7 while( ( unauinea = in.readLine( ) | t= mull } 2 t » fontradaval = Integer.parsoznt( unaLines ) 30 LE( eleateides == vector.1ength ) 2 vector = reajustar( vector, vector.length * 2}; 2 vector{ elenbeidos++ | = entradaval 3B u > 3 catcn( Exception e } ( } // No se procesan los errores % Systen.out.printla( ‘Lectura finalizada’ ) a return reajustar( vector, elonteldos }: 4 9 0 Reajustar e1 int{ ] vector; devuelve el mevo vector 41 public static int (} reajustar( int [ ] vector, int nueveTananyo ) a { “ Ant [ } original = vector; “a int munCopia = Math.min( original length, muevoTamanyo |: 45 6 vector = new int muovoTamanyo a for( int 10; 1 < muscopla; i++) 3 vector{ i] = original i 1; 9 return vector: mo) s1) Figure 2.4 Cédigo para loor uno cantidad limitada de ints y devolvelor como salda. define el vector bidimensional x, con el primer indice tomuando valores entre 0 y 1 y el segundo movigndose entre Oy 2 (para guardar un total de seis cbjetos). El ‘compilador asigna seis posiciones de memoria a dichos objeios 24.4 Argumentos de Ia linea de comandos Los argumentos de la linea de comandos aparecen cuando examinamos el pardme- tro de main. El vector de cadenas de caracteres representa los argumentos adi rnales de Ia linea de comandos. Por ejemplo, cuando se ejecuta el programa, Java Beo este aquel args{0} referencia al String “este" y args(1] referencia al string aque!" El programa de la Figura 2.5 implementa el programa #0, 1 public class Bee 20 3 // mueetra 1oe argunentos de 1a Linea de comandos 4 public static void main( string ( ] args) so 6 7 a for( ant 4 = 0; 4 < arge.lengen — Systen.out.print| argel $] + °°): A€( args.length != 0 ) system.cut.printin( args args.length ~ 11): 10 else un Systen.cut.printin| ‘Mo hay argunentos que mostrar i 4 > Figuie25 Ei comondo eco, 2.5 Manejo de excepciones Las excepciones son elementos que almacenan informaci6n y la transmiten fuera de la secuencia normal de retorno de datos. Las excepeiones se propagan hacia at ris a través de la secuencia habitual de llamada, hasta que sean recogidas por al ‘guna rutina, Se emplean para detectar hechos excepeionales, como por ejemplo, cerrores. 25.1 Procesamiento de excepciones El codigo de la Figura 2.6 muestra el empleo de excepciones. El cédigo que even tualmente puede generar una excepcidn se encierra en e! bloque try. El bloque tery se extiende desde la linea 1$ hasta Ia linea 19. Inmediatamente después del bloque try se encuentran los manejadores de excepciones. Esta parte del cdigo se ejecuta slo si se produce una excepcidn. En el momento en el que ésta se lun- za, el Bloque txy del que procede se considera finalizado. Cada blogue catch se prueba en orden hasta encontrar un manejador de excepciones adecuado. Con avooas import java.io." public class Divideror c public static void main{ String [ ) args ) c / BufferedReader se discute en la Secciéa 2.6 feredReader in - new BufferedReader ( new inputstreanteader( System.in ) )7 String unatineas System.out.printin( "Introduce un entero: * unaLinea = in.zeadbine( ) x = Integer.parserat( unalines ); System.out.printin( "La mitad de xes * + (x /2) 5 catch( Exception ¢ ) 1 2 3 4 5 4 7 a 9 10 nu 2 13 “4 15 1“ 0 18 w 2 21 ( System.out.printin( e): ) 2 3 , Figura 2.6 Un programa sencilo pore iustor las excepciones. Except ion ineluye los tipos de todas las excepciones de nuestro interés, recoge cualquier excepcidn generada por el blogue ey. Mas coneretamente, estas excep- ciones son del tipo ToException, genenulas por readLine si se produce algiin error inesperado de lectura, y del tipo NunberFormat Except ion, generadas por parsernt, si unalinea no es convertible a entero. ‘Una vee capturada la excepcisn correspondiente se ejecuta el cddigo del blo- que catch —en nuestro caso la linea 21—. Entonces este bloque y el que contie- ne la combinacién try/catch' se consideran terminados. En el ejemplo se im- prime un mensaje significative para cl objet e de tipo Exception. Como alternativa, podria realizarse un procesamiento adicional o bien darse mensajes de 25.2 Laclausula finally Algunos objetos construidos en el blogue txy deberfan ser eliminados antes de concluir la ejecucién del mismo. Por ejemplo, los ficheros que se abrea en el blo- que exy necesitan cerrarse antes de abandonar dicho bloque. Uno de los proble- ‘mas que aparece es que si se lanza una excepeién dentro de un bloque tr, ka eli- ‘minacién podria no producirse al causar la excepeién la salida inmediata del bloque try. Aunque la eliminacién de los objetos puede realizarse jusio después del ultimo bloque cats, esto silo es efectiva si la excepeién es recogida por al- zuna cldusula catch, y esto es difieil de garantizar con seguridad 2 catch mauiren um logue de lnsruccones en Mpa de ne fsrucion ti, por oq a Haves mo son ‘iladores anteriores de Je acepuan, deforma crvénea, edge qpe ao tachuye ts eves nocenaan Lacliusula £ina11y que sigue al titimo bloque catch (0 al blogue try si no hay ningin blogue catch) se emplea en estas situaciones. La cléusula finally consiste en la palabra clave finally seguida del bloque finally. Existen tres situaciones bisicas: 1. Siel bloque try se ejecuta sin generarse excepciones, el control pasa al logue Final iy. Esto es asi atin cuando el bloque Exy termine antes de alcanzar su Gitima instrucci6n, mediante un return, break @ continue. Si se produce una excepeidin dentro del blogue try que no es recogida, el ‘control pasa al blogue finaly. Tras ejecutar éste la excepeidn se propaga, Si se produce una excepcién dentro del bloque try que es revogida en un catch posterior, el control pasa al bloque catch correspondiente. Tras ‘ejecutarse, se procesa el blogue finaly, 25.3 Excepciones més comunes En Java existen muchos tipos de excepciones estindar. Las excepciones run-time (oem tiempo de ejecucisn) incluyen eventos como la divisiGn-por-cero de enteros Yy los accesos ilegales a vectores. Como estos eventos pueden producirse cast en cualquier punto, serfa agotador incorporar constantemente manejadores de excep- ciones para ellos. En cualyuier caso, si se especifica para ellos un blogue catch, estas excepciones se comportan como cualquier otra, Pero si no se especitica nin- uno, se lanza una excepci6n estindar que se propaga de la forma usual, pudiendo sobrepasar ma in. En este caso el programa termina de forma andmiala, presentan- ddo un mensaje de error. En la Figura 2.7 se muestran algunas de las exeepeiones ‘run-time més wsuales. ‘La mayoria de las excepciones son del tipo standard checked. Si un método puede lanzar una de estas excepciones directa o indirectamente, el programador debe definir el bloque catch adecuado para ella o indicar de forma explicita que Excepciones Run-time Signiticodo Despocamiento 0 civisin entera por coro. arithneticException Conveniin legal de un string aun tee | aneroo. NunberFormatException IndexOutofSoundsException | Acceso @ un elemento nexistente de un vector ode un Strinc. Negat iveArraySizeException | Intonto do creacién do un vector de | longtud negative, Nul1PointerException Intento de uso de una referencia nua, Violacién de la seguridad en tempo de ejacucién. SecurityBxception fique27 Excepciones run-time més comunes. peaesn Ia excepcidn va a propagarse, incluyendo para esto Gltimo la eldusula throws en Ja declaracin del método, Observe que antes © después deben definirse mane} ddores para elias, ya que el método main no deberfa tener cliusula throws. En el Capitulo 4 se muestra cémo definir nuevos tipos de excepeiones. En la Figura 2.8 se recogen algunas de las excepciones mis usuales de este tipo. Los errores son excepciones, pero no se ajustan al tipo Exception. Tipica- ‘mente son irrecuperables. E] error mis comin es OutofMemoryzrrer. Para cap- {urar cualquier excepcidn posible debe recogerse un objeto Throwable. Excepciones Checked Significado java. io, EOPException Final de fichero antes de lo esperado, Java. io.FileNot FoundExcept ion | Fchero inevistente, Java. io. IOException Incluye muchas excepciones de E/S. InterruptedException Lanzada por 0! método ‘Thread.sleep. Figura 2.8 Eacepciones standard checked més comunes. 2.5.4 Las cléusulas throw y throws EL programador puede lanzar una excepcién empleando la ckiusula throw. Por ejemplo, podemos lanzar una excepci6n de tipo Exception mediante throw new Exception( "Nalas Noticias" }; Normalmente, no se lanzan excepciones del tipo Exception, sino que se lan- an excepciones definidas por el usuario. Los detalles de esto se explican en el Capitulo 4 ‘Como se ha mencionado anteriormente, las checked deben ser recogidas © propagadas explicitamente hacia ta rutina que ha realizado a lamada, pero en algunas ocasiones, y como titimo recurso, deben procesarse en main. Para hacer esto iitimo, ef método que no desea capturar la excepcidn debe indicar, a través de la ckiusula enows, qué excepeiones se van a propagar. La cliusula throws se escribe al final de la cabecera del método, La Fi- ura 29 muestra un método que propaga las excepciones del tipo ToException que encuentra, éstas deben ser recogidas en main (ya que n0 incluremos una cliusula throws en main) 2.6 Entrada y salida La entrada y salida (ES) se realiza en Java empleando el paquete java.io. La instruccisn eet Seed. be. import Java.io.*: 1 2 3. public class DenoThrow ac 5 public static void procesaPichero( String Fichero ) 6 throws IOException 7 ‘ 8 // esta implenentacion omitida propaga cualquier 7/ YoException hacia 1a rutina invocadora ) public static void main( String [J args) c for( int 4 = 0; 4 < argo.length; iss) c uy { procesaFich catch( ToBxception ¢ } ( system.cut.printin( e ); , Figura 2.9 Musstia de la cléusiia throws ‘debe aparecer en cualquier programa que empice las rutinas de E/S de un modo no trivial. La librerfa de Java es bastante compleja y tiene multitud de opciones. EXa~ minaremos sélo las mas bisicas, concentrindonos por completo en la E,S con for- ‘mato. 2.6.1 Operaciones basicas de E/S Contamos con tres canales predefinidos para realizar la F/S mediante el terminal system.in, que es la enirada estindar, System. out, que es la salida usual, y System.err, para la salida de errores, ‘Como ya hemos mencionado, los métodos print y print in se emplean para Ja salida con formato, Gracias al método toString, un valor de cualquier tipo puede convertirse en un String que puede imprimirse; en muchos casos esta transformacién es automstica. A diferencia de C y C++, que tienen multitud de opciones de formato, la salida de Java se realiza, casi exclusivamente, mediante la ‘eoacatenacién de Strings sin formato alguno, Un modo sencillo de realizar la Iectura de la entrada es leer una sola linea, al- ‘macenindola en un objeto de tipo string, para lo que se emplea reaaLine. Esie método lee hasta que encuentra un final de linea 0 el final del fichero. Los caracte- +e leidos, salvo el final de linea (en el caso de que se encuentre), se devuelven co- ‘mo un nvevo String. Para emplear vead:ine, se debe construr primero un objeto BufferedReader sobre un objeto tnputStreanReader. que a Su Vez se crea Par tiendo de System. in. Esto se muestra en las lineas 8 y 9 de la Figura 2.6. Observe ue las TOExcept ion son del tipo standard checked, Por 10 que, en algunos casos, deben ser recogidas. En muchas situaciones, se permite que la z08xception $e propague hasta un bloque catch del métedo main; esta técnica se ilustra en Ia Figura 29. lo 3) oe 26.2 Elobjeto StringTokenizer Recuerde que para leer un solo cardcter de tipo primitive, como un int, se debe cemplear ‘Beis S Gemerer es cemin al bones ie cireincercnions' tipo int. Todos los errores, incluyendo el producide cuando no se obtienen exac- tamente dos tokens, son tratados en el bloque catch. Como es habitual, con un mayor esfuerz0 se podian generar mejores mensajes de error Por defecto, los tokens se separan mediante expacios en blanco. El StringTokenizer puede construirse de modo que reconozca otros caracteres co mo delimitadores,o para considerat dichox delimitadores como tokens 2.6.3 Ficheros de acceso secuencial Una de las reglas baisicas de Java es que lo que funciona en la E/S con el terminal también funciona en la E/S con ficheros. Para trabajar con un fichero no construi- ‘mos un objeto BufferedReader a partir de un InpatStreanReader, sinoa partir de un FLieReader, que es creado a su Ye7 especificando el nombre de un fichero, En la Figura 2.11 se muestra un ejemplo que ilustra estas ideas bisicas. Se trata de un programa que imprime el contenido de los ficheros de texio que se 1 Smport java.io." 2 3. public class ContonidoFicheros ac 5 public static void main( string [ ] args Bho At 7 At( args.lengtn == 0 ) 8 system.out.printin( 'No se especitican ficheros* 2 for| int £ $< args.length: i++) 10 contenidoFichero( ares{ i) ) u , n 13 public static void contenideFichero( String nonbreFichero ) uf 5 PileReader e1richere, 6 BufferedReader lector = nulls v7 String unaLinea; 8 v Systen.out .printin( *Pichero: * + nombreFichero } DB uy 2 c 2 elFichero = new FileReader( nombrerichero } B lector = new BufferedReader( elP: er while( (unatinea = 2B Syeten.out-printial uns 26 ) 2 catch( Exception © | 2 ( Systen.out.printan( e); } a x 1) Cherre del fickero ET uy 2 3B Af(ector {= null ) “u Tector.close( 3: 3s d 38 eatch( roRxception ©) () Pe scat ae indiquen en la linea de comandos. La rutina main simplemente recoge los argu: ‘mentos de la linea de comandos, pasando cada uno a cont enidoFichero. En contenidoPichero s construye el objeto Fi leReader en Ia linea 22, que se cemplea para crear el objeto BufferedReader ~ Lector ~ en la linea 23, A partir de este punto la lectura es igual a la ya explicada. Después de terminar con un fichero, debemos cerrarlo, ya que de otro modo podrfamos quedarnos sin cunales. Observe que esto no puede hacerse al final del bioque try. pues una excepciGn causaria Ia salida del bloque prematuramente. En consecuencia, cerramos el fichero tras Ia secuencia ery /catch. Como todos los errores recuperables estin incluidos en Except ion, no es necesaria una cldusula Finally. Estamos seguros de alcanzar la instruccién de cierre de fichero, por si hay ms trabajo que hacer. La salida con formato es similar a 1a entrada con formato. Como no 1a usare~ ‘mos en este texto, remitimos al lector a cualquier referencia de Java si desea cono- cer los detalles de la misma, Resumen En este capftulo hemos estudiado los tipos referencia. Una referencia es una varia- ble que almacena, 0 bien una direceién de memoria donde se almacena un objeto, ‘bien una referencia especial nu11. S6lo pueden referenciarse los objetos, aunque un objeto puede ser referenciado por mas de una variahle. Cuando dos referencias ‘son comparadas via ==, el resultado es true si ambas referencias apuntan al mis- ‘mo objeto. De forma similar, = hace que una variable referencia apunte a otro ob- jeto, Las referencias pueden manipularse con muy pocas operaciones. La mas im- pportante es la representada por cl operador punto, que permite la seleccién de un método de una clase, o bien el acceso a sus atributos internos, Debido 2 que en lava sélo existen ocho tipos primitives, casi cualquier cosa es ‘un objeto accesible a través de una referencia, Esto incluye lay cadenas de caracte= res, Jos vectores. los objetos de la clase Exception, Jos canales de entrada y sali- da de datos y el Stringtokenizer. El string es un tipo referencia especial pues sobre ef mismo estén definidos los operadores de concatenacién + y +=. Por lo dems, un String se gomporta como cualquier otra referencia; asf, se necesita equal. para comprobar si los es tados de dos strings son identicos. Un vector es una coleccidn de elementos de! mismo tipo. El vector se indexa partiendo de 0 y se garantiza el chequeo del ran- 0. Los vectores se pueden expandir dinimicamente, usando new para asignar ‘mayor cantidad de memoria y copiando después los elementos uno a uno. Las excepciones se emplean para detectar eventos excepcionales. Una excep cin se lanza mediante la cléusula throw, y se propaga hasia que es recogida por algun bloque catch asoxiado a un blogue try. Excepto para las excepciones en tiempo de ejzcucién (run-time exceptions) y los Brrores, cada método debe indi- car las exeepeiones que puede propagar empleando la eliusula throws. El stringTokenizer se emplea para partir un String, obteniendo nue- vos Strings. Normalmente se emplea junto a otras rutinas de procesamiento de Je entrada. La entrada se manipula a iravés de los objetos BufferedReader. InputStreanReader y FileReader a Bia a Ni i Elementos del juego agregado Coleccién de objetos almacenados en la misma unidad, argumento de la linea de comandos Empleado como parimetro del método, atributo Length Usado para conocer la longitud de un vector bloque catch Se emplea para el procesamiento de excepciones. bloque txy Comprende el eddigo que puede generar una excepci6n. BufferedReader Se emplea para e! procesamiento linea a linea de la entrada, concatenacién de eadenas Realizada a través de los operadores + y += construccién Para los objetos se efectia mediante la palabra reservada new. entrada y salida (E/S) Implementada en e! paguete java. io, equaie Se emplea para comprobar si los vallores de dos objetos almacenados son iguales. Error Fxcepci6n imecuperable excepeiin del tipo standard checked Debe ser recogida 0 declarada expli mente en Ia ckdusila throws del método correspondiente excepelin run-time No necesita ser declarada. Ejemplos notables son arLthnetictxcept ion y Null PointerException excepeién Sirve para detectar situaciones excepcionales tales como errores, expansién dindmica de vectores Permite aumentar el tamano de los vectores. ‘cuando ello sea preciso, FileReader Empleaclo cuando la entrada se efectia por fichero. finally Se ejecuta siempre antes de salir de un bloque try /eatch. inmatable Se dice de un objeto que no puede cambiar de estado. Por ejemplo, los seeings son inmutables. Java.4o Paquete que debe ser importado para producir cualquier salida no trivial Java.uti2 Paguete que debe ser importado para poder emplear el objeto StringTokenizer, Liza y Ider Variables empleadas para indicar los lados izquierdo y derecho, res tivamente, iméindo tengtn Usa pars conocer a longi de una cadena de carctres new Empleado para crear un nuevo objeto. nat Valor de una variable referencia que no apunta a ningin objeto. mull fointertxception Generada cuando se intenta acceder a una referencia ull. ‘objeto Eniidad no primitive. operador de indexacién de vectores { } Pesmite el acceso a cada elemento de un vector, ‘operador punto (.) Permits el acceso a cada componente de una estructura [Paso por referencia En muchos lenguajes de programacién significa que el par metro formal es una referencia al parimetro actual. Este es el efecto producido cen Java cuando el paso por valor se utiliza sobre un tipo referencia. recogida de basura Recuperacidn automsitica de la memoria que ya no es referen- cada, Stzing Objeto especial empleado para almacenar una secuencia de caracteres. StringTokentzer Empleado para obtener Strings delimitados a partir de una tal ee Bann Hanne een, zal system. in, dyatem.out y Syatem.err Canales de ES predefinidos. ‘throw Empleado para lanzar una excepcion. ‘throws Indica que un método puede propagar una excepeisn. tipo referencia Cualquier tipo no primitivo, tostxing Convierte un tipo primitivo, o un objeto, en un string. vector Almacena una colecci6n de elementos del mismo tipo. vector multidimensional Vector cuya manipulacién requicre varios indices, Errores comunes Para tipos referencia y vectores, = no ace una copia de los objtos sino de las referencias. Para tipos referencia y cadenas de caracteres, para comprobar si dos objetox ticnen exactamente el mismo estado debe emplearse equels en lugar de == Los errores por salida de rango son habituales en todos los lenguajes de programacién Los tipos referencia se inicializan a nuit por defecto; es decit, no se Construye ningtin cbjeto nuevo sin haber llamado previamente a new. Una swatiable referencia sin iniializar» 0 la Nl! Pointer Exsept ion indica {que el programador ha olvidado crear un objeto En Java los vectores se indexan desde 0 hasta N~2, donde 1! es el tamaito dol vector. El acceso a components fuera de ese range se detecta de for ‘ma automitica en tiempo de ejecucion. Los vectores bidimensionales se indexan como Ai) (41 y no como AGS Las excepciones standard checked deten ser recogides, 0 declaradas en Ia cliusula throws del método correspondiente para permitir su propagacign Debe emplearse " ~ cn lugar de ° *, para mostrar un espacio en blanco. En Internet A continuacién mostramos los ficheros disponibles para este capitulo, Todos ellos son autocontenidos y no wuelven a utilizarse en el resio del texto, Se encuentran’ ene directorio Chapter 2 DivideBytwo,java Cédigo correspondiente a la Figura 2.6, Es la versién inglesa de la clase DiviaevorDes. eho java Cédigo correspondiente a la Figura 2.5. Es la versién inglesa de la clase ee. Listiles,java, Codigo correspondiente a la Figura 2.11. Es la version inglesa de la clase ContenidoFicheros Lottery,java Cédigo correspondiente a la Figura 2.3. Es la versién inglesa de Ia clase Loteria. ‘MaxTest java Cédigo correspondiente a la Figura 2.10. Bs la versién inglesa de la clase mazrest. Readintsjava_ Codigo correspondiente a la Figura 2.4, Es la version Seofienn cis Seclien Venuhenetbliaheeen a Ejercicios Cuestiones breves 2.1, Enumere las principales diferencias entre tipos referencia y tipos primitivos. 22. 24, 2.6. 27, 2.8. 29, 240. Enumere cinco operaciones que pueden ser aplicadas a 10s tipos referencia, Deseriba emo funcionan las excepciones en Java, Enumere las principales operaciones que pueden realizarse con cadenas de caracteres, Problemas tedricos Si x ey tienen los valores 5 y 7. respectivamente, determine la salida de la system.out.printin( x!) 4y): systen.out.printin( x7" +y)i Problemas practicos Un estsum es el entero 32-bit calculado sumando todos les caracteres Ur code de un fichero (se permite Desbordamientotnferior silencioso, ‘aunque éste es improbable cuando todos los caracteres son ASCID). Dos fi- ccheros iguales tienen el mismo testsum. Escriba un programa que calcule el testsum de un fichero cuyo nombre se introducird en Ia linea de coman- dos. Modifique el programa de ia Figura 2.11 de modo que no se introduzca ningsin parimetro por la Iinea de comandos, sino que se utilice Ia entrada cestindar, Escriba un método que devuelva true si String stri es un prefijo de ng atx2, No debe emplear ninguna rutina de biisqueda de cadenas de ccaractetes, excepto charat. Practicas de programacién Escriba un programa que muesire la cantidad de caracteres, palabras y i reas de los ficheros que se indiquen en Ia Ifnea de comandos. Implemente un programa de copia de ficheros, Incluya un test que se ase- ‘gure de que el fichero de origen y el de destino son diferentes. Necesitard leer alguna referencia sobre Java para aprender a programar la salida de datos en fichero. Referencias ‘Se puede encontrar mas informacién en las referencias listadas al final del Capi CAPITULO 3 Objetos y clases Una componente fundamental de Ia programacién orientada a objetos es la especificacin, implementacién y uso de abjetos, En el Capitulo 2 vimos ak unos ejemplos de objetos, incluyendo las cadenas y los ficheros, que son parte de 1a librerfa obligatoria de Java. También vimos gue estos objeto tienen un estado interno que se puede manipular aplicando el operador punto para seleccionar un iétodo. En Java, el estado y Ia funcionalidad de un objeto vienen dados por la finicién de una clase. Un objeto es una instancia de una case En este capitulo veremos c neste capitulo se comienza a estudiar la programacién orientada a objetos. + Como usa Java las clases para conseguir encapsulacién y ocultamiento de informacion. ‘© Cémo se implementan y se documentan de forma automética las clases # Cémo se agrupan las clases en paquetes. 3.1 Qué es la programacién orientada a objetos? La programacidn orientada a objeios parece estar surgicndo como el paradi dominante de los noventa, En esta secciGn se estudian algunos elementos de la orientacién a objetos que soporta Java y se mencionan algunos de los principios de la programacion orientada a objetos. EI corazén de Ia programacién orientaca a objetos es el objeto. Un objeto es un tipo de datos con estructura y estado, Cada objeto tiene definidas operaciones que pueden acceder a ese estado 0 manipalarlo. Como ya hemos visto, en Java lox objeios se distinguen de los valores de los tipos primitivos. pero ésta es més bien luna caracterfstica de Java que de la programacién orientada a objetos. Ademiis de ejecutar acciones generales, podemos hacer Io siguiente: ‘© Crear nuevas objetos, posiblemente con un valor inicial ‘= Copiar © comprobar la igualdad. © Realizar E/S sobre esos objetos. También vimos el objeto como una unidad aidmica que el usuario no deberta pretender diseccionar. La mayoria de nosotros ni siguiera pensaria en jugar con los, bits que representan a un nimero en coma flotante, y considerarfamos completa ‘mente ridiculo el intentar incrementar nosotros misinos un némero en com fo tante alterando sa representacién interna. El principio de atomicidad se conoce como ocultamiento de la informacién, El usuario no tiene acceso directo a las partes del objeto 0 a su implementacidn; sola rmente se puede acceder a ellas de forma indirecta a través de métodos proporcio- rados junto con el objeto. Podemos pensar que cada objeto viene con el aviso «No abrir —partes no utlizables por el usuario». En la vida real, la mayorta de la gente ‘que intenta arreglar las cosas a pesar de tales avisos, termina produciendo mis perjuicio que beneficio. En este sentido, la programacién imita al mundo real. El agrupamiiento de datos y las operaciones que se aplican sobre ellos, forman un agregado, mientras que el ocuitamiento de los detalles del agregado, se conoce co- sm encapsulacién. Un objetivo importante de la programaci6n orientada a objetos es soportar la reutilizacién de eédigo. Al igual que los ingenietos usan las misma componentes repetidamente en sus diseios los programatiores deberfan ser capaces de reutiizar sabjetos en lugar de implementarlos repetidumente, Cuando tenemos una imple- rmentacién del objeto exacto que necesitamos usar, la reuilizacién es simple. El problema esté en uilizar un objeto disponible cuando no es exactamente el que se necesita, sino solamente uno muy parecido. Los lenguajes orientados a objetos proporcionan varios mecanismos para satis~ acer este objetivo, Uno es el uso de codigo generico. Si la implementacion es ntica independientemente del tipo de los abjetos sobre los que se splica, no hay necesidad de rescribir completamente cl cédigo: en lugar de ello, se escribe el e6- digo genéricamente, de forma que funcione para cualquier tipo. Por ejemplo, la I= ‘gica usada para ordenar un vector de objetos es independiente del tipo de lox abje~ tos que s€ estin ordenando, de modo que se podfa usar un algoritmo genético, El mecanismo de herencia nos permite extender Ia funcionalidad de un objeto. En otras palabras, poxlemos crear tipos nuevos con las propiedades del tipo orig nal restringidas (0 extendidas). La hetencia nos permite avanzar un Fargo trecho hacia el objetivo deseado de reutilizacién de c6digo. Otro principio importante de la programacién orientada a objetos es el poli ‘morfismo. Un tipo referencia polimérfico puede referenciar objetos de varios tipos diferentes. Cuando se aplican métodos al tipo polimérfico. se selecciona automat ccamente la operacién apropiada para el objeto referenciado en ese momento, En Java, esto se implementa como parte de la herencia. El polimorfismo nos permite implementar clases que comparten una Kigica comtin. Como se estudia en el Capf- tulo 4, esto se aplica reiteradamenic en las librerfas de Java. El uso de la herencia Para crear estas jerarquias distingue la programaciGn orientada a objetos de la mas simple programacién hasada en objetos. En Java, los algoritmos gen mplemenian como paste de la herencia. En el Capitulo 4 se estudia la herencia y el polimorfismo. En este capitulo, descri- bimos cémo Java usa las clases para conseguir encapsulacién y ocultamiento de Un objeto en Java es una instancia de una clase. Una clase es similar a una estructura en C o un registro en Pascal 0 Ada, excepto porel hecho de que hay dos mejoras importantes. En primer lugar, las componeates pucden ser funciones 0 datos, las cuales se conocen respectivamente por métodos y atributos. En segundo lugar, se puede restringir Ia visibilidad de dichas componentes. Puesto que los mé- todos que manipulan el estado del objeto son componentes de la clase, se accede a cllos mediante el operador punto, al igual que a los atributos. En la terminologia de la programacién orientada a objetos, cuando hacemos una llamada a un méto- do, estamos pasando un mensaje al objeto. 3.2 Un ejemplo sencillo Recuerde que cuando esté disefiando una clase. es importante ser capaz de ocultar los detalles internos al usuario de la clase. Esto se consigue de dos formas, En pri- ‘mer lugar, 1a clase puede definir su funcionalidad mediante componentes de ase, lamadas métodos. Aleunos de estos métodas deserien cémo se crea ¢ ini cializa una instancia de la estructura, otros e6mo se realiza las comprobaciones de igualdad o cémo se leva a cabo la salida. Otras funciones sertan espectticas it la estructura particular. La idea es que los atributos internos que representan el esta- do del objeto no deberfan ser manipulados directamente por el usuario de la clase, sino solamente a través de los métodos. Esta idea se puede reforzar ocultando ccomponentes al usuario. Para hacer esto podemos especificar que se almacenen en tuna seccién privada. El compilador hard cumplir fa regla gue convierte a las com- ponentes de la secciGn privada en inaccesibles para el usuario del objeto. En gene- ral, todas las componentes de datos deberfan ser privadas En la Figura 3.1 se muestra una declaracién de clase para un objeto celdagntero!.La declaracién consta de des partes: una piiblica y otra privada, La seceign publica representa la porcién visible al usuatio del objeto. Puesto que expe ‘ramos ocultar los datos, en general solamente deberia aparecer métodos y constantes cn Ia seccién paibica. En nuestro ejemplo, tenemos métodos que leen y escriben en cl objeto celdarnvero, La sexeién privada contiene los datos: sta cs invisible pa- ra el usuario del objeto. Se debe acceder al atributo valorAlmacenado a través de las rutinas piblicas Leer y escribir; main no puede acceder directamente a ella, En la Figura 3.2 enconwramos una representacin grifica de la situaciGn, 1 // clase celdat 207) ant leer( ) --> Devuelve el valor alnacenado 3. // void eseribir( int x) --> Se almacena x 4 5 public class celdarntero ‘ 7 J/ Metodos publicos 8 public int leer| ) (return valorAlmacenado: 9 public void escribir( int x ) {valoralnacenado = x;} 10 n 1) Representacién interna privada del dato 12 private int valorAimacenado; 3) Figura 3.1._Uno daclaracién completa de una clase Celdaznt ero. * Recuerde que ls clases deen hn le > e cen lichens del isin nombee que Ia clase, Lucgo Cel dst Figura 3.2 Componentes de Celdaintero: leer y exer ibix son occetibler pero valorAlmacenado est acute, La Figura 3.3 muestra cémo se usan fos objetos de la clase Celdatntero. Puesto que Leer y escribir son componentes de la clase Celdazntera, se puede acceder a elias usando el operador punto. También se podria acceder al atri- but valoraimacenado usando el operador punto, pero debido a que es privada, el acceso en Ia linea 14 seria ilegal, si ésta no estuviera comentada, ‘A continuacién resumimes la terminologta. La clase define componentes, que pueden ser ctribuos (datos) 0 métodos (funciones). Los mStodos pueden actuar s0- bre los atributos y pueden Hamar a otros métodos. El modificador de visibilidad public significa que la componente es accesible para cualquiera a través del opera- «dor punto, El modhificador de visibilidad private significa que la componente sola- mente es accesible través de otros métods de esa clase. Si no hay modificador de vsibilidad, tenemos acceso amnistos, ef cual se estudia en la Seccion 3.5.4, Hay un ccuarto modificador conocido como protected. que se estudia en el Capitulo 4. //ejercieto con la clase Celdantero 1 2 3. public 1 ac 5 public static void main( string [| args ) 6 7 8 ‘TestCeldazntero t Celdatntero = = new Celdatatere( ); nuescrabir( 5) Systom.out .printin( ‘Contenidop de 1a celda: * +m.Leer( } ) J ta siguiente Linea rer{a ilegal oi no eatuviera comentada / porque valorAlmacenado es una componente peiveda 1 mvaloxaimacenade = 0; ? > Figura 33. Una rutina simple de comprobacién para mostrar cérno se accede © los objetos oe la cose Celdazntero, 3.3, Javadoc ‘Cuando se disefta una clase, la especificacién de la clase representa el disefto de la clase y nos dice qué se puede hacer sobre un objeto. La implementacién representa les detalles internos de emo se comsigue esto. En Io que respects al usuario, estos detalles no son importantes. En muchos casos, Ia implementacién representa in- formacién del propictario que el diseftador de la clase no desea compart. Sin ‘embargo, la especificacidn debe estar compartida, en caso contrario, no se podria ae ase la especificacién pero con ‘cultamiento de la implementacién se consigue colocando especificacién ¢ imple- mentacidn en ficheros fuente separados. Por ejemplo, en C+ la inerfaz de clase se coloca en un archivo con extensién .h, y la implementaciGn de la clase en un archivo .cpp. En el fichero la interfay de clase muestra los métodos (propor- ‘ionando las cabeceras de los métodos) implementados por la clase. Java tiene un enfogue distinto, Es facil ver que se puede documentar autométi- ‘camente una lista de métodos en una clase, con signatures y tipos del resultado, & partir de la implementacién. Java usa esta idea: el programa javadoc?, proporcio- nado en todos los sistemas Java, se puede cjecutar para generar autométicamente documentacién para las clases. La salida de javadoc es un conjunio de ficheros HTML que se puede ver 0 imprimir con un navegador. El fichero de implementacién también puede afladir comentarios javadoc que comiencen con el token /**. Dichos comentarias se aaden automticamente, de tuna forma uniforme y consistente, a la documentacién producida por javador, Hay también varias marcas especiales que se pueden incluir en los comenta- rios javadoc. Algunas de ellas Son Bauthor, @param, @return y @exception. En la Figura 3.4 se muestra el uso de los comentarios javadoc en la definicién de clases. En a linea 3, se usa la marca ¢autnor. Esta marca debe preceder tla deti- nicién de Ia clase, La linea 10 ilustra el uso de la marca @return, y la 19 el de la marea @param . Estas marcas deben aparecer antes de la declaracién de un ‘método. El primer token que sigue a la marca ¢paran es el nombre del pardmetro. La marca Gexception no se ilustra, pero tiene la misma sintaxis que @paran. Loe 2 + Clase para simular una colda de monoria para un entero 3 + Gauthor Mark A. Weiss a0 5 © public class celdazntero 74 aos 9 + obtiene el valor almacenado. 10 * Greturn el valor almacenado. u ” 12 public int leer ) BO 4 return valorAlmacenado: BY 6 oye 18 * xlmacena un valor. 1° + param » el nimero a alnaconar 2 ” 21 public void eseribir( int x ) 2 2B valoraimacenado mw 3 26 private int valorAlmacenado; a) Figura 4 Declorocién de Celdazntere con comentarios javadoc. PS eas Wik iden delat i alia ite a 30, pa, En la Figura 3.5 se muestra Ia salida que resulta de Ia ejecucién de javadoc. Ejecute javadoc proporcionando el nombre (incluida la extension . java) del fi- ‘chero fuente. Para obener dibujos para los construciores, métodos, etc. debe tener tun subdirectorio images en el directorio donde se generan los ficheros HTML. Sie O6- Shit Gelnencinconee Ran 34, {este subdirectorio es parte de la distribucién JDK y esta replicado en el codigo {que se suminisra en la red). ‘La salida de javadoc esté formada exclusivamente por comentarios, excepto cen el caso de las cabeceras de los métodos. El compilador no comprueba gue di- ‘chos comentarios estén implementados. A pesar de ello, nunca nos quedaremos ‘cortos al valorar la importancia de disponer de documentacién apropiada. javadoc hace més fécil la tarea de generar documentacién con un buen formato, 3.4 Métodos basicos Algunos métodos son comunes a todas las clases. En esta seccisn se estudia los imétodos modificadores y de acceso, y tres métodos especiales: los constructores, toString y equals. También se habla de los métodos estticos, uno de los ct les es mein, 3.4.1 Constructores Como se ha mencionado anteriormente, una propiedad basica de los objetos es que se pueden definir, posiblemente con un valor inieial, En Java, los métodos que Conirolan como se crea e inicializa un objeto reciben el nombre de consiructores. Gracias a la sobrecarga, en una clase se puede definir diversos constructores. Si no se proporciona ningn constructor, como en el caso de la clase Celdazntero de la Figura 3.1, se genera un constructor por defecto que inicializa ‘cada stributo usando los correspondientes valores por defecto. Esto significa que Jos atributos de tipo primitivo se inicializan a cero y los tipos referencia se inicia- lizan a la referencia nul 1. Por tanto, en el caso de Celdakntero, la componente valorAlnacenado es 0. Para escribir un constructor, proporclonamos un método con el mismo nombre due la clase y sin resultado. En la Figura 3.6 hay dos constructores: uno comienza cn la linea 7 y el otro en la linea 15. Usando estos constructores, podemos cons Imuir objetos Fecha de las dos formas siguientes: Fecha f1 = new Fecha( ); Fecha £2 = new Fecha( 15, 4, 1998): Observe que una vez que se escribe un constructor, ya mo se utiliza un cons- tractor por defecto sin parimetros. Si desea volver a contar con él tiene que escti= birlo explicitamente. Ast, el constructor de la linea 7 €8 ebligatorio para poder construir el objeto que referencia £1. 3.4.2. Métodos modificadores y de acceso Los atributos de una clase se declaran normalmente como privados. En conse- ‘cuencia, las rutinas que no pertenecen a la clase no pueden acceder directamente & ellos. Sin embargo, algunas veces nos gustaria examinar el valor de un atributo, € incluso podriamos querer cambiarlo directamente. Una altemativa para hacer esto es deciarar los atributos como pulblicos. sta es, sinembargo, ina eleccidn pobre. pues viola el principio de ocultamiento de in- formacién. En su lugar podcmos proporcionar métodos para examinar y cambiar cada atributo. Un méiodo que examina pero no cambia e! estado de un objeto es tun método de acceso. Un método que cambia el estado es wn modificador (pocque modifica el estado del objeto). Cases particulares de métodos de acceso y modificadores trabajan solamente sobre un aiributo, Estos métodos de acceso usualmente tendrén nombres que em piczan por obtener, como obtene:Mes, mientras que los modificadores ten dan nombres que comienzan por cambi.ar*, como canbiares. La ventaja de usar un modificador es que de esta forma podemos asegurar que Jos cambios realizalos cn el estado del objeto son consistentes. Ast, un mosifica- dor que cambie el atributo dia en un objeto Fecha nos garantizaré que solamente se generan fechas legales 343 Saliday tostring Normalmente queremos mostrar el estado de un objeto usando print. Esto se cconsigue definiendo un método toString* en la clase, Dicho método devuelve tn valor de tipo String apto para producir una salida, Como ejemplo, en la Figu- ra 3.6 se muesira una implementacién basica del mStodo costing para la clase Fecha. 344 equals El método equals se usa para comprobar si dos referencias deseriben el mismo valor. La signatura es siempre la siguiente public boolean equals ( Object Ider ) Observe que el parimetro es del tipo object. en lugar del tipo de la clase. El mé todo equals sobre una clase Nonbreclase se implementard de modo que de- vuelva true sélo cuando ider es una instancia de WonbreCtase y, si tras la con- versién @ NombreCtase, todos Ios atributos primitivos son iguales (usando ==) y todos los atributos referencia son iguales (usando una aplicacién componente & componente de eavals). En la Figura 3.6 se proporciona un ejemplo de c6mo se implementa equals. El operador instanceof se estudia en la Seccion 3.6.3, ‘ahs tees los tostrig, equal y compare70 mo se han tadcido yo que dchos mStados etinprdefnion para ct ‘ones datas on oa Ubro sobeovacriben 2 tos predofiniden, // Clase Fecha bésica para ilustrar algunas caracteriaticas de 7) Tava sin comprobaciones de error ni comentarios javadoc public class Foch t / Constructor de cero pardémetros public Fecha( ) c dia anyo = 1998 J Constructor de tres parémetros public Fecha( int elDla, int eiMes, int e1Anyo ) « aia = e1Dia; es = elMes; anyo = elanyo: / Devuelve true #i des valores son iguales public boolean equale( Object ler) c At 1 ( Ider instanceof Fecha) | return false; Fecha lderFecha = ( Fecha ) Ider: return lder?echa.dia == dia 6& lderFecha.nes AderFecha-anyo == anyo: J/ Convereién a string public string tostring( } t return dia + mes + */* + anyo; ) 11 Rexibutos private int dial private int anyor PBSSLSERESSSRENBRRESRB SSI sar TSI See vo mnen— 8 Figura 3.6. Uno clase Fecha bésica que llustta el uso de constuctores y los méto- dos oquale y toString. 3.4.5 Métodos static Un método estitico es un método que no necesita un objeto que lo controle. El mé- todo estitico ms comin ¢s main. En las clases String, Integer y Math se pue- de encontrar otros métodos estiticos. Algunos ejemplos son String .valuedt Integer.parsetnt, Math. ein y Math max. El acceso a los métodos estiticos utiliza las mismas reglas de visibilidad que los atributos estiticos. Recuerde del Capitulo 1 que algunos atributos de ta clase usan el modificador static. Usindolo, en conjuncién con Ia palabra final, obtenemos las constan- tes. Sin la palabra final, tenemos atriburos esidticos, que tienen otro significado Gidaln ‘eatiniledd en te Sherisn S64: un 0 3.4.6 main Cuando se usa el comando java para ejecutar el intérprete, se llama al método rain de Ia clase del fichero referenciado por el comando, Por tanto, cada clase ‘puede tener Su propia funciGn main sin ningun problema. Sin embargo, aunque asi se puede probar la funcionalidad, colocar nain en una clase proporciona a esta funcién més visibilidad que la que estarfa permitida en general. Por tanto, lama- das de main a métodos no pablicos tendran éxito en la prueba, aungue seran ilega- les en un entorno mis general 3.5 Paquetes Los paquetes se usan para organizar una serie de clases relacionadas. Cada paque- te consta de un conjunto de clases. Dos clases en un mismo paquete tienen restric~ Devuelve @l area (abstracts) ©) —-> Compara el rea de dos objetoe ==> Método tostring usual 10 MW. public abstract class Figura Ri 13 abstract public double area }: u 18 public Figura( string nombreFigura ) 6 nombre = aoabrerigura; | v 18 f4nal public boolean menorgue( Figura ier ) 1 {return area( ) < Ider-area( ); ) a 21 ‘final public String toStrina( ) 2% «= { return nombre + * con area" + area( Iz) 2B 26 private String nombres 3 Figure 45 La closo abstracto Figura, La Figura 4.5 muestra la clase abstracta Pigura. En la linea 24 se declara un String que almacena el tipo de la figura, Esto se emplea dnicamente en las cla ses derivadas. Este aributo es privado, asf que las clases derivadas no tienen acce- so directo a l. El resto de la clase especifica una coleecin de métodes. El constructor nunca se invoca directamente, ya que Pi gura es uma clase abs- tracta. Sin embargo, necesitamos un constructor. al que la clase derivada invocaré ‘cuando necesite inicializar los componentes privados. El constructor de Figura inicializa el atributo interno nombre. La linea 13 declara el método abstracto area. En tiempo de ejecucidin se decid ri el métado area adecuado de la correspondiente clase derivada, area €s un méto- do abstracto. ya que no tiene ningtin significado por defecto que pueda ser espec ceado para aplicarse sobre una clase heredada que opte por no implementarlo, EI método de comparacidn de figuras implementado en las lineas 18 y 19, no es abstracto ya que puede ser aplicado en todas las clases derivadas. De hecho, st

También podría gustarte