Anda di halaman 1dari 174

CertPrs8/Java 6 Cert.

Estudie Guide/Sierra-Bates/159106-0/captulo 7 ciega el folio 541

7
genricos y colecciones
objetivos de certificacin
L de L de L

Disee usando colecciones hacen caso de iguales () y hashCode (), distinguen == e igualan () use las versiones genricas de colecciones incluyendo ponga, liste, y el mapa

Use los mtodos de parmetros, genricos de 3 escritura de tipo usa java.util a Sort y la bsqueda usa comparable y taladro de dos minutos comparador propia prueba de preguntas y respuestas

L de L

542

Captulo 7:

Genricos y colecciones

los |enerics| son posiblemente la mayora de que se habla la caracterstica de Java 5. Ciertas personas les aman, ciertas personas les siente odio, pero estn aqu para quedarse. A su simple, ellos puede

ayudar muy

hacer cdigo

la

g
parte fcil de campo

duro para cubierta el ms cree,

la

mayor

el para escritura, y mantenga.

comn y y ms robusto. Afortunadamente, el exa til caractersticas, A su la mayor parte de men creadores y sobra exterior el estado hincado la mayor parte de complejo, ellos pueda para el simple fi el de el especialmente sea muy, n de genricos, tramposo bits. Cobertura de colecciones en este examen se ha expandido en dos vas del examen previo: el uso de genricos en colecciones, y la habilidad para clasificar y buscar por las colecciones.

objetivo de certificacin

haciendo caso de hashCode () e igualan () ( el objetivo 6.2 )


6.2 Distinga entre corrija y incorrecto hace caso de de corresponder hashCode y iguales mtodos, y explique el diferencia entre == y el iguales mtodo.

Es un objeto. Acostumbre se. Tiene el estado, tiene comportamiento, ha un trabajo. (O al menos sus oportunidades de la ganancia uno subir despus de pasar el examen.) Si excluya los primitivos, toda cosa en Java es un objeto. No slo un objeto , pero un objeto con un capital O. cada excepcin, cada evento, cada conjunto se extiende de java.lang.Object. Para el examen, usted no necesita saber cada mtodo en el objeto, pero necesitar conocer los mtodos listados en la tabla 7-1. Las cubiertas de captulo 9 esperan (), notifique (), y notifyAll (). El mtodo de
finalize () era cubierto en captulo 3. As en esta seccin nosotros miraremos a slo el hashCode () y igualan mtodos de () . Oh, ese exterior de cantos toString (), no haga lo. De acuerdo, cubriremos que en este momento porque ello toma dos segundos.

el mtodo de () de |tostring| hace caso


de toString () cuando usted quiere un de | mor| T simple para ser capaz de leer algo significativo sobre los objetos de su clase. El cdigo puede llamar toString () en su objeto cuando quiere leer los detalles tiles sobre su | ject| de |ob|. Cuando usted pasa una referencia de objeto al mtodo de () System.out.println, por ejemplo, el el mtodo de toString () de objeto es llamado, y el retorno de toString () es mostrado en el ejemplo siguiente:

Haciendo caso de hashCode () e igualan () ( objetivo de examen 6.2 )

543

tabla 7-1 mtodos de objeto de clase cubierto en el examen

Descripcin de mtodo
los iguales booleanas (|obj| de objeto) decida si dos objetos

son significativa equivalentes.


el vaco finaliza () llamado por el basurero cuando el basurero ve que el objeto no se puede referenciar. hashCode () de |int| retorna un valor de |int| de | hashcode| para un objeto, de modo que el objeto puede usado en clases de coleccin que usa picando, incluyendo Hashtable, HashMap, y HashSet.

el vaco final notifica () despierte un hilo que es esperando para la cerradura de este objeto. vaco final notifyAll () despierta todos los hilos que son esperando para la cerradura de este objeto. el vaco final espera () causa el hilo actual para esperar hasta otras llamadas de hilo notifique () o notifyAll () en este objeto. Encuerde toString () retorna una "representacin de texto" del objeto.

el pblico clasifica HardToRead{ la parte principal vaca esttica pblica (|args| de cuerda){ h de HardToRead = nuevo HardToRead(); System.out.println ( la h); } }

Correr la clase de HardToRead nos da el hermoso y significativo,


% H a r d T o R e a d H a r d T o R

e a d @ a 4 7 e 0 d e c a f

La salida precedente es lo que consigue cuando no hace caso del mtodo de toString
() del objeto de clase. Ello da le el nombre de clase ( al menos que es significativo ) seguido por el @ simbolice, seguido por la

representacin hexadecimal unsigned del | hashcode| del objeto. Trate de leer esta salida podra motivarle para hacer caso del mtodo de
toString () en sus clases, por ejemplo, el pblico clasifica BobTest{ la parte principal vaca esttica pblica (|args| de cuerda){ F de Bob = nuevo Bob ( " GoBobGo ", 19);

544

Captulo 7:

Genricos y colecciones

System.out.println ( la f); } } clasifique Bob{ int shoeSize; Apodo de cuerda; Bob ( encuerde apodo, |int| ShoeSize ){ this.shoeSize = shoeSize; this.nickName = apodo;

} el pblico encuerda toString () { retorne ( " soy un Bob, pero me puede llamar " + apodo + ". Mis zapatos el tamao es " + shoeSize); } }

Esto debe ser algo ms legible:


% BobTest de caf soy un Bob, pero usted me puede llamar GoBobGo. Mis zapatos el tamao es 19

Ciertas personas afectuosa se refieren a () como el " derrame se-sudesentrae el mtodo, " porque las ms comnes ejecuciones de toString () simplemente escupen el exterior el estado del objeto ( en otros trminos, los valores actuales de las variables de caso importantes ). Eso lo es para toString (). Ahora agarraremos () y hashCode () de iguales.
toString

hacer caso de () de iguales


Aprendi sobre el mtodo de equals ()
en captulos ms tempranos, donde miramos a las clases de envoltura. Nosotros discutimos cmo comparar dos se opone las referencias usando el operador de == evalan para ciertamente

slo cuando ambas referencias se refieren al mismo objeto ( porque == simplemente mira a los bits en la variable, y ellos es idntico o ellos no es ). Vi que la clase de cuerda y las clases de envoltura tienen el |overridden| los iguales el mtodo de () ( heredado del objeto de clase ), de modo que pudo comparar dos objetos diferentes (de el mismo tipo) para ver si sus contenidos son significativa equivalentes. Si dos casos de entero, nmero entero diferente ambos tenga el |int| valora 5 , hasta es interesado son iguales. El hecho que las 5 vidas de valor en dos objetos separados no importan. Cuando realmente necesita saber si dos referencias es idntico, use ==. Pero cuando necesita saber si los objetos se ( no las referencias ) es igual, use el mtodo de
equals () . Para cada clase usted escribe, debe decidir si ello tiene sentido para

Hacer caso de () de iguales ( objetivo de examen 6.2 )

545

considere dos casos diferentes igualan. Para ciertas clases, podra decidir eses dos objetos nunca puede ser igual. Por ejemplo, imagine un automvil de clase que tiene las variables de caso para cosas como marca, modelo, ao, configuracin -- usted no quiere desde luego su automvil repentinamente para tratarse como el mismo automvil muy como alguien con un automvil que tiene los atributos idnticos. Su automvil es su automvil y usted no quiere su Billy vecino manejar fuera en ello slo porque, " hey, es realmente el mismo automvil; los iguales el mtodo de () dicho as."as ningunos dos automviles alguna vez debe ser considerado exactamente igual. Si dos referencias se refieran a un automvil, entonces sabe que ambos estn hablando de un automvil, no dos automviles que tienen mismos atributos. As en el caso de un automvil usted no podra alguna vez necesitar, o desear, para hacer caso del mtodo de equals () . Por supuesto, sabe que
no es el fin de la historia.

Lo que lo significa si usted no hace caso de igualan ()


Existe un oculto potencial de limitacin aqu: si no haga caso de la s de una clase iguale mtodo de (), usted no ser capaz de usar esos objetos como una llave en un | hashtable| y usted no consigue probablemente los conjuntos exactos, tal ese no existe ningunos duplicados conceptuales. Los iguales el mtodo de () en los usos de objeto de clase slo el operador de == para las comparaciones, as a menos que hace caso de iguale (), dos objetos son considerados
iguales slo si las dos referencias se refieran a mismo objeto. Parecemos a lo que lo significa para no ser capaz de usar un objeto como una llave de | hashtable|. Imagina le tenga un automvil, un

automvil muy especfico ( diga, color rojo John llanura desrtica y rida de Subaru en oposicin al mini purpreo de Mary )que quiere poner en un HashMap( un tipo del |hashtable| que miraremos a ms tarde en este captulo ), de modo que usted puede buscar en un automvil particular y recupere el objeto correspondiente de persona que representa el dueo. As usted aade el caso de automvil como la llave al HashMap (conjuntamente con un objeto de persona correspondiente como el valor). Pero ahora qu sucede cuando quiere hacer una bsqueda? Usted quiere decir para la coleccin de HashMap, " aqu est el automvil, ahora da me el objeto de persona que armoniza con este automvil." pero ahora se halla en un apuro a menos que usted todava ha una referencia al objeto exacto usted usado como la llave cuando lo aadi a la coleccin. En casa otro palabras, usted no pueda marca un idntico Automvil objeto y uso ello para el bsqueda. La lnea fundamental es esto: si quiera objetos de su clase para ser usado como llaves para un |hashtable| ( o como elementos en cualquiera estructura de datos que usan la equivalencia para buscar - y/o recuperar un objeto ), entonces debe hacer caso de iguale () de modo que dos casos

diferentes pueden ser considerado el mismo. As cmo desearamos fijar el automvil? Podra hacer caso del mtodo de equals ()
de modo que ello comparan el nico VIN (nmero de identificacin de vehculo) como la base de la comparacin. Por all, puede usar un caso cuando lo aade a una coleccin, y esencialmente recrea un caso idntico cuando quiere hacer una bsqueda basado en ese objeto como la llave. Por supuesto, hacer caso de los iguales el mtodo de () para el automvil

tambin permite el potencial que ms de un oponga se representando un automvil nico sencillo pueda existir, que no pueda estar a salvo

546

Captulo 7:

Genricos y colecciones

en su diseo. Afortunadamente, la cuerda y envoltura clasifican trabaje bien como llaves

en |hashtables| -- hacen caso de los iguales el mtodo de () . As antes que usar el caso real de automvil como la llave en el automvil / dueo paree, pudo usar simplemente una cuerda que representa el identificador nico para el automvil. Por all, nunca habr ms de un caso representando un automvil especfico, pero usted puede todava usar el automvil - o ms bien, los atributos de uno del automvil - como la llave de bsqueda.

poner en prctica un mtodo de equals ()


dice que usted decide hacer caso de igualan () en su clase. Podra parecerse a esto:
el pblico clasifica EqualsTest{ la parte principal vaca esttica pblica (|args| de cuerda){ Moof un = nuevo Moof ( 8); Moof dos = nuevo Moof ( 8); si (one.equals( dos )){ System.out.println ( " un y dos es igual"); } } } clasifique Moof{ private int moofValue; Moof(int val) { MoofValue = valor; } public int getMoofValue() { retorne moofValue; } los iguales booleanas pblicos (o de objeto){ si Moof de |instanceof| de o de (( ) y ((( Moof ) o).getMoofValue() == this.moofValue )){ retorne ciertamente; } de otro modo{ retorne falsamente; } } }

parecemos a este cdigo en detalle. en la mayor parte mtodo de () de EqualsTest, nosotros crea dos casos de Moof, pasando el mismo valor 8 al constructor de Moof. Ahora mirada a la clase de Moof y a ver lo que ello hace con ese argumento de constructor -asigna el valor a la variable de caso de
moofValue. Ahora imagine que ha decidido dos objetos de Moof es el mismo si su moofValue es

idntico. As usted hace caso de el

Hacer caso de () de iguales ( objetivo de examen 6.2 )

547

mtodo de () de iguales y compare el dos moofValues. Es as de simple. Pero dejenos derrumbar lo que est sucediendo en los iguales el mtodo de () :
1. los iguales booleanas pblicos (o de objeto) { 2. si Moof de |instanceof| de o de (( ) y ((( Moof )o).getMoofValue() == this.moofValue )){ 3. retorne ciertamente; 4. } de otro modo{ 5. retorne falsamente; 6. } 7. }

Ante todo, usted debe observar todos los reglamentos de haciendo caso de, y en lnea 1 nosotros est declarando en realidad un vlido haga caso de de los iguales el mtodo de () que nosotros heredamos del objeto. La lnea 2 es donde toda la accin es. Lgicamente, tenemos que hacer dos cosas a fin de hacer una comparacin de igualdad vlida. En primer lugar, est seguro que el objeto ser examinando es del tipo correcto! lo entrar polimorfa como represente objeto, as que necesita hacer una prueba de |instanceof|
encima. Tener dos objetos de los tipos de clase diferentes es considerado el igual no es normalmente una idea buena, pero eso es un asunto de diseo que nosotros no examinaremos aqu. Adems de, usted ha todava tenido que hacer el |instanceof| pruebe slo para estar

seguro de que pudo lanzar el argumento de objeto al tipo correcto de modo que puede acceder sus mtodos o variables a fin de hacer en realidad la comparacin. Recuerde, si el objeto no pasa el |instanceof| pruebe, entonces conseguir un |runtime| ClassCastException. Por ejemplo:
los iguales booleanas pblicos (o de objeto){

si ((( Moof )o).getMoofValue() == this.moofValue){ // la lnea precedente compila, pero es BAD ! retorne ciertamente; } de otro modo{ retorne falsamente; } } (Moof) el lanzamiento de o fracasar si la o no se refiere a algo ese IS-un Moof. En segundo lugar, compare los atributos nosotros sea importante para uno ( en este caso, justo MoofValue ). Slo el

desarrollador puede decidir lo que haga dos casos igualan. (Para ejecucin mejor, usted va a querer verificar el nmero menos de atributos.) En el caso era un poco sorprendido por el entero (( Moof )o).sintaxis de getMoofValue (), estamos lanzando simplemente la referencia de objeto, o , justo-en tiempo como tratamos de llamar un mtodo que est en la clase de Moof pero no en el objeto. Recuerde, sin el lanzamiento, usted

548

Captulo 7:

Genricos y colecciones

no pueda compilar porque el compilador ver el objeto referenciado por la o como simplemente, bien, un objeto. Y despus que la clase de objeto no tiene un mtodo de
getMoofValue (), el compilador dira en voz chillona (tecnicismo). Pero entonces como dijimos ms temprano, an con el lanzamiento, el cdigo fracasa al |runtime| si el objeto referenciado por la o no es algo que es el

compuesto para moldear a un Moof. As alguna vez no olvide para usar el primero de prueba de |instanceof|. Aqu est otra razn

para apreciar el cortocircuito y el operador si la prueba de |instanceof| fracasa, nunca llegaremos al cdigo que hace el lanzamiento, as que somos siempre seguros en |runtime| con lo siguiente:

si Moof de |instanceof| de o de (( ) y ((( Moof ) o).getMoofValue() == this.moofValue )){ retorne ciertamente; } de otro modo{ retorne falsamente; }

De modo que cuide igualan ()...


Whoa...no es as rpidamente. Si parezca a la clase de objeto en el |spec| de Java API, usted encontrar lo que nosotros llamamos un contrato especifique en los iguales el mtodo de () .

un contrato de Java es un conjunto de reglamentos que se debe seguir, o ms bien se debe seguir si quiera proporcionar una ejecucin "correcta" como otros esperarn ello para ser. O para ponerlo otra va, si no siga el contrato, su cdigo puede todava compilar y corra, pero su cdigo ( o alguna otra persona ) pueda romperse en |runtime| en cierta va inesperada.

Recuerde que los mtodos de equals son todo el pblico .La cosa siguiente no puede ser un vlido haga caso de de los iguales el mtodo de (), aunque podra parecer ser si no mira estrechamente bastante durante el examen:
(), hashCode (), y toString () clasifique Foo{ los iguales booleanas (o de objeto){ } }

Y est a la mira del argumento teclean como well.The siguiendo mtodo es una sobrecarga, pero no un override de los iguales el mtodo de () :
abucheo de clase{ los iguales booleanas pblicos (b de abucheo){ } }

Hacer caso de hashCode () ( objetivo de examen 6.2 )

549

Est seguro le es muy cmodo con los reglamentos de haciendo caso de de modo que puede identificar si un mtodo del objeto est siendo |overridden| , sobrecargue, o ilegalmente en un class.The igualan mtodo de () en el abucheo de clase cambia el argumento de Object a Boo, as que ello se convierte en un mtodo sobrecargado y no ser llamado a menos que es de su propio cdigo que conozca este nuevo, mtodo diferente que suceda para tambin ser nombrado igualan ().

los iguales el contrato de ()

Tirado directamente de los |docs| de Java, los iguales () contrate dice


la n es reflexivo. Para cualquiera referencia valore x , x.equals (x) deba la n es simtrico. Para cualquiera referencia valore x y y , x.equals (y)

retornar verdadera.

deba retornar verdadera si y slo si y.equals (x) retorna ciertamente.


la n es transitivo. Para cualquiera referencia valoran x , y , y z, si x.equals (y) retorna
ciertamente y y.equals (z) retorna ciertamente, entonces x.equals (z) debe retornar verdadera.

la

invocaciones mltiples de x.equals (y) firmemente retorna ciertamente o firmemente retorne falsamente, provase ninguna informacin usada en iguala comparaciones en el objeto son modificadas. n para cualquier non- nulo referencia valora x , x.equals (cero) deba retornar falso. Y es as no del gancho todava. No hemos parecido al mtodo de hashCode (), pero

n es consistente. Para cualquiera referencia valoran x y y , las

y hashCode () son destinados en conjunto por un contrato unido que especifica si dos objetos son considerados iguales usando los iguales el mtodo de (), entonces deben tener los valores de |hashcode| idnticos. As para ser verdaderamente seguro, su mtodo prctico debe ser, si usted hace caso de igualan (), haga caso de hashCode () tambin. As dejenos cambiarse arriba a hashCode () y vea cmo que el mtodo se une en a () de iguales.
igualen ()

hacer caso de hashCode ()


Hashcodes es tipicamente acostumbrar a aumentar la ejecucin de las colecciones grandes de los datos. El valor de |hashcode| de un objeto es usado por ciertas clases de coleccin ( miraremos

550

Captulo 7:

Genricos y colecciones

a las colecciones ms tarde en este captulo ). Aunque lo puede considerar como el tipo de un nmero de ID de objeto, ello no es necesariamente nico. Colecciones tales como HashMap y HashSet usan el valor de | hashcode| de un objeto para determinar cmo el objeto deba ser guardado en la coleccin, y el |hashcode| est usado de nuevo para ayude a localizar el objeto en la coleccin. Para el examen no necesita comprender los detalles profundos de cmo las clases de coleccin ese uso picando ponga en prctica, pero necesita saber que las colecciones les usan ( pero, |um| , ellos todo tenga "picadillo" en el nombre as usted debe ser bueno all ). Debe tambin ser capaz de reconocer una ejecucin apropiada o correcta de hashCode (). Esto no significa
jurdico y an no significa eficiente. Es perfectamente jurdico tener un mtodo de |

hashcode| terriblemente ineficiente en su clase, mientras no viola el contrato especificado en la documentacin de clase de objeto ( nosotros mire a ese contrato en un momento ). As para el examen, si usted es preguntar seleccionar un uso apropiado o correcto del |hashcode|, no equivoque apropiado para jurdico o eficiente.

Comprender Hashcodes
A fin de comprender lo que est apropiado y corrija, tenemos que mirar a cmo algunas de las colecciones usan |hashcodes|. Imagine un conjunto de cubos alineado en el piso. Alguien le da una pieza del papel con un nombre encima. Toma el nombre y calcula un cdigo de entero, nmero entero de ello por usando un es 1 , b tiene 2 , y as en, y aadiendo los valores numricos de todas las letras en el nombre en conjunto. un nombre de pila siempre resultar en el mismo cdigo; vase la figura 7-1.
figura 7-1 Llave Hashc ode Alex Bob UN ( 1) + LA L ( 12) + = 42 = apuala LA E ( 5) + X (24) LA B 19 = Federiqui ( 2) + LA O ( 15) + B 42 = to (2) LA D ( 4) + YO ( 9) 33 + EL R ( 18) + K (11) LA F ( 6) + EL R ( 18) + LA E ( 5) + (D) HashMap Collection Hashcode se da prisa "Bob" 19 33 42 Hashcode Algorithm

un ejemplo de |hashcode| simplificado

"Federiquito" "Ale x" dag a"

Nosotros no introducimos algo azar, tenemos simplemente un algoritmo que pueda siempre correr la misma va dado una entrada especfica, as la salida siempre es idntico para cualesquiera dos entradas idnticas. Hasta ahora todo va bien? Ahora la va que usa que codifica ( y nosotros lo llamar un | hashcode| ahora ) sea determinar que d prisa para poner la pieza de

Hacer caso de hashCode () ( objetivo de examen 6.2 )

551

papel en ( imagine que cada cubo representa un nmero de cdigo diferente usted puede conseguir ). Ahora imagine que alguien suba y muestran que usted un nombre y dice, " por favor recupere la pieza del papel que casa este nombre." as le mirar al nombre muestran che usted, y corra el mismo algoritmo de |hashcode| generador. El | hashcode| le dice en que d prisa deba mirar a encontrar el nombre. Podra haber notado un poco de defecto en nuestro sistema, sin embargo. Dos nombres diferentes podran resultar en el mismo valor. Por ejemplo, los nombres Amy y pueda tener mismas letras, as el |hashcode| ser idntico para ambos nombres. Eso es aceptable, pero significa que cuando alguien le pregunta (el dependiente de cubo) para la pieza de Amy de
papel, usted todava tendr que buscar por el objetivo d prisa la lectura cada nombre hasta que nosotros encontramos Amy antes que el mayo.

El |hashcode| dice le slo que saca en cubos para examinar, pero no cmo localizar el nombre una vez que estamos en ese cubo.

En Hashing de vida real, no es poco comn para haber ms de una entrada en un cubo. La recuperacin de Hashing es un proceso de danza de saln. 1. Encuentre al derecho darse prisa ( usando hashCode () ) 2. Busque el cubo para el elemento derecho ( usando () de iguales ).

As para eficiencia, su meta es tener los papeles distribuida tan igualmente como posible a travs de todos los cubos. Idealmente, podra tener slo un nombre por cubo de modo que cuando alguien pregunta

por un papel usted pudo calcular simplemente el |hashcode| y el garfio justo el un papel del cubo correcto ( sin tener que ir lanzando por los papeles diferentes en ese saque en cubos hasta que usted localiza el exacto usted est buscando ). El (pero todava funcional) eficiente menor el generador de |hashcode| retorna el mismo |hashcode| ( diga, 42 ) a pesar del nombre, de modo que todos los papeles desembarcaron en el mismo cubo mientras que los otros est situado vacie. El dependiente de cubo tiene que mantener yendo para ese un d prisa y lanzando dolorosamente por cada uno de los nombres en el cubo hasta el derecho son sido encontrados. Y si que es cmo ello trabajan, ellos puede no adems usar los |hashcodes| a casi slo vaya al un cubo grande y salga fuera de un fin y examine cada papel hasta que encuentra el un desean. Este distribudo-a travs de-el-ejemplo de cubos es similar a los |hashcodes| intermedios est usado en colecciones. Cuando usted pone un objeto en una coleccin que usan |hashcodes| , la coleccin usa el |hashcode| del objeto para decidir en que d prisa/ranure el objeto

552

Captulo 7:

Genricos y colecciones

deba desembarcar. Entonces cuando quiere traer que oponga se ( o, para un |hashtable| , recupere el valor asociado para ese objeto ), usted tiene que dar a la coleccin una referencia a un objeto que las comparaciones de coleccin con los objetos que ello contiene la coleccin. Mientras el objeto ( almacenado en la coleccin, como un papel en el cubo ) usted est tratando de buscar tener el mismo |hashcode| como el objeto que est usando para la bsqueda ( el nombre que se muestra

a la persona que trabaja los cubos ), entonces el objeto se encontrar. Pero...y esto es un grande, imagine lo que suceda si, yendo de vuelta a nuestro ejemplo de nombre, mostr el trabajador de cubo un nombre y ellos calcularon el cdigo basados en slo mitad las letras en el nombre en lugar de todo de ellos. Ellos tuvieron nunca encuentre el nombre en el cubo porque no podran estar mirando en el cubo correcto ! ahora puede ver porque si dos objetos es considerado igual, sus |hashcodes| tambin debe ser igual? De otra manera, usted tuvo nunca sea capaz de encontrar el objeto desde el mtodo implcito de |hashcode| en el objeto de clase virtualmente siempre sube con un nmero nico para cada objeto, an si los iguales el mtodo de () son el | overridden| en tal va que dos o ms objetos son considerados iguales. No importa cun iguales son los objetos si sus |hashcodes| no reflejan eso. As tiempo de otro ms: Si dos objetos son iguales, sus |hashcodes| deben ser iguales tambin.

poner en prctica hashCode ()


Qu el infierno se parece a un algoritmo de | hashcode| real? Las personas consiguen su PhDs en algoritmos de clculo de claves, as de un punto de vista de ciencia informtica, es ms all el alcance del examen. La parte que somos importante para uno aqu es el asunto de si siga el contrato. Y para seguir el contrato, considere lo que usted hace en los iguales el mtodo de () . Compara atributos. Porque esa comparacin casi siempre supone variable de caso valoran ( recuerde cuando nosotros mirar a las dos Moof se opone y les considere igualar si su s de moofValue de | int| era el mismo?). Su ejecucin de hashCode
() debera usar las mismas caso. Aqu est un ejemplo: variables de

clasifique HasHash{ x de |int| pblica; HasHash(int xVal) { la x = XVal; } los iguales booleanas pblicos (o de objeto){ h de HasHash = (HasHash) la o; // No pruebe a la casa sin // prueba de | instanceof| si ( h.x == this.x ){

retorne ciertamente; } de otro modo{ retorne falsamente; }

Hacer caso de hashCode () ( objetivo de examen 6.2 )

553

} public int hashCode() { retorne ( la x * 17); } }

Esto iguala el mtodo de () dice que dos objetos sea igual si tienen el mismo valor de x, se opone as con el mismo valor de x tenga
que retornar los |hashcodes| idnticos.

un hashCode () que retorna el mismo valor para todos los casos si son iguales o no es todava un valor de inversin legal an aproprie de - mtodo de hashCode () ! por
ejemplo, public int hashCode() { retorno 1492; }

Esto no viola el contract.Two se opone con un valor de x de 8 tenga el mismo |


hashcode|. Pero pues de nuevo, as puede dos objetos desigual, un con un valor de x de 12 y otro un valor de-920.Este mtodo de hashCode () es horriblemente ineficiente, recuerde, porque hace che todos los objetos desembarcan en el mismo cubo, pero an as, el objeto todava puede encontrarse como la coleccin giran la manivela por el un y nico cubo - usar () de igualesprobar desesperadamente para finalmente, esmeradamente, localiza el objeto correcto. En otros trminos, el | hashcode| no era realmente ninguna ayuda a exhausto la subida de exceso de velocidad la bsqueda, aunque mejorando la velocidad de bsqueda es el propsito propuesto de |hashcode| ! no obstante, este de ajustes de un picadillo-todo el mtodo podra ser considerado

apropiado y an corregira porque no viola el contrato. Otra vez, corrija no haga necesariamente bien de promedio.

Tipicamente, usted ver los mtodos de


hashCode () que hacen cierta combinacin de ^-e ( XOR-e )las variables de caso de s de una clase( en otros trminos, haciendo girar sus bits ), conjuntamente con tal vez multiplicando les por un nmero primo. En todo caso, mientras que la meta sea conseguir una distribucin ancha y casual de objetos a travs de cubos, el contrato ( y si un objeto se puede encontrar ) exija slo que dos objetos iguales tienen iguale |hashcodes|. El examen no le espera para evaluar la eficiencia de un mtodo de hashCode (), pero debe ser capaz de reconocer que unos puede y no trabaje ( trabaje el significado " cause el objeto para proporcionarse en la coleccin " ). Ahora que sabemos que dos objetos iguales deben tener |hashcodes| idnticos, son el contrario ciertamente? Dos objetos con los | hashcodes| idnticos tenga que ser considerado igual? Considera lo-- usted podra tener gran cantidad de objetos desembarque en el mismo cubo porque sus |hashcodes| son idnticos, pero a menos que pasan tambin el equals () pruebe,

no subirn como un partido en una bsqueda por la coleccin. Esto es exactamente lo que usted tener

554

Captulo 7:

Genricos y colecciones

consiga con nuestro muy ineficiente todosconsigue-el-mismo-mtodo de |hashcode|. Es jurdico y corrija, |slooooow| justo. As para un objeto para localizarse, el objeto de bsqueda y el objeto en la coleccin deben tener ambos |hashcode| idntico valoran y retorne ciertamente para los iguales el mtodo de () . As all est slo nada fuera de hacer caso de ambos mtodos para ser absolutamente cierto que sus objetos pueden usado en

colecciones que usa Hashing.

el contrato de hashCode ()
Ahora venida para usted directamente de la documentacin de Java API fabulosa para objeto de clase, puede presentamos (rollo de tambor) el contrato de hashCode ()
:

la n siempre que se invoca en el mismo

objeto ms de una vez durante un |tion| de |execu| de una aplicacin Java, el mtodo de hashCode () debe retornar
firmemente el mismo entero, nmero entero, provea ninguna informacin usada en iguala las comparaciones de () en el objeto

son modificadas. Este entero, nmero entero no tiene que permanecer consistente de una ejecucin de una aplicacin a otra ejecucin de la misma aplicacin. n si dos objetos son iguales segn los iguales (objeto) mtodo, entonces llamar el mtodo de hashCode () en cada
uno de los dos objetos deba producir el mismo resultado de entero, nmero entero.

la n no es requerido que si dos objetos son desiguales segn los iguales

mtodo, entonces llamar el mtodo de hashCode () en cada


(java.lang.Object)

uno de los dos objetos deba producir los resultados de entero, nmero entero distintos. Sin embargo, el programador debe tener conciencia de produciendo los resultados de entero, nmero entero distintos para los objetos desiguales pueden mejorar la ejecucin de los | hashtables|.

Y lo que son estos medios a usted...


Condicin
x.equals (y) == ciertamente x.hashCode () == y.hashCode ()

requerido
x.hashCode () y.hashCode () ==

no requiera (pero permiti)

x.equals (y) == falsamente x.hashCode () != y.hashCode () x.equals (y) == falsamente

x.equals (y) == ciertamente Ningunas necesidades de hashCode ()

Hacer caso de hashCode () ( objetivo de examen 6.2 )

555

As dejenos mirar a qu ms poder causar un mtodo de hashCode () para fracasar. Qu


sucede si incluye una variable pasajera en su mtodo de hashCode ()? Mientras que es jurdico ( el compilador no queje ), bajo ciertas circunstancias un objeto que pone en una coleccin no se encontrar. Como usted sabe, la publicacin por entregas salva un objeto de modo que ello se puede reanimar ms tarde por el |deserializing| ello de vuelta a oponer completo. Pero el peligro puede Robinson - recuerde que las variables pasajeras no son salvadas cuando un objeto es publicado por entregas. un guin malo puede parecerse a este: clasifique SaveMe cumple <publicar> por entregas{ x de |int| pasajera; y de |int|; SaveMe(int xVal, int yVal) { la x = XVal; la y = YVal; } public int hashCode() { retorne ( la x ^ y); // Valor de inversin legal, pero no corrija para // use una variable pasajera } los iguales booleanas pblicos (o de objeto){ SaveMe prueba = (SaveMe) la o; si ( y de == test.y y x de == test.x ){ // El valor de inversin legal, no corrija retorne ciertamente; } de otro modo{ retorne falsamente; } } }

Aqu est lo que pudo suceder usar codifica como el ejemplo precedente: 1. D a un objeto cierto manifieste (asignar valores a sus variables de caso). 2. Ponga el objeto en un HashMap, usando el objeto como una llave. 3. Salve el objeto a un archivo que usa publicacin por entregas sin

alterar ningn de su estado. 4. Recupere el objeto del archivo por el | deserialization|. 5. Use el |deserialized| ( devuelva a la vida en la pila ) oponga se para conseguir el objeto fuera del HashMap. Oops. El objeto en la coleccin y el de modo supuesto mismo objeto devuelve a la vida no es idntico. La variable pasajera del objeto vendr

556

Captulo 7:

Genricos y colecciones

parte posterior con un valor implcito antes que el valor la variable tuvo al tiempo ello es sido salvado ( o traduzca al el HashMap ). As usando el precedente SaveMe codifique, si el valor de la x es 9 cuando el caso es puesto en el HashMap, entonces desde la x est usado en el clculo del |hashcode| , cuando el valor de los cambios de x, el |hashcode| cambia
tambin. Y cuando ese mismo caso de SaveMe es devolver de |deserialization|, la x == 0 , a pesar del valor de la x al tiempo el objeto es

sido publicado por entregas. As el nuevo clculo de |hashcode| dar a un |hashcode| diferente, y los iguales el mtodo de () fracase adems desde la x est acostumbrado a determinar igualdad de objeto. Lnea fundamental: las variables pasajeras puede meterse en realmente su igualan ejecuciones de () y hashCode () . Mantenga transente de non- de variables o, si ellos se debe marcar pasajero, no les use para determinar |hashcodes| o igualdad.

objetivo de certificacin

Colecciones ( objetivo de examen 6.1 )


6.1 Dado A diseo guin, determine que coleccin clases and/or enlaces deba sea usado para correctamente instrumento eso diseo, incluyendo el uso de el Comparable enlace. Puede imagina tratar de escribir las aplicaciones de objeto orientado sin usar las estructuras de datos como |hashtables| o listas enlazadas? Qu deseara hacer cuando necesit mantener una lista clasificada de, digamos, todos los miembros en sus simpsones ventile el club? Obviamente usted puede la prctica de hacer las cosas uno mismo; Amazon.com deba tener miles de los libros de algoritmo que puede comprar. Pero con el tipo de fijan la hora de programadores son bajo hoy, es casi demasiado doloroso para considerar. Los marco de colecciones en Java, que tomaron forma con la liberacin de JDK 1.2 y estaba expandido en 1.4 y de nuevo en Java 5 y sin embargo de nuevo en Java 6, le d listas, conjuntos, mapas, y colas para satisfacer la mayor parte de sus necesidades de codificacin. Ellos ha sido probado, examinado, y pellizcado retorciendo. Pique el mejor para su trabajo y conseguir -- al menos -- la ejecucin razonable. Y cuando necesita algo un poco ms a la medida, los marco de colecciones en el paquete java.util son cargados con enlaces y las utilidades.

as qu hace con una coleccin?


Existe unas cuantas operaciones bsicas usted puede normalmente el uso con las colecciones: la n aade objetos a la coleccin. la n quita objetos de la coleccin.

As qu hace con una coleccin? (Objetivo de examen 6.1)

557

la n descubre si un objeto ( o el grupo de objetos ) est en la

coleccin.
la n recupera un objeto de la coleccin (sin quitarlo). la n itera por la coleccin, mirar a

cada elemento (objeto) uno tras otro.

Teclee enlaces y clases de los marco de colecciones

Para el examen necesitar saber que la coleccin para escoger basado en un requerimiento fijo. Las colecciones API empieza con un grupo de enlaces, sino tambin da le una camionada de las clases concretas. Los enlaces de ncleo que necesita saber para el examen ( y la vida por lo general ) es el siguiente nueve:
Coleccin Conjunto SortedSe t SortedMa p NavigableMa p

Lista

Mapa

Cola

NavigableSet

Las clases de ejecucin concretas de ncleo que necesita saber para el examen es el siguiente 13 ( existe otros, pero el examen no les cubre especficamente ):
Mapas
HashMap

conjuntos
HashSet

listas
ArrayList

Colas
PriorityQueue

Utilidade s

Coleccione s Conju ntos

Hashtable

LinkedHashSet

Vector

TreeMap LinkedHashMap

TreeSet

LinkedLis t

No todas las colecciones en los marco de colecciones en realidad ponen en prctica el enlace de coleccin. En otros trminos, no todas las colecciones pasa el IS-una prueba para la coleccin. Especficamente, ninguno de las clases y enlaces relacionadas con el mapa se extiende de la coleccin. As mientras que SortedMap, Hashtable, HashMap, TreeMap, y LinkedHashMap son todos inimaginados como las colecciones, ninguno extienda en realidad de la c de Collection-with-a-capital- ( vase la figura 7-2 ). A las cosas hechas un poco ms desconcertante, all est realmente tres sobrecargue los usos de la palabra "coleccin":

558

Captulo 7:

Genricos y colecciones

la coleccin de n (c en minsculas), que

represente cualquier de las estructuras de datos en que los objetos est guardado e itere arriba. la coleccin de n (c capital), que es en realidad el enlace java.util.Collection de que conjunto, lista, y cola se extienden. ( eso es, extienda se, no el |ment| de | imple|. All no estn ningunas ejecuciones directas de la coleccin.) las colecciones de n (c capital y fines con la s) son la clase java.util.Collections que tiene una pila de mtodos de uso prctico estticos para el uso con las
colecciones.

figura 7-2 el enlace y jerarqua de clase para las colecciones

< < i n t e r a c t e c o l e c c i n d e > >

<<interacte conjunto de >>

<<interacte lista de >>

<<in terac te cola de >>

HashSet << int era ct e >> Sor ted Set

LinkedHashSet

<<interacte >> NavigableSet

ArrayList

Vector

LinkedList

PriorityQu eue

TreeSet Objeto

<<interacte >> Mapa

< < i n t e r a c t e > > S o r t e d M a p

Conjuntos

Colecciones

Hashtable

HashMap

<<interact e >> Navigable Map

enseres extienda se

LinkedHashMap TreeM ap

As qu hace con una coleccin? (Objetivo de examen 6.1)

559

Puede equivocar as fcilmente "colecciones" para "coleccin" - tenga cuidado. Tenga presente que las colecciones son una

clase, con los mtodos de uso prctico estticos, mientras que coleccin es un enlace con declaraciones de los mtodos el campo comn a la mayor parte de las colecciones incluyendo aada (), quite (), contenga (), el tamao
(), y |iterator| ().

Las colecciones entran cuatro sabores bsicos: la n lista listas de cosas ( clasifican ese instrumento lista ). la n pone las cosas nicas ( clasifican ese instrumento ponga ). la n combina cosas con un ID nico ( clasifican ese instrumento combina ). la n trenza las cosas arregladas por el order in que van a ser elaborados. La figura 7-3 ilustra la estructura de una lista, un conjunto, y un mapa.
ndice: figura 7-3 0 1 2 3 4 " pedrn rodado de "" Greeley "" de Collins de ft "" Denver " lista: El itinerario del vendedor ( duplican permita ) 5 "Pedr n rodado "

La estructura de una lista, un conjunto, Valor: "Pedrn rodado" y un mapa

Pedrn rodado Greeley Vail Collins de ft Denver Dillon

Idaho salta

Conjunto: El territorio del vendedor ( ningunos duplicados permiti )

Hashcode se da prisa: Valores: "Avente el gancho " MonkeyWrench " ejecute en fases el ""ncleo de urdimbre"" de inversor funde condensador" HashMap: los productos del vendedor ( llaves gener de los ides de producto )

560

Captulo 7:

Genricos y colecciones

Pero all est sub sabores dentro de esos cuatro sabores de colecciones:

Clasificado

Unsorted

Ordenado

Desord enado

Una clase de ejecucin puede ser unsorted y desordenado, ordenado pero unsorted, o ambos ordene y clasifique. Pero una ejecucin nunca puede estar clasificado pero desordenado, porque la clasificacin es un tipo especfico del orden, como ver en un momento. Por ejemplo, un HashSet es un conjunto desordenado, unsorted, mientras que un LinkedHashSet es un ordenado ( pero no clasifique ) ponga que mantenga el order in que los objetos eran insertados. Quiz debemos ser explcitos sobre la diferencia entre clasificado y ordene, pero primero tenemos que discutir la idea de la iteracin. Cuando usted considera iteracin, usted puede considerar iterando sobre un conjunto usando, digamos, un bucle PARA para acceder cada elemento en el conjunto que est en servicio ( 0, 1, 2 , y as en ). Iterar por una coleccin normalmente significa caminar por los elementos uno tras otro empezando desde el principio elemento. A veces, sin embargo, an el concepto de primero es un poco extrao en un Hashtable all realmente no est una nocin del primero, secundar, tercero, y as en. En un Hashtable, los elementos son situados en el A (aparentemente) la orden catica basada en el |hashcode| de la llave. Pero algo tiene que ir el

primero cuando itera; as, cuando itera sobre un Hashtable, existir una orden. Pero hasta usted puede relatar, ello es completamente arbitrario y pueda cambiar en vas aparentemente casuales como la coleccin cambia.

ordenado

Cuando una coleccin est ordenado, ello significa que usted puede iterar por la coleccin en un especfico ( no-azar ) la orden. una coleccin de Hashtable no es ordenada. Aunque el Hashtable mismo tenga la lgica interna para determinar la orden (basados en |hashcodes| y la ejecucin de la propia coleccin), no encontrar cada orden cuando itera por el Hashtable. Un ArrayList, sin embargo, guarda el |tablished| electrnico ordenado por la posicin de ndice de los elementos (tal como un conjunto). LinkedHashSet guarda la orden establecer por insercin, as el ltimo elemento insertado es el ltimo elemento en el LinkedHashSet ( en oposicin a un ArrayList, donde puede insertar un elemento a una posicin de ndice especfica ). Finalmente, existe ciertas colecciones que mantienen una orden con referencia a-fida para como la orden natural de los elementos, y esas colecciones es entonces no slo ordene, sino tambin clasificado. Parecemos a cmo natural ordenado trabajan para las colecciones clasificadas.

Liste el enlace ( objetivo de examen 6.1 )

561

clasificado

una coleccin clasificada significa que el order in la coleccin es

determinado segn cierta regla o gobierna, conocido como la orden de clase. una orden de clase tiene nada que ver con cuando un objeto era aadido a la coleccin, o cuando era el la ltima vez era accedido, o lo que la "posicin" era aadido a. La clasificacin es hecha basada en propiedades de los objetos se. Usted pone objetos en la coleccin, y la coleccin deduzca lo que les ordene ponga en, basado en la orden de clase. una coleccin que guarda una orden ( tal como cada lista, que usa la insercin ordena ) no es realmente considerado clasifique a menos que lo clasifican usando cierta orden de clase. Ms comnmente, la clase ordena use sea de alguna importancia llamado la orden natural. Qu haga que quiera decir? Sabe cmo clasificar alfabticamente -- un comes antes de b, f viene antes de g, y as en. Para una coleccin de objetos de cuerda, entonces, la orden natural es alfabtica. Para objetos de entero, nmero entero, la orden natural es por valor numrico --1 antes de 2 , y as en. Y para Foo se opone, la orden natural es...um...no sabemos. No existe ninguna orden natural para Foo a menos que o hasta el desarrollador de Foo proporcione un, por un enlace (comparable) que define cmo casos de una clase puede ser comparado con uno a otro ( haga el caso un Come antes b , o la b de caso viene antes del A ?). Si el desarrollador decide que objetos de Foo deben ser comparados usar el valor de cierta variable de caso ( digamos existe una barra llamada ), entonces una coleccin clasificada ordenar los objetos de Foo segn los reglamentos en la clase de Foo para cmo usar la variable de caso de barra para determinar la orden. Por supuesto, la clase de Foo podra heredar tambin una orden natural de una clase superior antes que definir su propia orden, en algunos casos. Adems de la orden natural como se especifica por el enlace comparable, es tambin posible definir otro, ordenes de clase diferente usando otro enlace: Comparator. Nosotros discutir cmo usar ambos comparable y comparador para definir las ordenes de clase ms tarde en este captulo. Pero para ahora, slo tenga

presente que clasifique la orden ( incluyendo la orden natural ) no es igual que orden por insercin, acceso, o ndice. Ahora que nosotros conocemos orden y clasificacin, miraremos a cada uno de los cuatro enlaces, y nosotros bucearemos en las ejecuciones concretas de esos enlaces.

enlace de lista
una lista se interesa por el ndice. La una cosa que la lista tiene que no-listas no tienen es un conjunto de mtodos relacionado con el ndice. Esos mtodos claves incluyen cosas quiera consiga (ndice de |int|), IndexOf (o de objeto), sume ( ndice de |int|, objete el | obj| ) , y as en. Todo tres listan ejecuciones son ordenadas por la posicin de ndice una posicin que determina o por poner un objeto a un ndice especfico o aadiendo lo. Los tres listan ejecuciones son descritos en las secciones siguiente.

562

Captulo 7:

Genricos y colecciones

arraylist
Considere este como un conjunto crecer. Ello le da iteracin rpido y acceso al azar rpido. Para manifestar el obvio: es una coleccin ordenada (por el ndice), pero no clasifique. Podra querer saber que a partir de versin 1.4 , ArrayList ahora cumple el nuevo enlace de RandomAccess - un marcador interacta ( significando no tiene ningunos mtodos ) que dice, " esta lista soportan rpidamente ( generalmente el constante cronometra ) el acceso al azar." escoja que esto sobre un LinkedList cuando necesita iteracin rpida pero no es como probablemente para estar haciendo una gran cantidad de insercin y supresin.

vector
El vector es un remanente de los das ms tempranos de Java; Vector y Hashtable eran las dos colecciones originales, el resto era aadido con las versin 1.2 y 1.4 de Java 2. un vector es bsicamente igual que un ArrayList, pero los mtodos de vector son el |chronized| de |syn| para la seguridad de hilo. Normalmente querr usar ArrayList en lugar del vector porque los mtodos sincronizados aaden un golpe de ejecucin no podra necesitar. Y si hace necesidad enhebra de seguridad, existe los mtodos de uso prctico en las colecciones de clase que puede ayudar. El vector es la clase sla aparte de ArrayList para poner en prctica RandomAccess.

linkedlist

un LinkedList es ordenado por la posicin de ndice, como ArrayList, excepte que los elementos son doblemente asociados el uno al otro. Este enlace da le nuevos mtodos (ms all lo que consigue del enlace de lista) para aadiendo y quitando desde el principio o termine se, que lo hacen una buena eleccin para poner en prctica una pila o cola. Tenga presente que un LinkedList puede iterar ms lentamente que un ArrayList, pero es una eleccin buena cuando necesita insercin rpida y supresin. A partir de Java 5 , la clase de LinkedList ha sido mejorada para poner en prctica el enlace java.util.Queue. Como tal, soporta ahora los mtodos comnes de cola: el atisbo (), obtenga votos (), y
ofrezca ().

enlace establecido
un conjunto se interesa permite duplicados. Su iguales el mtodo de () objetos son idnticos ( en por unicidad -- no amigo bueno los determinan si dos cuyo caso slo uno

pueda ser en el conjunto ). Las tres ejecuciones establecidas son descritas en las secciones siguiente.

Hashset un HashSet es un conjunto unsorted,


desordenado que ello usa el |hashcode| de el objeto ser insertando, as el ms eficiente su ejecucin de hashCode () la
ejecucin de acceso mejor que conseguir. Use este de clase cuando usted quiere una coleccin sin duplicados y no se interesa por la orden cuando itera por ello.

Combine el enlace ( objetivo de examen 6.1 )

563

linkedHashset
un LinkedHashSet es una versin ordenada de HashSet que mantiene una lista doblemente asociada a travs de todos los elementos. Use este de clase en lugar de HashSet cuando usted se interesa por la orden de iteracin. Cuando itera por un HashSet la orden es impredecible, mientras que un LinkedHashSet le deja iterar por los elementos en el order in que eran insertados.

Al usar HashSet o LinkedHashSet, los objetos usted les aumente deber hacer caso de hashCode (). Si ellos no hace caso de hashCode (), el objeto implcito. el mtodo de hashCode () permitir los objetos mltiples que podra considerar "significativa igual" para ser aadido a su " ningunos duplicados permiti " ponga.

treeset

El TreeSet es una de dos colecciones clasificadas ( el otro ser TreeMap ). Usa una estructura de rbol negra roja (pero supo que), y las garantas que los elementos estarn al subir la orden, segn la orden natural. Opcionalmente, usted puede construir un TreeSet con un constructor que le deja dar a la coleccin sus reglamentos propios para lo que la orden debe ser ( antes que depender en el orden definido por la clase de los elementos ) por usar un comparador o comparable. A partir de Java 6 , TreeSet cumple NavigableSet.

Enlace de mapa
un mapa se interesa por los identificadores nicos. Combina una llave nica (el ID) a un valor especfico, donde ambas llave y el valor es, por supuesto, objetos. Es probablemente bastante familiarizado con mapas desde muchos lenguajes soportan las estructuras de datos que usan un llave / valor o par de nombre / valor. Las ejecuciones de mapa le dejan hacer las cosas guste la bsqueda para un valor basado en la llave, pregunte por una coleccin de justo los valores, o pregunte por una coleccin de justo las llaves. Como los conjuntos, mapas dependen en los iguales el mtodo de () para determinar si dos llaves es el mismo o diferente.

HashMap

El HashMap da le un mapa unsorted, desordenado cuando necesita un mapa y no se interesa por la orden ( cuando itera por ello ), entonces HashMap es la va para ir; otros mapas aaden un poco ms elevado. Donde las llaves desembarcan en el mapa se base en el |hashcode| de la llave, as, como HashSet, el ms |ficient| de |ef| su ejecucin de hashCode (), la ejecucin mejor
de acceso que conseguir. HashMap permite un cero teclee y valores nulo mltiple en una coleccin.

564

Captulo 7:

Genricos y colecciones

Hashtable

Como vector, Hashtable haya existido de Java prehistrico cronometran. En broma, no olvide para notar la inconsistencia de nombramiento: v de HashMap. Hashtable. Dnde est la capitalizacin del T? Oh bien, no ser estimado para deletrearlo. De cualquier modo, justo cuando el vector es un contraparte sincronizado para el alisado, ms moderno ArrayList, Hashtable es el contraparte sincronizado a HashMap. Recuerde que no sincroniza una clase, as cuando decimos que vector y Hashtable son sincronizados, los mtodos claves de la clase se es sincrnico. Otra diferencia, sin embargo, es se mientras que HashMap deja usted tener valores nulos as como un cero teclea, un Hashtable no le deja tener algo que es nulo.

linkedHashMap
Guste su contraparte establecido, LinkedHashSet, la coleccin de mapa de LinkedHash mantiene la orden de insercin ( o, opcionalmente, acceda la orden ). Aunque ser algo lento que HashMap para aadir y quitar elementos, puede esperar la iteracin rpida con un LinkedHashMap.

treeMap

Usted puede suponer probablemente ahora que un TreeMap es un mapa clasificado y sabe ya que en defecto, este medios " clasificado por la orden natural

de los elementos."como TreeSet, TreeMap le deje definir una orden de clase a la medida ( por la via de un comparable o comparador ) cuando usted construye un TreeMap, que especifica cmo los elementos debe ser comparado con uno a otro cuando se estn ordenando. A partir de Java 6 , TreeMap cumple NavigableMap.

Enlace de cola
una cola es diseada para tener una lista de " parados, " o las cosas para andarse en una procesin de alguna forma. Aunque otras ordenes son posibles, colas son tipicamente inimaginadas como FIFO ( el primero-en, de primer exterior ). Las colas soportan todos los mtodos estandares de coleccin y aaden tambin mtodos para aadir y substraer elementos y revisin forman fila elementos.

PriorityQueue esta clase es nuevo con Java

5. Desde la clase de LinkedList haya sido mejorado para poner en prctica el enlace de cola, bsico colas pueden ser manipuladas con un LinkedList. El propsito de un PriorityQueue es crear un " prioridad-en, exterior de prioridad " forme fila en oposicin a un tpico FIFO forma fila. los elementos de un PriorityQueue est ordenado o por el orden natural ( en cuyo caso los elementos que son el primero clasificado ser accedido primero ) o segn un comparador. En o embale, el orden de los elementos representa su prioridad relativa.

Trence el enlace ( objetivo de examen 6.1 )

565

Puede eliminar fcilmente ciertas respuestas inmediatamente si reconoce que, por ejemplo, un mapa no puede ser la clase para escoger cuando usted necesita un nombre / valor paree coleccin, desde el mapa es un enlace y no una clase de ejecucin concreta. El estilo en el examen es explcito cuando ello materias, as si usted es preguntar escoger un enlace, escoja un enlace antes que una clase que cumple que interface.The contrario es tambin verdadero - si usted es preguntar escoger una clase, no escoja un tipo de enlace.

La tabla 7-2 resume los 11 de los 13 concrete de coleccin orientada clasifican necesitar comprender para el examen. ( conjuntos y colecciones est viniendo enderece se la subida!)
tabla 7-2 coleccin interacta las clases de ejecucin de concreto

Clase

Mapa

conjunt lista o

ordenado

clasi ficad o

HashTable HashTable TreeMap

x x x

Ningn Ningn Clasificado

LinkedHashMap

x
x x

HashSet TreeSet

LinkedHashSet

Por orden de insercin u orden de ltimo acceso Ningn Ningn Clasificado Por natural orden o la comparacin a la medida gobierna Por orden de Ningn insercin

Ningn Ningn Por natural orden o la comparacin a la medida gobierna Ningn

ArrayList Vector LinkedList PriorityQueue

x x x

Por el ndice Por el ndice Por el ndice Clasificado

Ning n Ning n Ning n Por orden de alharaca

566

Captulo 7:

Genricos y colecciones

Est seguro le sepa cmo interpretar tabla 7-2 en una va prctica. Para el examen, usted podra ser estimado para escoger una coleccin basada en un requerimiento particular, donde ese necesidad es expresada como un guin. Por ejemplo, que la coleccin deseara usar si usted necesit mantener y busque en una lista de partes, identificado por su nmero de serie alfanumrico nico donde la parte pueda ser del tipo separe? Deseara cambiar su respuesta a todo si modificamos el requerimiento tal que tambin necesita ser capaz de imprimir los Parts que est en servicio, por su nmero de serie? Para la pregunta primera, puede ver que despus que tiene una clase de parte, pero necesite buscar para los objetos basados en un nmero de serie, usted necesita un Map.The llave ser el nmero de serie como una cuerda, y el valor ser la parte instance.The tenga como valor predefinido la eleccin debe ser HashMap, el mapa ms rpido para el acceso. Pero ahora cuando nosotros enmendamos el requerimiento para incluir conseguir las partes que est en servicio de su

nmero de serie, entonces necesitamos un TreeMap - que mantenga la orden natural de las llaves. Desde la llave es una cuerda, la orden natural para una cuerda ser una clase alfabtica estandar. Si el requerimiento hubiera sido para acordarse de que la parte era el ltimo acceso, entonces tuvimos probablemente necesite un LinkedHashMap. Pero desde un LinkedHashMap pierda la orden natural ( reemplazando lo con ltimo-acceda ordene ), si necesitemos listar las partes por nmero de serie, nosotros tendremos que clasificar explcitamente la coleccin, usando un mtodo de uso prctico.

objetivo de certificacin

Usar los marco de colecciones ( los objetivos 6.3 y 6.5 )


6.3 Escritura cdigo eso usos el NavigableSet y NavigableMap enlaces. 6.5 Uso capacidades en casa el java.util paquete para escritura cdigo para manipule A lista cerca clasificacin, tocar un instrumento musical A binario bsqueda, o convertir el lista para un conjunto. Uso capacidades en casa el java.util paquete para escritura cdigo para manipule un conjunto cerca clasificacin, tocar un instrumento musical A binario bsqueda, o convertir el conjunto para A lista. Uso el java.util.Comparator y java.lang. Comparable enlaces para sentimiento el clasificacin de listas y conjuntos. Adems, reconozca el efecto de el " natural ordenando " de primitivo envoltura clases y java.lang.String en clasificacin. Hemos tomado una mirada de alto nivel, terica a los enlaces y clases claves en los marco de colecciones, ahora a ver cmo

trabajan en la prctica.

ArrayList Basics ( objetivos de examen 6.3 y 6.5 )

567

bases de |arraylist|
La clase java.util.ArrayList es uno del ms
comnmente usado de todas las clases en los marco de colecciones. Se parece un conjunto en las vitaminas. Algunas de las ventajas ArrayList tenga sobre conjuntos es

la n que puede crecer con dinamismo. la n proporciona insercin ms poderosa y mecanismos de bsqueda que los conjuntos. Echamos una mirada al usar un ArrayList que contiene avanzan en lnea. una meta de diseo clave de los marco de colecciones fue proporcionar la funcionalidad rica al nivel de la parte principal interactan: Liste, ponga, y el mapa en la prctica, tipicamente querr ejemplificar concretamente un ArrayList polimorfa as:
Liste MyList = nuevo ArrayList();

A partir de Java 5 usted querr decir


Liste cuerda MyList = nuevo ArrayList < avance en lnea>();

Este tipo de la declaracin siguen el objeto orientado programando el principio de " codificando para un enlace " , y ello hace uso de genricos. Diremos gran cantidad ms sobre los genricos ms tarde en este captulo, pero para ahora slo sepa que, a partir de Java 5 , la sintaxis es la va que usted declara el tipo de una coleccin. (Antes de Java 5 all estaba nada para especificar el tipo de una coleccin, y cuando nosotros cubrimos genricos, hablaremos sobre las implicaciones de mezclar Java 5

( represente ) y pre-Java 5 ( untyped ) colecciones.) En muchas vas, ArrayList <cuerda> es similar a una cuerda en que ello declara un envase que puede tener las cuerdas slas, pero es ms poderoso que una cuerda. parecemos a algunas de las capacidades que un ArrayList tiene
Liste cuerda prueba = nuevo ArrayList < avance en lnea>(); Encuerde la s = " hola"; test.add ( " avance en lnea"); test.add ( la s); test.add ( la s+s); System.out.println ( test.size()); System.out.println (test.contains( 42));

568

Captulo 7:

Genricos y colecciones

System.out.println(test .contains("hihi")); test.remove ( " hola"); System.out.println ( test.size());

que producen
3 f a l s a m e n t e v e r d a d e r

o 2

Existe el gran cantidad yendo en en este programa pequeo. El anuncio que cuando nosotros declaramos el ArrayList no lo dimos
un tamao. Entonces fuimos capaz de preguntar el ArrayList para su tamao, lo fuimos capaz

de preguntar si contuvo los objetos especficos, quitamos un exterior de derecho de objeto del medio de ello, y entonces nosotros rechecked su tamao.

|autoboxing| con las colecciones


Por lo general, las colecciones pueden tener objetos pero no primitivos. Antes de Java 5 , un uso muy comn para las clases de envoltura fue proporcionar una va para conseguir un primitivo en una coleccin. Antes de Java 5 , usted tuvo que enrollar un primitivo a mano antes que usted pudo ponerlo en una coleccin. Con Java 5 , primitivos todava tienen que ser enrollados, pero el |autoboxing| lo cuida para usted.
Liste MyInts = nuevo ArrayList(); myInts.add (nuevo entero, nmero entero( 42)); // pre // de declaracin de Java 5 tenga que enrollar un |int|

A partir de Java 5 nosotros podemos decir


myInts.add ( 42); lo maneja ! // el |autoboxing|

En este ltimo ejemplo, somos todava sumadores un objeto de entero, nmero entero a myInts ( no un primitivo de |int|); es slo
que |autoboxing| nosotros. maneja la envoltura para

clasificar colecciones y conjuntos


Clasificar y buscar los tpicos ha sido aadido al examen para Java 5. Ambas colecciones y conjuntos puede ser clasificado y busca usando mtodos en el API.

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

569
colecciones de clasificacin

Empezamos con algo simple guste clasificar un ArrayList de cuerdas alfabticamente. Qu pudo ser ms fcil? De acuerdo, esperaremos mientras que usted va hallazgo el mtodo de () de clase de ArrayList...
consigue lo? Por supuesto, ArrayList no le da cada va para clasificar sus contenidos, pero la clase java.util.Collections hace importe java.util.*; clasifique TestSort1{ la parte principal vaca esttica pblica (| args| de cuerda){ ArrayList atraque se = nuevo ArrayList < avance en lnea>(); // #1 stuff.add("Denver"); stuff.add ( " pedrn rodado"); stuff.add ( " obtenga ganancia"); stuff.add ( " lamo tembln"); stuff.add ( " telururo"); System.out.println ( " unsorted " + material); Collections.sort ( atraque se); // #2 System.out.println ( " clasifique " + material); } }

Estos productos algo as como esto:


Denver, Boulder, Vail, Aspen, Telluride unsorted Aspen, Boulder, Denver, Telluride, Vail clasificado

La lnea 1 est declarando un ArrayList de cuerdas, y raye 2 estn clasificando el ArrayList alfabticamente. Diremos ms sobre las colecciones clasifique, conjuntamente con los conjuntos clasifique en una seccin posterior, para ahora nos deje mantener clasificando material. Imaginamos estamos construyendo la aplicacin de automatizacin domestica ltima. Hoy nosotros se enfoca en la diversin

domestica centre, y ms especficamente el centro de control de DVD. Nosotros hemos conseguido ya el archivo yo/software de o en su lugar apropiado para leer y escribir datos entre el archivo dvdInfo.txt y los casos de DVDInfo de clase. Aqu estn los aspectos claves de la clase:
clasifique DVDInfo{ Ttulo de cuerda; Gnero de cuerda; Encuerde leadActor; DVDInfo ( encuerde T, g de cuerda, encuerde un ){

570

Captulo 7:

Genricos y colecciones

titule = T; el gnero = g; LeadActor = A; } el pblico encuerda toString () { ttulo de retorno + " " + gnero + " " + leadActor + "\n"; } // afinadores de vaco y stter va aqu }

Aqu est los datos de DVD que estn en el archivo dvdinfo.txt:


Donnie Darko/scifi/Gyllenhall, buques corsarios correcto del perdido Ark/action/Ford, Harrison 2001/sci-fi/?? La cajita Shack/comedy/Murray, Bill La estrella Wars/sci-fi/Ford, Harrison Perdido en Translation/comedy/M urray, patriota de Bill Games/action/Ford, Harrison

En nuestra aplicacin de automatizacin domestica, nosotros queremos crear un caso de DVDInfo para cada lnea de los datos que nosotros leemos en del archivo dvdInfo.txt.

Para cada caso, analizaremos la lnea de los datos ( recuerde String.split ()?) y pueble DVDInfo " s tres variables de caso. Finalmente, queremos poner todos los casos de DVDInfo en un ArrayList. Imagine que el mtodo de populateList () ( debajo de ) haga todo de esto. Aqu est una pieza pequea del cdigo de nuestra aplicacin: ArrayList<DVDInfo> dvdList = new ArrayList<DVDInfo>(); populateList(); // aada los datos de archivo para el ArrayList System.out.println ( DvdList);

Podra conseguir la salida as:


Donnie Darko sci-fi Gyllenhall, Jake , Raiders of the Lost Ark action Ford, Harrison, 2001 sci-fi?? , Caddy Shack comedy Murray, Bill , Star Wars sci-fi Ford, Harrison , Lost in Translation comedy Murray, Bill, Patriot Games action Ford, Harrison

( la nota: Nosotros |overrode| DVDInfo " mtodo de toString () de s, as cuando


nosotros invocamos () de |println| en el ArrayList que ello invoc toString ()

para cada caso.)

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

571
Ahora que tuvo un poblado ArrayList, lo dejenos clasificar:
Collections.sort(dvdlist);

Oops!, consigue algo as como esto:


TestDVD.java:13: no pueda encontrar smbolo smbolo: clase de mtodo (java.util.ArrayList< DVDInfo

> ) la ubicacin: clasifique java.util.Collections Collections.sort ( el | dvdlist|);

Qu est acercndose a aqu? Sabemos que las colecciones clasifican tenga un mtodo de () de clase, sin embargo este error
implica

mtodo de () de clase que puede tomar un | dvdlist|. Esto significa que all debe ser de alguna importancia el mal con el argumento estamos pasando (|dvdlist|). Si usted tenga ya deduzca el problema, nuestra suposicin es que usted lo hizo sin la ayuda del mensaje de error oscuro mostrada arriba...Cmo el infierno hace clasifica casos de DVDInfo? Por qu ramos capaces para clasificar casos de la cuerda? Cuando busca Collections.sort () en el API su primera reaccin podra ser aterrar. Cuelgue estrechamente, una vez ms las seccin de genricos le ayudar a leer que el sino pareciendo firma de mtodo. Si lea la descripcin del de un |arg| clasifique mtodo de (), ver que el mtodo de () de
clase toma un argumento de lista, y que los objetos en la lista deben poner en prctica un enlace llame comparable. Echa que encuerde cumpla comparable, y se es el por qu fuimos capaz de clasificar una lista de cuerdas usando el mtodo de () Collections.sort.

que

las

colecciones

no

tienen

un

el enlace comparable
El enlace comparable es usado por el mtodo de () Collections.sort y el mtodo de () java.util.Arrays.sort para clasificar listas y conjuntos de objetos, respectivamente. Para poner en prctica comparable, una clase debe poner en prctica un mtodo sencillo, compareTo (). Aqu est
una invocacin de compareTo (): int x = thisObject.compareTo(anotherObject);

El mtodo de compareTo ()

retorna un |int| con las caractersticas siguientes:

negativa de n si ThisObject < AnotherObject cero de n si thisObject == anotherObject grado positivo de n si ThisObject >

AnotherObject

572

Captulo 7:

Genricos y colecciones

El mtodo de () de clase usa compareTo () para determinar cmo la lista o el conjunto de objeto se debe clasificar. Despus que llega a poner en prctica compareTo () para sus clases propias, usted puede usar cualesquiera criterios sobrenaturales que usted prefiere, para clasificar casos de sus clases. Retornar a nuestro ejemplo ms temprano para DVDInfo de clase, podemos tomar la salida fcil y usar la ejecucin de s de la clase de cuerda de
compareTo (): clasifique DVDInfo cumpla comparable DVDInfo { // cdigo existente // #1 public int compareTo(DVDInfo d) { retorne title.compareTo ( d.getTitle ()) ; // } } #2

En lnea 1 declaramos que clasifique cumple comparable en tal va que objetos de DVDInfo pueden ser comparados con
DVDInfo otros objetos de DVDInfo. En lnea 2 nosotros ponemos en prctica compareTo () por

comparar el dos DVDInfo los ttulos de objeto. Despus que sabemos que los ttulos es las cuerdas, y que encuerde cumpla comparable, esta es una buena va para clasificar nuestro DVDInfo se opone, por el ttulo. Antes que genricos acompaaron en Java 5 , habra tenido que poner en prctica comparable algo as como esto:
clasifique DVDInfo cumple comparable{ // cdigo existente |int| pblico CompareTo (o de objeto){ // tome un objeto ms bien // que un tipo especfico d de DVDInfo = (DVDInfo) la o; retorne title.compareTo ( d.getTitle()); } }

Esto es todava jurdico, pero puede ver que es doloroso y arriesgado, porque tiene que hacer un lanzamiento, y necesita verificar que el lanzamiento no suspender antes que lo prueba.

Es importante recordar se cuando hace caso de igualan () debe tomar un argumento del tipo oponga se , pero ese cuando usted hace caso de compareTo () deba tomar un argumento del tipo que
est clasificando.

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

573
Poner lo todo en conjunto, nuestra clase de DVDInfo debe parecerse a ahora esto:
clasifique DVDInfo cumple comparable <DVDInfo>{ Ttulo de cuerda; Gnero de cuerda; Encuerde leadActor; DVDInfo ( encuerde T, g de cuerda, encuerde un ){ titule = T; el gnero = g; LeadActor = A; } el pblico encuerda toString () { ttulo de retorno + " " + gnero + " " + leadActor + "\n"; } public int compareTo(DVDInfo d) { retorne title.compareTo ( d.getTitle()); } el pblico encuerda getTitle () { ttulo de retorno; } // otros afinadores de vaco y personas que preparan }

Ahora, cuando invoca Collections.sort (dvdList) ; conseguimos

2001 sci-fi?? , Caddy Shack comedy Murray, Bill , Donnie Darko sci-fi Gyllenhall, Jake , Lost in Translation comedy Murray, Bill , Patriot Games action Ford, Harrison , Raiders of the Lost Ark action Ford, Harrison, Star Wars sci-fi Ford, Harrison

Viva ! nuestro ArrayList ha sido clasificado por el ttulo. Por supuesto, si desear che nuestro sistema de automatizacin domestico para realmente mecer, probablemente querremos clasificar las colecciones de DVD en gran cantidad de vas diferentes. Despus que clasificamos nuestro ArrayList por poner en prctica el mtodo de compareTo (),
parecemos para estarse hincado. Nosotros podemos poner en prctica slo compareTo () una vez

en una clase, haga as cmo que nosotros emprenda la clasificacin nuestras clases en un ordenado diferente que lo que nosotros especificamos en nuestro mtodo de compareTo
()? Pregunta buena. Como lo quiso la suerte, la respuesta est viniendo levante despus.

574

Captulo 7:

Genricos y colecciones

clasificacin con Comparator


Mientras que mtodo de () usted estuvo

buscando

el

Collections.sort usted podra tener el anuncio que existe una versin sobrecargada de clasifique () que toma un

ambos lista AND algo llame un comparador. El enlace de comparador le da la capacidad para clasificar una coleccin dada muchas vas diferentes. La otra cosa prctica sobre el enlace de comparador es que lo puede usar para clasificar casos de cada clase - las clases uniformes que no puede modificarse -a diferencia del enlace comparable, que le fuerzan para cambiar la clase cuyos casos que quiere clasificar. El enlace de comparador es

tambin mismo fcil de ponga en prctica, teniendo slo un mtodo, compare (). Aqu
est una clase pequea que puede estar acostumbrado a clasificar una lista de los casos de DVDInfo, por el gnero. importe java.util.*; clasifique GenreSort cumple comparador <DVDInfo>{ el |int| pblico compara ( DVDInfo un, DVDInfo dos ){ retorne one.getGenre ().compareTo(two.getGenre()); } }

El mtodo de () Comparator.compare retorna un |int| cuyo significado es igual que el


Comparable.compareTo ()

mtodo. En este caso estamos tomando la ventaja de se preguntando compareTo () para hacer el trabajo real de comparacin para nosotros. Aqu est un programa de prueba que nos deja probar ambos nuestro cdigo comparable y nuestro nuevo cdigo de comparador:
importe java.util.*; importe java.io.*; // populateList () necesita esto el pblico clasifica TestDVD{ ArrayList<DVDInfo> dvdlist = new ArrayList<DVDInfo>(); la parte principal vaca esttica pblica (|args| de cuerda){ nuevo TestDVD ().vaya(); } el vaco pblico ir () { populateList(); System.out.println(dvdlist); // la salida como lea del archivo Collections.sort(dvdlist); System.out.println(dvdlist); // la salida clasificada por el ttulo gues de GenreSort = nuevo GenreSort(); Collections.sort ( | dvdlist| , gues); System.out.println(dvdlist); } // la salida clasificada por el gnero

el valor de retorno de

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

575

vaco pblico populateList () { // lea el archivo, cree los casos de DVDInfo, y // pueble el |dvdlist| de ArrayList con estos casos} }

Usted ha visto ya la primera dos salida liste, aqu estn los tercero:
Patriot Games action Ford, Harrison , Raiders of the Lost Ark action Ford, Harrison, Caddy Shack comedy Murray, Bill , Lost in Translation comedy Murray, Bill, 2001 sci-fi?? , Donnie Darko scifi Gyllenhall, Jake, Star Wars sci-fi Ford, Harrison

Porque los enlaces comparables y de comparador es as similar, espere el examen para tratar de confundirle. Por ejemplo usted puede ser preguntar poner en prctica el mtodo de compareTo () en el enlace de
comparador. Estudie la tabla 7-3 para marcar a fuego las diferencias entre estos dos enlaces.

tabla 7-3 comparando comparable a Comparator

java.lang.Comparable
int objOne.compareTo(objTwo)

java.util.Comparator
int compare(objOne, objTwo)

Resultados

negativ a si

Mismo como comparable

ObjOne < el

cero de objTwo si el grado positiv o de


objOne == objTwo si ObjOne >

ObjTwo

Debe modificar la clase cuyos casos que quiere clasificar. Los slos clasifican la sucesin se pueden crearse

Construye una separata de clase de la clase cuyos casos que quiere clasificar. Muchas sucesiones de clase se pueden crearse Puesto en prctica frecuentemente en el API cerca: Significado para ser puesto en prctica para Encuerde, clases de envoltura, feche, el calendario... clasificar casos de las clases de terceras partes.

576

Captulo 7:

Genricos y colecciones

clasificacin con los conjuntos clasifica


Nosotros ha sido usando la clase java.util.Collections para clasificar colecciones; ahora dejenos mirar al usar la clase java.util.Arrays para clasificar conjuntos. Las noticias buenas es que clasificando los conjuntos de objetos son tal como clasificar colecciones de objetos. El mtodo de () Arrays.sort es |overridden| del mismo modo el mtodo de () Collections.sort
es.

la n Arrays.sort (arrayToSort) la n Arrays.sort ( ArrayToSort, el comparador )

Adems, el mtodo de () Arrays.sort es sobrecargado casi unas milln veces para proporcionar un par de los mtodos de clase para cada tipo del primitivo. Los mtodos de () Arrays.sort que clasifican primitivos siempre la clase basada en la orden natural. No engae por una pregunta de examen que prueban para clasificar un conjunto primitivo usando un comparador. Finalmente, recuerde que los mtodos de () de clase para ambas colecciones clasifica y los conjuntos clasifique es los mtodos estticos, y que ellos alteran los objetos ellos est clasificando, en lugar de retornando un diferente clasifique oponga se.

Nosotros ha dicho mucho sobre clasificar por orden natural y uso comparadores para sort.The ltimo rule de que necesitar marcar a fuego es se, todas las veces que quiera para clasificar un conjunto o una coleccin, los elementos adentro debe todo es mutuamente comparable. En otros trminos, si tenga un objeto y pone gato y los objetos inferiores en ello, no ser capaz de clasificarlo. Por lo general, objetos de tipos diferentes deben no ser considerado mutuamente comparable, a menos que especficamente manifestado de otra manera.

buscar conjuntos y colecciones

Las colecciones clasifican y los conjuntos clasifican ambos proporcionan mtodos que permiten le para buscar para un elemento especfico. Al buscar por colecciones o los conjuntos, los reglamentos siguientes se aplican:
las bsquedas de n son ejecutadas usando el

mtodo de binarySearch () . bsquedas exitosas de n retornan el ndice de |


int| del elemento ser buscando.

bsquedas fracasadas de n retornan un ndice de


|int| que representa la insercin point. El punto de insercin es el lugar en el coleccin / conjunto donde el elemento pueda ser insertado para mantener el coleccin / conjunto correctamente clasificado. Porque posi-

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

577
el |tive| retorna valores y 0 indican las bsquedas exitosas, el mtodo de
binarySearch () usan niegue los nmeros para indicar los puntos de insercin.

es un resultado vlido para una bsqueda exitosa, el primer punto de insercin disponible es-1. All-frente, el punto real de insercin es representado como (-(punto de insercin)-1 ). Por ejemplo, si el punto de insercin de una bsqueda est a elemento 2, la insercin real seale con el dedo retorne ser-3. la n el coleccin / conjunto ser buscando deba ser clasificado antes que puede buscarlo. n si usted intento para buscar un conjunto o coleccin que han no ya sido clasificado, los resultados de la bsqueda no sern fciles de predecir. n si el coleccin / conjunto usted quiere la bsqueda era clasificada en orden natural, se debe buscar en la orden natural. (Normalmente esto se realiza no enviando un comparador como un argumento al mtodo de binarySearch ()
Desde 0 .)

n si el coleccin / conjunto usted quiere la

bsqueda era clasificada usando un comparador, ello se debe buscar usando el mismo comparador, que es en espera de una vacante para ascender como el segundo argumento al mtodo de binarySearch () .
Recuerde que los comparadores no pueden ser usados cuando los conjuntos penetrantes de primitivos. echamos una mirada a una muestra de cdigo que ejercita el mtodo de binarySearch () : importe java.util.*; clasifique SearchObjArray{ la parte principal vaca esttica pblica (| args| de cuerda){ Encuerde |sa| ={"un ", " dos ", " tres ", " cuatro"}; Arrays.sort(sa); para ( encuerde s: sa) System.out.print ( la s + " "); System.out.println ( " \none = " + Arrays.binarySearch ( |sa|, " un")); // #2 // #1

System.out.println ( " d marcha atrs

ahora clase"); ReSortComparator Reed-Solomon = nuevo ReSortComparator(); // #3 Arrays.sort ( |sa|, Reed-Solomon); para ( encuerde s: sa) System.out.print ( la s + " "); System.out.println ( " \none = " + Arrays.binarySearch ( |sa|, " un")); // #4 System.out.println ( " un = " + Arrays.binarySearch ( |sa|, " un ", Reed-Solomon)); // #5 }

578

Captulo 7:

Genricos y colecciones

ReSortComparator de clase esttico comparador de enseres { // #6 el |int| pblico compara ( encuerde A, encuerde la b ){ retorne b.compareTo ( el A); // #7 } } }

que producen algo as como esto:


u n c u a t r o u n d o s t r e s =

1 a h o r a d m a r c h a a t r s l a c l a s e u n t r e s d o s u n c u a t r o = 1 un = 2

Aqu est lo que sucedi:

La lnea 1 clasifique el conjunto de |sa|,


alfabticamente (la orden natural). La lnea 2 busque para la ubicacin del elemento " un " , que es 1. La lnea 3 haga un caso de comparador. En la lnea prxima nosotros con referencia a clase el conjunto usando el comparador. 4 intento de lnea para buscar el conjunto. Nosotros no pasamos el mtodo de binarySearch () el comparador que nosotros acostumbramos a clasificar el conjunto, as que conseguimos una respuesta (indefinida) incorrecta. La lnea 5 busque de nuevo, pasando el comparador a binarySearch (). Esta vez conseguimos la respuesta correcta, 2 Lnea 6 definimos el comparador; es bien para este para ser una clase interior. La lnea 7 por conmutar el uso de los argumentos en la invocacin de compareTo (), conseguimos una clase invertida.

Al

resolviendo penetrante y clasificando inquieren, dos grande |gotchas| son 1. Buscar un conjunto o coleccin que ha no sido clasificado. 2. Usar un comparador en la clase o la bsqueda, pero no ambos.

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

579

Convertir conjuntos a listas a conjuntos

All est un par de mtodos que permite le para convertir conjuntos a listas, y listas a conjuntos. La lista y las clases establecidas han mtodos de toArray (), y los conjuntos
clasifican tenga un mtodo llamado asList (). El mtodo de () Arrays.asList copia un conjunto en una lista. Dice el API, " retorne una lista de tamao fijo respaldada por el conjunto especificado. (Cambios para la lista retornado " escriba por " al conjunto.)"cuando usted usa el mtodo de asList (), el conjunto y la lista llegue a ser unido a la cadera. Cuando actualiza uno de les, el otro consigue actualice de forma automtica. permtanos echar una mirada: Encuerde |sa| ={"un ", " dos ", " tres ", " cuatro"}; List sList = Arrays.asList(sa); // haga una lista System.out.println ( " tamao " + sList.size()); System.out.println ( " idx2 " + sList.get ( 2)); sList.set ( 3, " seis"); // lista de cambio |sa| 1 = " cinco"; // conjunto de cambio para ( encuerde s: sa) System.out.print ( la s + " "); System.out.println ( " \nsl 1 " + sList.get ( 1));

Estos productos
tamao 4 idx2 tres u n c i n c o t r e s

s e i s | s l | 1 c i n c o

El anuncio que cuando nosotros imprimimos el estado final del conjunto y la lista, ellos tiene ambos sido actualizado con mutuamente cambia. No desee hacer algo as como este comportamiento un excelente examen inquiere? Ahora dejenos echar una mirada al mtodo de toArray () . No hay nada la ida demasiado elegante en con el mtodo de toArray () ;
entra dos sabores: que retorne un nuevo objeto coloca en orden de batalla, y que usan el conjunto usted lo envia como el conjunto de destino: Liste entero, nmero entero IL = nuevo ArrayList < el entero, nmero entero>(); para ( x=0 de |int|; la x < 3; x++) iL.add ( la x); Objete |oa| = iL.toArray(); // cree un conjunto de objeto El entero, nmero entero ia2 = nuevo Integer 3; ia2 = iL.toArray ( ia2); // cree un conjunto de entero, nmero entero

580

Captulo 7:

Genricos y colecciones

Usar listas

Recuerde que las listas es normalmente

acostumbrar a mantener cosas en cierta orden. Usted puede usar un LinkedList para crear un primero-en, cola de primer exterior. Usted puede usar un ArrayList para acordarse de lo que las localizaciones era visitado, y en lo que la orden. El anuncio que en ambos de estos ejemplos es perfectamente razonable asumir que los duplicados podran ocurrir. Adems, las listas le permiten para hacer caso de manualmente el orden de elementos por aadir o quitar elementos por la via del ndice del elemento. Antes de Java 5 , y el bucle PARA mejorado, la ms comn va para examinar una lista " elemento por el elemento " estaba cerca el uso de un Iterator. Todava encontrar Iterators en uso en el cdigo de Java usted encuentre, y usted puede slo encontrar un Iterator o dos en el examen. Un Iterator es un objeto que es asociado con una coleccin especfica. Le deja enlazarse por la coleccin paso a paso. Los dos mtodos de Iterator que necesita comprender para el examen es
la
hasNext () retorna si all est al menos otro elemento ms en la coleccin ser atravesndose. Invocar hasNext () no le

n booleana ciertamente

mueve al coleccin.

elemento

prximo

de

la

la n objeta ()

prximo este mtodo retorna el objeto prximo en la coleccin, y mueva le adelante al elemento despus del elemento slo retornado.

parecemos a un poco cdigo que usan una lista y un Iterator:


importe java.util.*; perro de clase{ nombre de cuerda pblico; Siga (n de cuerda){ nombre = n; } } clasifique ItTest{ la parte principal vaca esttica pblica (|args| de cuerda){ Liste perro d = nuevo ArrayList < siga>(); Siga el perro = nuevo perro ( " |aiko|"); d.add ( siga); d.add (nuevo perro( " trbol")); d.add (nuevo perro( " magnolia")); Iterator perro i3 = d.iterator(); // haga un |iterator| mientras que ( i3.hasNext ()) {

Siga d2 = i3.next(); // no tire el anzuelo exija System.out.println ( d2.name); } System.out.println ( " tamao " + d.size()); System.out.println ( " get1 " + d.get (1).nombre); System.out.println("aiko " + d.indexOf ( siga));

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

581

d.remove ( 2); Objete |oa| = d.toArray(); para ( objete o: oa) { Siga d2 = (perro) la o; System.out.println("oa " + d2.name); } } }

Estos productos
3 0 t r b o l d e | o a | d e | a i k o |

d e | o a | d e | a i k o | d e t r b o l d e g e t 1 d e t a m a o d e m a g n o l i a d e t

r b o l d e | a i k o |

Primero de, usamos sintaxis de genricos para crear el Iterator ( un Iterator del tipo sigue ). Debido a esto, cuando nosotros usamos el mtodo de () prximo, nosotros no
tuvimos que lanzar el objeto retornado por () prximo a un perro que nosotros pudimos

haber declarado el Iterator as:


Iterator i3 = d.iterator(); iterator|

// haga un |

Pero entonces habramos tenido que lanzar el valor retornado:


Siga d2 = (perro) i3.next();

El resto del cdigo demuestra usando el


tamao (), consiga mtodos de (), indexOf (), y toArray () . No debe existir todas las sorpresas con estos mtodos. En unas cuantas pginas la tabla 7-5 listar toda la lista, conjunto, y mtodos de utilizacin de mapas que usted deba estar familiarizado con para el examen. Como una advertencia ltima, recuerde que lista es un enlace !

Usar conjuntos
Recuerde que los conjuntos son usados cuando no quiere todos los duplicados en su coleccin. Si usted intento para aadir un elemento a un conjunto que existe ya en el conjunto, el elemento duplicado no ser aadido, y el mtodo de add () retornar falso. Recuerde, HashSets tiende a ser muy rpido porque, como nosotros discutimos ms temprano, usan |hashcodes|.

582

Captulo 7:

Genricos y colecciones

Usted puede crear tambin un TreeSet, que es un conjunto cuyos elementos son clasificados. Debe usar cautela al usar un TreeSet ( nosotros est a punto de explicar porque ):
importe java.util.*; clasifique SetTest{ la parte principal vaca esttica pblica (|args| de cuerda){ |ba| booleana = nuevo booleana 5; // inserte el cdigo aqu |ba| 0 = s.add ( " A"); |ba| 1 = s.add (nuevo entero, nmero entero( 42)) ; |ba| 2 = s.add ( " b"); |ba| 3 = s.add ( " A"); |ba| 4 = s.add ( nuevo objeto()); para ( x=0 de |int|; la x < ba.length; x+ +) System.out.pr int(ba[x + " "); System.out.pr intln ( " \n"); para ( objete o: s) System.out.pr int ( la o + " "); } }

Si inserte la lnea de cdigo siguiente usted conseguir salida algo as como esto:
Ponga la s = nuevo HashSet(); cdigo // inserte este

ciertamente verdadero falso verdadero verdadero una 42 b java.lang.Object@e09713

Es importante saber se la orden de objetos imprimidos en el segundo bucle PARA no es fcil de predecir: HashSets no garantiza cada orden. Tambin, el anuncio que la cuarta invocacin de aada () fracas, porque ello intent para insertar una entrada duplicada ( una cuerda con el valor un ) en el conjunto. Si inserte esta lnea de cdigo que conseguir algo as como esto:
Ponga la s = nuevo TreeSet(); // inserte este cdigo Excepcin en "parte principal" de hilo java.lang.ClassCastException: caf. lang.String a java.lang.Integer.compareTo (Integer.java:35) a java.util.TreeMap.compare (TreeMap.java:1093)

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

583

a java.util.TreeMap.put (TreeMap.java:465) a java.util.TreeSet.add (TreeSet.java:210)

El asunto es que todas las veces que quiera una coleccin para ser clasificado, sus elementos deben ser mutuamente comparables. Recuerde que a menos que especifique de otra manera, los objetos de tipos diferentes no es mutuamente comparable.

Usar mapas

Recuerde que cuando usted usa una clase que los enseres combine, cualesquiera clases que

usted usa como una parte de las llaves para ese mapa debe hacer caso del hashCode () y igualan mtodos de () . ( bien, le slo tener que hacer caso de les si se interese en recuperar material de su mapa seriamente, es jurdico usar una clase que no hace caso de iguala () y hashCode () como una llave en un mapa; su cdigo compilar y corra, slo no encontrar su material.) Aqu est cierto cdigo crudo demostrando el uso de un HashMap:
importe java.util.*; perro de clase{ el pblico sigue (n de cuerda){ nombre = n; } nombre de cuerda pblico; los iguales booleanas pblicos (o de objeto){ si el |instanceof| de o de (( sigue ) y y ((( Dog ) la o).nombre == nombra a )){ retorne ciertamente; } de otro modo{ retorne falsamente; } } public int hashCode() {retorne name.length(); } } gato de clase{ } mascotas de |enum|{PERRO, FUSTIGA, EST EN CELO} clasifique MapTest{ la parte principal vaca esttica pblica (| args| de cuerda){ Combine < oponga se, oponga se > la m = nuevo HashMap < oponga se, oponga se>(); m.put ( " k1 ", nuevo perro ( " |aiko|")); m.put ( " k2 ", Pets.DOG); m.put ( Pets.CAT, " CAT teclea"); Siga d1 = nuevo perro ( " trbol"); // aada cierto llave / valor parea // nos deja mantener esta referencia

584

Captulo 7:

Genricos y colecciones

m.put ( d1, siga

"

llave"); m.put ( nuevo gato (), " fustigue llave"); System.out.println (m.get( " k1")); Encuerde k2 = " k2"; System.out.println (m.get( k2)); P de mascotas = Pets.CAT; System.out.println (m.get( p)); System.out.println (m.get( d1)); System.out.println (m.get( nuevo gato())); System.out.println ( m.size()); } } // #3 // #4 // #5 // #6 // #2 // #1

que producen algo as como esto:


D o g @ 1 c D O G C A T t e c l e a e l p e r r

o t e c l e e n u l o 5

Permtanos repasar la salida. El primer valor recuperado es un objeto inferior ( su valor varie ). El segundo valor recuperado es un valor (DOG) de |enum|. El tercero valor recuperado es una cuerda; note que la llave era un valor de |enum|. Examen de chasquido: Qu es la implicacin del hecho que fuimos capaz de usar con buen resultado un |enum| como una llave? La implicacin de estos son que los |enums| hacen caso de iguale () y hashCode (). Y, si parezca a la
clase java.lang.Enum en el API, ver que, en realidad, estos mtodos han sido |overridden|. La cuarta salida es una cuerda. El punto importante casi esta salida es que la llave acostumbr a recuperar la cuerda sea sido hecho de un objeto inferior. La quinta salida es nula.

El punto importante aqu est que el mtodo de get () no logr encontrar el objeto de

gato que era ms temprano insertado. (La ltima lnea de la salida confirma que en realidad, 5 teclea/valore pares existen en el mapa.) Por qu no encontramos la cuerda de llave de gato? Por qu trabaj para usar un caso de perro como una llave, al usar un caso del gato como una llave fracase? es fcil de ver se sigue el |overrode| iguala a () y hashCode ()

mientras que gato no hizo. Permtanos tomar una mirada rpida a los |hashcodes|. Usamos una frmula de |hashcode| increblemente simplista en la clase inferior -- el |hashcode| de un objeto inferior es la longitud del nombredel caso. As en este ejemplo el | hashcode| = 6. Permtanos comparar los dos mtodos de hashCode () siguientes:

Clasificar colecciones y conjuntos ( objetivos de ExamExam 6.3 y 6.5 ))

585

public int hashCode() {retorne name.length(); } public int hashCode() {retorno 4; }

// #1 / / #2

Es hora de otro examen de chasquido: Es el dos valor de inversin legal de | hashcodes| precedente? Ellos recuperarn con buen resultado los objetos de un mapa? Qu ser rpido? La respuesta a las primeras dos preguntas es s y s ni de estos |hashcodes| ser muy eficiente ( en realidad ellos ambos son increblemente ineficientes ), pero son ambos valor de inversin legal, y ellos puede ambos trabajo. La respuesta a la ltima pregunta es que el primer |hashcode| ser un poco rpidamente que el segundo |hashcode|. Por lo general, los |hashcodes| ms nicos una frmula crean, el rpidamente la recuperacin ser. La primera frmula de | hashcode| generar un cdigo diferente para cada longitud de nombre ( por ejemplo el
nombre Robert genere un |hashcode| y el nombre Benchley genere un |hashcode| diferente ). La frmula de |hashcode| de segundo puede siempre producir el mismo resultado, 4 , as que ello

atrasar que el primero. Nuestro ltimo tema de mapa es lo que sucede cuando un objeto usado como una llave haya sus valores cambiados? Si aadamos dos lneas de cdigo al fin del ms temprano MapTest.main (),
d1.name = " magnolia"; System.out. println (m.get( d1) );

conseguimos algo as como esto:


D o g @

4 D O G C A T t e c l e a e l p e r r o t e c l e e e l 5 c e r o n u l o

El perro que sea sido encontrado previamente no se pueda encontrar ahora. Porque la variable Dog.name est acostumbrado a
crear

cambi el valor del |hashcode|. Como un examen final para |hashcodes|, determine la salida para las lneas de cdigo siguientes si son aadidos al fin de MapTest.main ():
d1.name = " magnolia"; System.out.println (m.get( d1)); d1.name = " trbol"; // #1

el

|hashcode|

cambiando

el

nombre

System.out.println (m.get( nuevo perro ( " trbol"))); d1.name = " Arturo"; System.out.println (m.get( nuevo perro ( " trbol")));

// #2 // #3

586

Captulo 7:

Genricos y colecciones

Recuerde que el |hashcode| sirve para la longitud de la variable de nombre. Cuando usted
estudia un problema as, puede ser til para considerar las dos fases de la recuperacin: 1. Use el mtodo cubo correcto

de hashCode ()

para encontrar el para encontrar el

2. Use el mtodo de equals () objeto en el cubo

En la primera llamada para conseguir (), el | hashcode| es 8 (magnolia) y debe ser 6 (trbol), as la recuperacin fracasa en paso 1 y conseguimos nulos. En la segunda llamada para conseguir (), los |hashcodes| es ambos 6 , as paso 1 tiene exito. Una vez en el cubo correcto ( el " longitud del nombre = 6 " d prisa ), los iguales el mtodo de () es invocado, y desde mtodo de () de iguales perro comparan nombres, igualan () tiene exito, y la salida es la llave inferior. En la tercer invocacin de consiga (), la prueba de |hashcode| tiene exito, pero los iguales la prueba de () suspenden porque Arturo no es igual al trbol.

navegando |treesets| (penetrante) y TreeMaps


Hemos de que se habla buscar listas y conjuntos. Permtanos volver nuestra atencin para buscar TreeSets y TreeMaps. Java 6 introdujo (entre otros) dos nuevos enlaces: java.util.NavigableSet y java.util.NavigableMap. Para los propsitos del examen, usted se interesa en cmo TreeSet y TreeMap ponen en prctica estos enlaces.

Imagine que el Santa CruzEl transbordador de Monterey tiene un horario irregular. decimos que tenemos la salida de Santa Cruz diaria cronometran almacene, en tiempo militar, en un TreeSet. parecemos a cierto cdigo que determinan dos cosas: 1. El ltimo transbordador que deja antes de 4 | pm| (1600 horas) 2. El primero transporta que salga despus de 8 |pm| (2000 horas)
importe java.util.*; transbordador de clase pblico{ la parte principal vaca esttica pblica (|args| de cuerda){ TreeSet cronometran = nuevo TreeSet < el entero, nmero entero>(); times.add ( 1205); // aada ciertos tiempos de salida times.add ( 1505); times.add ( 1545); times.add ( 1830); times.add ( 2010); times.add ( 2100);

Otros mtodos de navegacin

587

// Versin de Java 5 TreeSet entero, nmero entero subconjunto = nuevo TreeSet < el entero, nmero entero>(); el subconjunto = (TreeSet) times.headSet ( 1600); System.out.println ( " J5 - ltimo antes de 4pm es: " + subset.last()); TreeSet entero, nmero entero sub2 = nuevo TreeSet < el entero, nmero entero>(); sub2 = (TreeSet)times.tailSet(2000); System.out.println ( " J5 - primero despus de 8pm es: " + sub2.first()); // La versin de Java 6 usando el nuevo () inferior y los mtodos de () ms altos

} }

System.out.println ( " J6 - ltimo antes de 4pm es: " + times.lower (1600) ); System.out.println ( " J6 - primero despus de 8pm es: " + times.higher (2000) );

Esto deba producir lo siguiente:


J5 - ltimo antes de 4pm es: 1545

J5 - primero despus de 8pm es: 2010 J6 - ltimo antes de 4pm es: 1545 J6 - primero despus de 8pm es: 2010

Como puede ver en el cdigo precedente, antes de la adicin del enlace de NavigableSet, centrar la puntera en un sitio arbitrario en un conjunto - usar los mtodos disponibles en Java 5-- eran una propuesta de |clunky| y de cmputo caro. Por otra parte, usar los nuevos mtodos de Java 6 baja () y () ms alto, el cdigo se convierte en mucho limpiador. Para el propsito del examen, los mtodos de NavigableSet relacionados con este tipo de la navegacin est
inferior (), derribe (), ms alto (), revistiendo (), y la principalmente paralela mtodos de NavigableMap son lowerKey (), floorKey (), ceilingKey (), y higherKey (). La diferencia entre bajar () y derribe () es que baje () retorna el elemento menos del elemento dado, y derribe () retorna el

elemento menos de o igual para el elemento dado. Similarmente, () ms alto retorna el elemento mayor que el elemento dado, y revistiendo () retorne el elemento mayor que o igual para el elemento dado. La tabla 7-4 resume los mtodos que usted deba saber para el examen.

otros mtodos de navegacin


Adems de los mtodos nosotros slo discutimos existe unos cuantos ms nuevos mtodos de Java 6 que, pueda ser considerado los mtodos de "navegacin".

588

Captulo 7:

Genricos y colecciones

Votacin

Aunque la idea de la votacin no es nueva a Java 6 (como usted ver en un minuto, PriorityQueue tiene un mtodo de () de
votacin antes de Java 6), no conocer TreeSet y TreeMap. La idea de la votacin es que nosotros queremos ambos para recuperar y quitar un elemento del comienzo o el fin de una coleccin. En el caso de TreeSet, pollFirst ()

retorna y quite la primera entrada en el conjunto, y pollLast () retorna y quite el ltimo. Similarmente, TreeMap ahora proporciona pollFirstEntry () y pollLastEntry () para recuperar y quitar pares de valor clave.

Descender por orden


Tambin nuevo a Java 6 para TreeSet y TreeMap es los mtodos que retornan una coleccin en el orden inverso de la coleccin en que el mtodo es sido invocado. Los mtodos importantes para el examen es TreeSet.descendingSet () y TreeMap.descendingMap(). La tabla 7-4 resume los mtodos de "navegacin" que usted necesitar saber para el examen.

tabla 7-4 mtodos relacionado importante de "navegacin"

Descripcin de mtodo
TreeSet.ceiling (e) retorne el elemento ms bajo > = e TreeMap.ceilingKey (llave) retorne la llave ms bajo > = teclee TreeSet.higher (e) retorne el elemento ms bajo > la e TreeMap.higherKey (llave) retorne la llave ms bajo > teclee TreeSet.floor (e) retorne el elemento ms alto < = e TreeMap.floorKey (llave) retorne la llave ms alta < = teclee TreeSet.lower (e) retorne el elemento ms alto < la e TreeMap.lowerKey (llave) retorne la llave ms alta < teclee TreeSet.pollFirst () retorna y quite la primera entrada

TreeMap.pollFirstEntry () retorna y quite el primer par de valor clave TreeSet.pollLast () retorna y quite la ltima entrada TreeMap.pollLastEntry () retorna y quite el ltimo par de valor clave TreeSet.descendingSet () retorne un NavigableSet en marcha atrs orden TreeMap.descendingMap () retorne un NavigableMap en marcha atrs orden

Colecciones apoyado

589

colecciones apoyadas
Algunas de las clases en el paquete java.util soportan el concepto de las "colecciones apoyadas". Nosotros usaremos un poco de cdigo para ayudar a explicar la idea:
TreeMap < encuerde, encuerde > combine = nuevo TreeMap < encuerde, avance en lnea>(); map.put ( " un ", " hormiga"); map.put ( "d", " siga"); map.put ( "h", " est en celo"); SortedMap < encuerde, encuerde > el |submap|; |submap| = map.subMap ( "b", // #1 crean una coleccin " g"); apoyada System.out.println ( el mapa + " " + submap); #2 muestran contenidos map.put ( "b", " batee"); submap.put ( "f", " pesque"); //

// #3 aumentan // #4 original aumenta copia // #5 aumentan original - fuera de // #6 de rango aumente la copia -- fuera del rango //

map.put ( "R", " mapache"); // submap.put ( "p", " cerdo");

System.out.println ( el mapa + " " + submap); #7 muestran los contenidos finales

Esto deba producir algo as como esto:

{a=ant, d=dog, h=horse} {d=dog} {a=ant, b=bat, d=dog, f=fish, h=horse, r=raccoon} {b=bat, d=dog, f=fish}

El mtodo importante en este cdigo es el mtodo de () TreeMap.subMap. es fcil de suponer (y es correcto), que el mtodo de
subMap () est haciendo una copia de una porcin del TreeMap nombre mapa. La primera

lnea de la salida verifica las conclusiones que hemos dibujado slo. Lo que suceda despus es poderoso y un poco inesperado ( ahora nosotros est consiguiendo para porque son las colecciones apoyadas llamadas ). Cuando nosotros aadimos los pares de valor clave para el original TreeMap o la de copia parcial SortedMap, las nuevas entradas eran de forma automtica aadidas a la otra coleccin -- a veces. Cuando el |submap| era creado, provemos un rango de valor para la nueva coleccin. Este rango define no solo lo que deba ser incluido cuando se crea la copia parcial, sino tambin defina el rango de valores que puede ser aadido a la copia. Como nosotros podemos verificar mirando en el segundo la lnea de la salida, nosotros podemos aadir nuevas entradas a una u otra coleccin al alcance de la copia, y las nuevas entradas saque a luz en ambas colecciones. Adems, podemos aadir una nueva entrada a la coleccin original, an si es fuera el rango de la copia. En este caso, la nueva entrada sacar a luz sla en el original -- no ser aadido a la copia porque es fuera el rango de la copia. El anuncio que nosotros comentamos el exterior raya a #6. Si usted intento para aadir una entrada de exterior de rango a la coleccin copiada una excepcin se tirar.

590

Captulo 7:

Genricos y colecciones

Para el examen, necesitar comprender las bases slo explicado, ms unos cuantos ms detalles cerca de tres mtodos de TreeSet ( el juego de audfonos (), el subconjunto (), y
tailSet () ), y tres mtodos de TreeMap (headMap (), subMap (), y tailMap ()). Como con los mtodos de navegacin orientada nosotros slo discuti, podemos ver una gran cantidad de barras entre el TreeSet y los mtodos de TreeMap. Los mtodos de () /headMap () de juego de audfonos crean un subconjunto que empieza al comienzo de la coleccin original y fines al punto especificado por el argumento del mtodo. Los mtodos de tailSet () /tailMap () crean un subconjunto que empieza al punto especificado por el argumento del mtodo y va al fin de la coleccin original. Finalmente, los mtodos de () /subMap () de subconjunto le permiten para especificar ambos puntos de principio y fin para la coleccin de subconjunto que est creando. Como usted podra esperarse, la pregunta de si el subconjunto puntos de fin coleccin es inclusivo o exclusiva es un poco tramposa. Las noticias buenas es que para el examen usted tiene que recordar slo ese cuando estos mtodos son invocados con |endpoint| y argumentos booleanas, el booleana siempre significa " es inclusivo?". un poco ms las noticias buenas es que todo lo que tiene que saber para el examen es se a menos que especficamente indicado por un argumento booleana, el punto de partida de un subconjunto siempre es inclusivo. Finalmente, usted notar cuando usted estudia el API que todos los mtodos nosotros ha sido discutiendo aqu tiene una versin sobrecargada que no conocer Java 6. Los mtodos ms viejos retorne un SortedSet o un SortedMap, los nuevos mtodos de Java 6 retornan un NavigableSet o un NavigableMap. La tabla 7-5 resume estos mtodos.
tabla 7-5 mtodos de "coleccin apoyada" importante para TreeSet y

TreeMap

Descripcin de mtodo
el juego de audfonos ( e, b*) Resultados un subconjunto terminando a la e de elemento y con exclusin de la e HeadMap ( k, b*) Resultados un |submap| terminando a k clave y con exclusin del k clave TailSet ( e, b*) Resultados un subconjunto empezando a y incluyendo la e de elemento TailMap ( k, b*)

Resultados un |submap| empezando a y

incluyendo el k clave
el subconjunto ( s, b*, e, b*) Resultados un subconjunto empezando a s de elemento y conclusin slo antes de la e de elemento SubMap ( s, b*, e, b*) Resultados un |submap| empezando a s clave y conclusin slo antes de teclear s * NOTA: Estos argumentos booleanas son opcionales. Si existen es un mtodo de Java 6 que le deja especificar si el |endpoint| es exclusivo, y estos mtodos retornan un NavigableXxx. Si el argumento(s) booleana no existe, el mtodo retorna ni un SortedSet o un SortedMap.

Colecciones apoyado

591

Decimos que ha creado una coleccin apoyada usando o unos tailXxx () o subXxx () method.Typically en estos casos las colecciones originales y de copia tienen los elementos de "primero" diferentes. Para el examen ello es importante que recuerda que los mtodos de
pollFirstXxx () siempre quitarn la primera entrada de la coleccin en que se invocan, pero ellos quitarn un elemento de la otra coleccin slo si tenga mismo valor. As ello es la mayor parte del probablemente ese invocando pollFirstXxx () en la copia quite una

entrada de ambas colecciones, pero invocar pollFirstXxx () en el original quitar slo la entrada del original.

Usar la clase de PriorityQueue

La ltima clase de coleccin que necesitar comprender para el examen es el PriorityQueue.

A diferencia de las estructuras de cola bsicas que es primer-en, de primer exterior en defecto, un PriorityQueue ordena sus elementos usando una prioridad de usuario definido. La prioridad puede tan simple como el orden natural ( en que, por ejemplo, una entrada de 1 puede ser una prioridad ms alta que una entrada de 2 ). Adems, un PriorityQueue puede ser ordenado usando un comparador, que le deje definir cualquier ordenando desea. Las colas tienen unos cuantos mtodos no proporcionar en otros enlaces de coleccin: el atisbo (), obtenga
votos (), y ofrezca (). importe java.util.*; clasifique PQ{ PQsort de clase esttico comparador de enseres { // clase inversa el |int| pblico compara ( el entero, nmero entero un, entero, nmero entero dos ){ retorno dos - uno; // unboxing } } la parte principal vaca esttica pblica (| args| de cuerda){ int[] ia = {1, 5,3,7,6,9,8}; // datos desordenados PriorityQueue entero, nmero entero pq1 = nuevo PriorityQueue < el entero, nmero entero>(); // use la orden natural para ( la x de |int|: el |ia| ) // carga cola

592

Captulo 7:

Genricos y colecciones

pq1.offer ( la x); para ( la x de |int|: el |ia| ) // repasa cola System.out.print ( pq1.poll() + " "); System.out.println(""); PQsort pqs = new PQsort(); PriorityQueue entero, nmero entero pq2 = nuevo PriorityQueue ( 10 , |pqs|); para ( la x de |int|: el |ia| ) // // consiga un comparador // comparador de uso

cargue la cola pq2.offer ( la x); System.out.println ( " tamao " + pq2.size()); System.out.println ( " atisbo " + pq2.peek()); System.out.println ( " tamao " + pq2.size()); System.out.println ( " votacin " + pq2.poll()); System.out.println ( " tamao " + pq2.size()); para ( la x de |int|: el |ia| ) // repase la cola System.out.print ( pq2.poll() + " "); } }

Este cdigo produce algo as como esto:


1 3 5 6 7 8 9 tamao 7 atisbo 9 tamao 7 obtenga votos 9 tamao 6 8 7 6 5 3 1 cero

Parecemos a este en detalle. El primer bucle PARA itera por el conjunto de |ia| , y use el mtodo de () de oferta para aadir elementos al PriorityQueue nombr a pq1. El segundo bucle PARA itera por pq1 usar el mtodo de () de votacin, que retorna la entrada ms alta de prioridad en pq1 AND quita la entrada de la cola. El anuncio que los elementos son retornados en la orden de prioridad ( en este caso, la orden natural ). Despus, nosotros creamos un comparador -en este caso, un comparador que ordena elementos en el opuesto de la orden natural. Nosotros usamos este comparador para construir un secundar PriorityQueue, pq2 , y nosotros cargamos lo con el mismo conjunto que nosotros usamos ms temprano. Finalmente, nosotros verificamos el tamao de pq2 antes y despus llama al atisbo () y
obtenga votos (). Esto confirma que () de atisbo retorna el elemento ms alto de prioridad en la cola sin quitando lo, y obtenga votos () retorna el elemento de prioridad

ms alto, y lo quita de la cola. Finalmente, repasamos los elementos restantes en la cola.

Colecciones apoyado

593

Visin general de mtodo para conjuntos y colecciones

Para estas dos clases, hemos cubierto ya los mtodos ms tramposos podra encontrar en el examen. Las listas de tabla 7-6 un resumen de los mtodos que deba tener conciencia de. ( la nota: La sintaxis de T se explicar ms tarde en este
captulo; por ahora, considera lo como significando " cada conjunto que no es un conjunto de primitivos." )

tabla 7-6 teclee los mtodos en conjuntos y colecciones

Mtodos claves en java.util.arrays


lista esttico AsList (T)

Descripciones Convierta un conjunto a una lista ( y les endurezca se ). |int| esttico BinarySearch ( oponga se, teclee ) Busque un conjunto clasificado para un valor dado, retorne |int| esttico BinarySearch ( primitivo, teclee ) un ndice o punto de insercin. |int| esttico BinarySearch (T, llave, comparador) Busque un conjunto de comparador clasificado para un valor. los iguales booleanas estticos ( oponga se, objete )iguales Compare dos conjuntos para booleanas estticos( primitivo, primitivo ) determinar si sus contenidos son iguales. el vaco esttico pblico clasifica (objeto) el vaco esttico Clasifique los elementos de un pblico clasifique (primitivo) conjunto por la orden natural. el vaco esttico pblico clasifica (T, comparador) Clasifique los elementos de un conjunto usando un comparador. cuerda esttico pblico ToString (objeto) cuerda esttico Cree una cuerda que contiene los pblico ToString (primitivo) contenidos de un conjunto. Mtodos claves en descripciones java.util.Collections
|int| esttico BinarySearch ( liste, teclee ) busque una lista

"clasificada" para un valor dado,

|int| esttico BinarySearch ( liste, teclee, el comparador )

retorne un ndice o punto de insercin.


el vaco esttico da marcha atrs (lista) d marcha atrs la

orden de elementos en una lista.


comparador esttico retorno de reverseOrder () un comparador que clasifican el contrario de comparador esttico ReverseOrder (comparador) la corriente de

la coleccin clasifica sucesin.


el vaco esttico clasifica (lista) clasifique una lista o por

orden natural o por el A


el vaco esttico clasifica ( liste, el comparador ) comparador .

594

Captulo 7:

Genricos y colecciones

Visin general de mtodo para lista, pone, combine, y forme fila

Para estos cuatro enlaces, hemos cubierto ya los mtodos ms tramposos podra encontrar en el examen. Las listas de tabla 7-7 un resumen de la lista, conjunto, y mtodos de utilizacin de mapas que deba tener conciencia de, pero no olvide los nuevos mtodos "navegables" derriba, baje, revistiendo, y ms alto que discuti unos cuantos folia retroceda.
tabla 7-7 teclee los mtodos en lista, conjunto, y mapa

Teclee mtodos de enlace


booleana aada (elemento) booleana sume ( haga un ndice de, el elemento )

lista

conju Mapa nto

Descripci ones Aada un elemento. Para las listas, opcionalmente aada el elemento a un punto de ndice.

X X

booleana contenga (objeto) containsKey booleana (llave de objeto) containsValue booleana (valor de objeto)

X X

Busque una coleccin para un objeto ( o, opcionalmente para combinan una llave ), retorne el resultado como un
booleana.

el objeto consigue (ndice) el objeto consiga (llave)

Consiga un objeto de una coleccin, por la via de un ndice o una llave. Consiga la ubicacin de un objeto en una lista.

int indexOf(object)

Iterator iterator()

Consiga un Iterator para una lista o un conjunto.


X

Ponga keySet ()

Retorne un conjunto conteniendo las llaves de un mapa. Aada un llave / valor parea a un mapa.

put( teclee, valore )

remove(ndice) quita (objeto)

X X

X Quite un elemento por la via de un

remove(llave) () de tamao de |int| X X

ndice, o por la via del valor del elemento, o por la via de una llave.
X X

Retorne el nmero de elementos en una coleccin. Retorne un conjunto que contiene los elementos de la coleccin.

Objete toArray de T de toArray ()

(T)

Para el examen, los mtodos de PriorityQueue que son importantes para comprender son () de oferta ( que es similar a aada () ), el atisbo () ( que recuperan el elemento a la cabeza de la cola, pero no borra lo ), y obtenga votos () ( que recuperan el elemento principal y lo quite de la cola ).

Los genricos teclean ( objetivos de examen 6.3 y 6.4 )

595

Es importante saber algunos de los detalles de natural ordering.The siguiendo el cdigo le ayudar a comprender las posiciones relativas de los caracteres en maysculas, los caracteres, y espacios en minsculas en un orden natural:
Encuerde |sa| ={">|ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff|| ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff|| ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff|| ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff||ff|< ", " >ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff< ", " >ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff< ", " >FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF<"}; // ordenado? PriorityQueue cuerda pq3 = nuevo PriorityQueue < avance en lnea>(); para ( encuerde s: sa) pq3.offer ( la s); para ( encuerde s: sa) System.out.print ( pq3.poll() + " ");

Estos productos
> la f < >FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF< >f< >|ff|<

Si recuerde que los espacios clasifican antes de caracteres y que las letras en maysculas clasifican antes de caracteres en minsculas usted debe ser bueno para ir a traer el examen.

objetivo de certificacin

el genrico teclea ( los objetivos 6.3 y 6.4 )

6.3 Escritura cdigo eso usos el genrico versiones de el Colecciones API, en casa detalle el Conjunto, Lista, y Mapa enlaces y ejecucin clases. Reconozca el limitaciones de el no-genrico Colecciones API y cmo para refactor cdigo para uso el genrico versiones. 6.4 Desarrolle se cdigo eso marcas apropiado uso de tipo parmetros en casa class/interface declaraciones, caso variables, mtodo argumentos, y retorno tipos; y escritura genrico mtodos o mtodos eso marca uso de wildcard tipos y comprenda el similitudes y diferencias entre stos dos acercamientos. Escritura cdigo eso usos el NavigableSet y NavigableMap enlaces.

596

Captulo 7:

Genricos y colecciones

Conjuntos en Java han sido siempre caja fuerte de tipo - un conjunto declar como represente la cuerda (cuerda) no puede aceptar entero, nmero entero ( o |ints| ), siguen, o algo aparte de las cuerdas. Pero recuerde que antes de Java 5 no exista ninguna sintaxis para declarando una coleccin tipo seguro. Para hacer un ArrayList de cuerdas, usted dijo,
ArrayList myList = new ArrayList();

o, el equivalente polimorfo
Liste MyList = nuevo ArrayList();

No exista ninguna sintaxis que le deja especificar que myList tomar cuerdas y nicas
cuerdas. Y sin la va para especificar un tipo para el ArrayList, el compilador no pudo imponer que usted pone las cosas slas del tipo especificado en la lista. A partir de Java 5 , nosotros puede usar los genricos, y mientras que son no solo para hacer

representan las colecciones seguras, que son poco ms o menos todo la mayor parte de los desarrolladores usan genricos para. As, mientras que los genricos no son para las colecciones, considere colecciones como la razn abrumadora y motivacin para aadir genricos al idioma. Y ello no era una buena decisin, ni ha sido una adicin totalmente de bienvenida. Porque conjuntamente con toda la seguridad de tipo contenta delicada, los genricos vienen con una gran cantidad de equipaje - la mayor parte de que nunca ver o ser importante para uno, pero existe ciertos |gotchas| que suben de modo sorprendente rpidamente. Nosotros cubrir el un la mayor parte del probablemente para sacar a luz en su propio cdigo, y sos es tambin los asuntos que necesitar saber para el examen. El desafo ms grande para el sol al aadir genricos al idioma ( y la razn principal ello les tom tan largo ) era cmo negociar con la herencia codifique construya sin genricos. Los ingenieros de Java de sol obviamente no quisieron romper el cdigo de Java existente de todos, as que ellos tuvieron que encontrar la manera para Java clasifican con ambas caja fuerte de tipo (genrico) y caja fuerte de no-tipo ( no-genrico/pre-Java 5 ) colecciones para todava de trabajo en conjunto. Su solucin no es el ms amistoso, pero le deja usar el cdigo no genrico ms viejo, as como use el cdigo genrico que juega con el cdigo no genrico. Pero note que nosotros diga " juegan, " y no " juegan WELL." Mientras que usted puede integrar Java 5 y Java 6 el cdigo genrico con cdigo de nogenrico de herencia, las consecuencias puede ser desastroso, y desafortunadamente, la mayor parte de los desastres suceda a |runtime|, no compile tiempo. Afortunadamente, sin embargo, la mayor parte de los compiladores generarn advertencias para decirle cuando est usando inseguro (no-genrico de significado) colecciones. El examen de Java 5 cubre ambos preJava 5 (no-genrico) y colecciones de estilo de Java 5 , y ver las preguntas que espera usted para comprender el tramposo

Los genricos teclean ( objetivos de examen 6.3 y 6.4 )

597

los problemas se puede venir de mezclar el cdigo de no-genrico y genrico en conjunto. Y como algunos de los otros tpicos en este libro, pudo llenar un libro entero si realmente quiso cubrir cada detalle sobre los genricos, pero el examen ( y este libro ) cubren ms de la mayor parte de los desarrolladores alguna vez necesitarn usar.

la va de herencia para hacer colecciones


Aqu est una revisin de un pre-Java 5 ArrayList tuvo la intencin de teniendo cuerdas. (Decimos che el "prometido" porque se es casi todo tuvo - intenciones buenas para asegurarse de que el ArrayList tendra las cuerdas slas).
Liste MyList = nuevo ArrayList(); // no pueda declarar un tipo myList.add ( " Federiquito"); cuerdas myList.add ( nuevo perro()); perros tambin // OK, tendr // y tendr los

myList.add (nuevo entero, nmero entero( 42)); // y entero, nmero entero...

una coleccin no genrica puede tener cada tipo del objeto ! una coleccin no genrica es bastante contenta para tener algo que no es un primitivo. Este maravilloso era totalmente hasta el programador para ser...cuidadoso. Tenga nada para garantizar el tipo de coleccin no era mismo miembro amigable de programador para tal idioma fuertemente representado. Nosotros somos as acostumbrados al compilador pararnos de asignar, digamos, un |int| a una referencia booleana o una cuerda a
una referencia inferior, pero con las colecciones, ello era, " venga en ! la puerta es siempre abierta ! todos los objetos son de bienvenida aqu cualquier tiempo !" y desde una coleccin pueda tener algo, los mtodos que consiguen objetos fuera de la coleccin tendran slo un tipo del retorno teclea java.lang.Object. Ese maravilloso que consiguiendo una cuerda retire de que nuestro slo-cuerdas-tenga la intencin de liste requiera un lanzamiento:

Encuerde la s = (cuerda) myList.get ( 0);

Y desde usted no pudo la garanta que lo que era que viene el exterior realmente era una cuerda ( despus que se permita poner algo en la lista ), el lanzamiento pudo fracasar al |runtime|. As, los genricos cuidan ambos fines ( el presentando y consiguiendo el exterior ) por imponer el tipo de sus colecciones. Permtanos actualizar la lista de cuerda:
Liste cuerda MyList = nuevo ArrayList < avance en lnea>(); myList.add ( " Federiquito"); // OK, ello tendr cuerdas myList.add ( nuevo perro()); // error de compilador !!

598

Captulo 7:

Genricos y colecciones

Tiempo perfecto. Eso es exactamente lo que deseamos. Por usar sintaxis de genricos -- que significa poniendo el tipo en los corchetes de ngulo, estamos diciendo el compilador que esta coleccin puede mantenerse slo encuerde objetos. El tipo en los corchetes de ngulo es mencionado para como o el " tipo de |parameterized|, " represente el parmetro, " o por supuesto anticuado justo " teclee." en este captulo, nosotros nos referiremos a lo ambas nuevas vas. As, ahora ese lo que usted pone IN es avalado, puede garantizar tambin lo que salga, y esto significa que usted puede librarse del lanzamiento cuando consigue algo de la coleccin. En lugar de
Encuerde la s = (cuerda) myList.get ( 0); / / pre genrico

s, cuando una cuerda de // no era garantiz ada

podemos decir ahora slo


Encuerde la s = myList.get ( 0);

El compilador ya sabe que myList contiene las cosas slas que puede ser asignado a una cuerda referencia, as ahora no existe ninguna necesidad para un lanzamiento. Hasta ahora, parece bastante simple. Y con el bucle PARA nuevo, usted puede iterar por supuesto sobre el avalado-para-es-lista de cuerda:
para ( encuerde s: myList) { x de |int| = s.length(); // ninguna necesidad para un lanzamiento antes de llamar un mtodo de cuerda ! el compilador de // ya supo la "s" era una venida de cuerda de MyList}

Y por supuesto usted puede declarar un parmetro de tipo para un argumento de mtodo, que hacen entonces el argumento una referencia tipo seguro:
takeListOfStrings vaco (lista< encuerda >cuerdas) { strings.add("foo"); // ningn de problema aadiendo una cuerda}

El mtodo sobre no poder compilar si nosotros lo cambi para


takeListOfStrings vaco (lista< encuerda >cuerdas){ strings.add (nuevo entero, nmero entero( 42)); // NINGN!! las cuerdas son la caja fuerte de tipo}

Los genricos teclean ( objetivos de examen 6.3 y 6.4 )

599

Los tipos de retorno puede declararse obviamente represente seguro tambin:


el pblico lista <perro> getDogList () { Liste perro siguen = nuevo ArrayList < siga>(); // ms cdigo para insertar perros

p e r r o s d e r e t o r n o ; }

El compilador le parar de retornar algo no compatible con una lista perro ( aunque lo que es y no es compatible vaya a conseguir muy interesante en un minuto ). Y desde las garantas de compilador que slo una caja fuerte de tipo sigue la lista es retornado, esos llamando el mtodo no necesitar un lanzamiento para tomar perros de la lista:
Siga la d = getDogList ().consiga ( 0); // KNOW che un perro est viniendo exterior

Con pre-Java 5 , el no-genrico codifica, el mtodo de getDogList () podra ser


el pblico lista getDogList () { Liste los perros = nuevo ArrayList(); // cdigo para aadir los perros slos... los dedos cruzaron... perros de retorno; // una lista de ANYTHING trabajar aqu}

y el llamador necesitara un lanzamiento:


Siga la d = (perro) getDogList ().consiga ( 0);

( el lanzamiento en este ejemplo se aplica a lo que venga de la lista consiga mtodo de () ; no estamos lanzando lo que es retornado por el mtodo de getDogList (), que es una lista.)
Pero qu se sabe del beneficio de una completamente heterognea? En otros qu ocurrira si usted gusta el hecho de genricos pudo hacer un ArrayList tener cada tipo del objeto? coleccin trminos, que antes que pudo

Liste MyList = nuevo ArrayList(); // nogenrico, de estilo antiguo

sea casi idntico para


Liste objeto MyList = nuevo ArrayList < oponga se>(); // ANY de asideros objeta tipo

600

Captulo 7:

Genricos y colecciones

Declarar una lista con un parmetro de tipo de hace una coleccin que trabaja en casi la misma va como el original pre-Java 5, coleccin no genrico -- usted puede poner cada objeto teclee en la coleccin. Usted ver un poco posterior que las colecciones y colecciones no genricas del tipo <objeto> no es totalmente el mismo, pero la mayor parte del tiempo las diferencias no importa. Oh, si slo esto era el fin de la historia...pero all estn todava unos cuantos asuntos tramposos con argumentos de mtodos, el polimorfismo, e integrando el cdigo de genrico y no-genrico, as que estamos consiguiendo la subida calentada aqu.

genricos y cdigo de herencia

Las cosa de genricos ms fciles que necesitar saber para el examen son cmo actualizar el cdigo no genrico para hacer ello genrico. Slo aade un tipo en los corchetes de ngulo ( < > ) inmediatamente siguiendo la coleccin teclee en ambas declaracin variable y la llamada de constructor, incluyendo cualquier parte declara una variable ( de modo que signifique los argumentos y tipos de retorno demasiado ). una lista de pre-Java 5 tenido intenciones para tener los entero, nmero entero slos:
Liste MyList = nuevo ArrayList();

llegue a ser
Liste entero, nmero entero MyList = nuevo ArrayList < el entero, nmero entero>();

y una lista tuvo intenciones para tener las cuerdas slas abandone
el pblico lista changeStrings (s de ArrayList){ }

para esto:
el pblico lista <cuerda> changeStrings (ArrayList <cuerda> la s){ }

Fcilmente. Y si existe el cdigo que us la versin no genrica ms temprana y ejecute un lanzamiento para conseguir las cosas fuera, que no rompern el cdigo de todo el mundo:
El entero, nmero entero yo = (entero, nmero entero ) list.g et ( 0); // ya no tire el anzuel o necesi te, // pero no causar dao

Mezclar colecciones no genricas y genricas ( objetivos de examen 6.3 y 6.4 )

601 Mezclar colecciones no genricas y genricas


Ahora aqu est donde empieza a conseguir interesante...imagine tenemos un ArrayList, del tipo de nmeros enteros, y nosotros estamos pasando lo en un mtodo de una clase cuyo cdigo fuente que no tenemos acceso a. Puede este trabajo?
// una clase de Java 5 usando una coleccin genrica importe java.util.*; el pblico clasifica TestLegacy{ la parte principal vaca esttica pblica (|args| de cuerda){ Liste entero, nmero entero MyList = nuevo ArrayList < el entero, nmero entero>(); // represente la coleccin segura myList.add ( 4); myList.add ( 6); Vbora de vbora = nueva vbora(); int total = adder.addAll(myList); // pasa lo a un argumento untyped System.out.println ( sume); } }

La clase de no-genricos ms vieja queremos usar:


importe java.util.*; vbora de clase{ addAll de |int| (lista de lista){ // mtodo con un no-genrico lista argumento, // pero asume (sin la garanta) que ser los entero, nmero entero Iterator lo = list.iterator(); el |int| suma = 0; mientras que ( it.hasNext ()) { el |int| yo = entero, nmero entero de (( ) it.next ()).intValue(); total += yo; } total de retorno;

} }

S, estos trabajos slo se aclaran. Puede mezclar el cdigo genrico correcto con el cdigo de no-genrico ms viejo, y todos se alegran de. En el ejemplo previo, el mtodo de herencia de addAll () asumido ( confie en? esperado?)
que la lista pas en estaba en realidad limitado a los entero, nmero entero, aunque cuando el cdigo era escrito, no exista ninguna garanta. Estuvo a la altura de los programadores para tener cuidado.

602

Captulo 7:

Genricos y colecciones

Desde el mtodo de addAll () no est haciendo algo excepta la ganancia el entero, nmero entero ( usando un lanzamiento ) de la lista y accediendo su valor, no exista ningunos problemas. En ese ejemplo, all no estaba ningn riesgo al cdigo del llamador, pero el mtodo de herencia podra haber soplado arriba si la lista pas en contenido en lo absoluto entero, nmero entero ( que cause un ClassCastException ). Pero ahora imagine que usted llama un mtodo de herencia que no lee un valor pero aade algo al ArrayList? Puede este trabajo?
importe java.util.*; el pblico clasifica TestBadLegacy{ la parte principal vaca esttica pblica (| args| de cuerda){ Liste entero, nmero entero MyList = nuevo ArrayList < el entero, nmero entero>(); myList.add ( 4); myList.add ( 6); Insercin en = nueva insercin(); in.insert(myList); // el paso lista <entero, nmero entero> al cdigo de herencia } } insercin de clase{ // mtodo con un no-genrico lista argumento el vaco inserta (lista de lista){ list.add (nuevo entero, nmero entero( 42)); // aumente la lista

entrante } }

Seguro, este cdigo trabaja. Ello compila, y que ello corre. El mtodo de () de
insercin pone un entero, nmero entero en la lista que es sido tecleado originalmente como, tan ningn de problema. Pero...qu ocurrira si modificamos el mtodo de () de insercin as: el vaco inserta (lista de lista){ list.add (nueva cuerda( " 42")); } // ponga una cuerda en la lista // pasado en casa

Puede ese trabajo? S, tristemente, hace ! lo ambos compila y corren. Ninguna excepcin |runtime|. Sin embargo, alguien slo atiborrado una cuerda en un represente de modo supuesto ArrayList seguro del tipo . Cmo puede que es? Recuerde, el cdigo de herencia ms viejo es sido permitido poner algo a todo (exceptuar primitivos) en una coleccin. Y a fin de soportar cdigo de herencia, Java 5 y Java 6 permita su nuevo cdigo seguro tipo hacer uso del cdigo ms viejo ( lo ltimo el sol quiso hacer era preguntar que varios milln desarrolladores de Java modifiquen todo su cdigo existente ).

Mezclar colecciones no genricas y genricas ( objetivos de examen 6.3 y 6.4 )

603
As, el compilador de Java 5 o Java 6 es forzado en le dejar compilar su nueva caja fuerte de tipo codifique aunque su cdigo invoca un mtodo de una clase ms vieja que tome un argumento no-tipo seguro y haga que sabe lo que con ello. Sin embargo, slo porque el compilador de Java 5 permite este cdigo para compilar no

lo significa tener que alegrarse de sobre ello. En realidad el compilador le advertir que est tomando un grande, grande arriesgue enviar su ArrayList protegido delicado en un mtodo peligroso que puede tener su va con su lista y poner en los flotadores, avanzan en lnea, o an perros. Cuando usted llam el mtodo de addAll
() en el ejemplo ms temprano, ello no insert algo a la lista ( lo simplemente aadido levante los valores dentro de la coleccin ), as no exista ningn riesgo al llamador que su lista podra ser modificada en cierta va horrible. Compila y corre la multa justa. Pero en la versin segunda, con la herencia inserte el mtodo de () que

aade una cuerda, el compilador gener una advertencia:

javac TestBadLegacy.java Nota: TestBadLegacy.java usan las operaciones desenfrenadas o inseguras. Nota: Recompile con - Xlint:unchecked para los detalles.

Recuerde ese compilador advertencias sea NO considerado A compilador failure. El compilador gener un archivo de clase perfectamente vlido de la compilacin, pero era bastante bondadoso para decirle hablando, en esas mismas palabras," yo espero seriamente de que sepa lo que est haciendo porque este cdigo viejo tiene el respeto de NO ( o conocimiento uniforme ) de su representando, y pueda hacer sea lo que sea el infierno que quiere su ArrayList precioso ."

Est seguro le sepa la diferencia entre " compilacin fracase " y " compila sin error " y " compila sin advertencias " y " compila con las advertencias."en la mayor parte de las preguntas en el examen, usted se inquieta slo sobre compilar en forma de v. la compilacin fracasa - las advertencias de compilador no importan para la mayor parte del examen. Pero cuando est usando genricos, y mezclando ambos represente y codifique, advierten materia.

De vuelta a nuestro ejemplo con el cdigo de herencia que haga una insercin, tenga presente que para las versiones de BOTH del mtodo de () de insercin ( que aada un
entero, nmero entero y que aada una cuerda ) el compilador emite advertencias. El compilador no sabe si

604

Captulo 7:

Genricos y colecciones

el mtodo de () de insercin est aadiendo lo


correcto (entero, nmero entero) o la cosa mala (cuerda). La razn el compilador produce una advertencia es porque el mtodo es ADDING algo a la coleccin ! en otros trminos, el compilador sabe existe una oportunidad el mtodo podra aadir la cosa mala a una coleccin el llamador piense es la caja fuerte de tipo.

Para los propsitos del examen, a menos que la pregunta incluye una respuesta que mencionan advierten, entonces an si sepa la compilacin produzca las advertencias, que es todava un exitoso compile! compilando con advertencias sea considerado NEVER una falta de compilacin. Otro tiempo ms - si vea el cdigo que sabe compile con las advertencias, usted no deba escoger " compilacin fracasa." como un answer.The lnea fundamental es esto: el cdigo que compila con advertencias es todava un exitoso compile. Si la pregunta de examen quiere probar su conocimiento de si el cdigo producir una advertencia ( o lo que puede hacer al cdigo para ELIMINAR advertencias ), la pregunta (o responde) incluir explcitamente

la palabra " advertencias."

Hasta ahora, hemos mirado a cmo el compilador generar advertencias si ve que existe un casual su coleccin seguro tipo se pudo daar por cdigo de caja fuerte de notipo, ms viejo. Pero una de las preguntas desarrolladores a menudo pregunta es, " aprobacin, seguro, compila, pero por qu hace lo RUN? Por qu hace el cdigo que inserta la cosa mala en mi lista trabaje al | runtime|?" en otros trminos, porque haga el JVM deja atiborrar el cdigo viejo en su ArrayList, sin todos los problemas a todo? Ningunas excepciones, nada. Slo una quietud, detrs de las escenas, sume la violacin de su seguridad de tipo que no podra hallar hasta el momento posible peor. Existe una verdad grande usted necesita saber comprende porque que ello corre sin problemas - el JVM no tiene ninguna idea que su ArrayList tuvo por deber para tener los entero, nmero entero slos. La informacin de mecanografa no existe al |runtime| ! todo su cdigo genrico es estrictamente para el compilador. Por un proceso llamado " represente la borradura, " el compilador hace todo de sus verificaciones en su cdigo genrico y entonces descorteza la informacin de tipo fuera del |bytecode| de clase. A | runtime| , el cdigo de coleccin de ALL ambas herencia y nuevo cdigo de Java 5 le escribir usando genricos -buenas apariencias exactamente como la versin de pre-genrico de colecciones. Ninguno de su informacin de mecanografa existe al | runtime|. En otros trminos, aunque usted WROTE
Liste entero, nmero entero MyList = nuevo ArrayList < el entero, nmero entero>();

Mezclar colecciones no genricas y genricas ( objetivos de examen 6.3 y 6.4 )

605
En el momento el compilador es hecho con ello, el JVM ve lo que siempre vi antes de Java 5 y genricos:
Liste MyList = nuevo ArrayList();

El compilador an inserta los lanzamientos para usted -- los lanzamientos que usted tuvo que hacer para conseguir cosas fuera de una coleccin de pre-Java 5. Considere genricos como estrictamente un Compile-cronometre proteccin. El compilador usa la informacin de tipo genrica ( en los corchetes de ngulo) para asegurarse de que su cdigo no ponga las cosas malas en una coleccin, y que no asigna lo que usted consigue de una coleccin al tipo de referencia malo. Pero NONE de esta proteccin existe al |runtime|. Esto es un poco diferente de los conjuntos, que dan le BOTH compile-cronometre la proteccin de proteccin y |runtime|. Por qu hicieron los genricos por este camino? Por qu hay ninguna informacin de tipo al | runtime|? Para soportar cdigo de herencia. A |runtime| , colecciones son las colecciones tal como los das antiguos. Lo que le la ganancia de usar genricos es compilar-cronometre la proteccin que las garantas que no pondr la cosa mala en una coleccin representada, y elimina tambin la necesidad para un lanzamiento cuando consigue algo exterior, desde el compilador ya sepa que slo un entero, nmero entero est viniendo fuera de una lista de entero, nmero entero. El hecho es, usted no la proteccin de |runtime| de NEED...hasta que usted empieza mezclar a fondo el cdigo de genrico y no-genrico, como nosotros hicimos en el ejemplo previo. Entonces puede tener desastres al |runtime|. El nico consejo de que tengamos sea pagar el atencin muy cercana a esas advertencias de compilador:
javac TestBadLegacy.java Nota: TestBadLegacy.java usan las operaciones

desenfrenadas o inseguras. Nota: Recompile con - Xlint:unchecked para los detalles.

Esta advertencia de compilador no es muy descriptiva, pero la segunda nota sugiere que recompile con Xlint:unchecked. Si hace, conseguir algo as como esto:
javac -- Xlint:unchecked TestBadLegacy.java TestBadLegacy.java:17: advertencia: llamada desenfrenado unchecked para aada (e) como un miembro del tipo crudo java.util.List list.add (nueva cuerda( " 42")); ^ 1 advertencia

Cuando compila con el - Xlint:unchecked cuelga, el compilador muestra usted exactamente que el mtodo(s) podra estar haciendo algo peligroso. En este ejemplo,

606

Captulo 7:

Genricos y colecciones

desde el argumento de lista no declare con un tipo, el compilador lo trata como la herencia codifica y asume ningn riesgo para lo que el mtodo traduce al la lista "cruda". En el examen, debe ser capaz de reconocer cuando est compilando el cdigo que producir advertencias pero todava compile. Y cada cdigo que compila (an con advertencias) corre ! ningunas violaciones de tipo ser atrapar en |runtime| por el JVM, hasta esas violaciones de tipo meta en su cdigo en alguna otra va. En otros trminos, el acto de aadir una cuerda a un <entero, nmero entero> la lista no fracasar al | runtime| hasta que trata de tratar que Stringyou-think-is-an-Integer como un entero, nmero entero.

Por ejemplo, le imagine querer que su cdigo tire algo fuera de su represente de modo supuesto ArrayList seguro ese cdigo ms viejo pone una cuerda en. Ello compila (con advertencias). Ello corre...o al menos el cdigo que aade en realidad la cuerda a las corridas de lista. Pero cuando toma la cuerdaese-no era-supuesto-para-es-all fuera de la lista, y trate de asignarlo a un entero, nmero entero referencie o invoque un mtodo de entero, nmero entero, es muerto. Tenga presente, entonces, que el problema de poner la cosa mala en un representado (genrico) la coleccin no saca a luz al tiempo le hacer en realidad el add () a la coleccin. Ello sacan a luz slo posterior, cuando trata de usar algo en la lista y no casa lo que estuvo embarazada. En el antiguo (pre-Java 5) das, siempre asumi que podra conseguir la cosa mala fuera de una coleccin ( desde ellos estaba todo caja fuerte de no-tipo ), as que tom los pasos de defensiva apropiados en su cdigo. El problema con mezclar genrico con el cdigo no genrico es que no estar embarazada esos problemas si usted ha sido arrullado en un sentido falso de la seguridad por tener el cdigo seguro escrito de tipo . Slo recuerde que el momento que vuelve que representa la coleccin segura arriba para ms viejo, caja fuerte de no-tipo codifica, su proteccin desaparece. De nuevo, pague el atencin muy cercana a compilador advierten, y est dispuesto a vea los asuntos as suben en el examen.

Al usar la herencia (caja fuerte de no-tipo) colecciones - est a la mira de los problemas unboxingues ! si declare una coleccin no genrica, el mtodo de get ()
ALWAYS retorna una referencia del tipo java.lang.Object. Recuerde que unboxing no pueda convertir un objeto viejo simple a un primitivo, an si que objete la referencia refiera a un entero, nmero entero ( o algn otro primitivo enrollado ) en la pila. Los conversos

unboxingues slo de una referencia envoltura de clase ( como un entero, nmero entero o un largo ) a un primitivo.

Polimorfismo y genricos ( objetivos de examen 6.3 y 6.4 )

607

|gotcha| Unboxing, continuado:


Liste la prueba = nuevo ArrayList (); test.add ( 43); x de |int| = (entero, nmero entero) test.get ( 0);

// debe tirar el anzuelo !!

Liste entero, nmero entero test2 = nuevo ArrayList < el entero, nmero entero>(); test2.add ( 343); int x2 = test2.get(0); // no tire el anzuelo necesario

Est a la mira de los lanzamientos desaparecidos asociado con pre-Java 5, colecciones no genrico.

Polimorfismo y genricos
Las colecciones genricas dan le mismos beneficios de la seguridad de tipo que siempre ha tenido con los conjuntos, pero existe ciertas diferencias cruciales que pueden morderle si usted no se prepare. La mayor parte de stos tienen que ver con polimorfismo. Ha visto ya que polimorfismo se aplica al tipo de "base" de la

coleccin:
Liste entero, nmero entero MyList = nuevo ArrayList < el entero, nmero entero>();

En otros trminos, nosotros fuimos capaz de asignar un ArrayList a una referencia de lista, porque la lista es un |supertype| de ArrayList. Nada la cosa especial all - esta asignacin polimorfa trabaja la va que ello siempre trabaja en Java, a pesar de la mecanografa genrica. Pero qu se sabe de esto?
padre de clase{ } el nio de clase extiende padre{ } Liste padre MyList = nuevo ArrayList < el nio>();

Considera lo para un minuto. Mantenga pensar...

608

Captulo 7:

Genricos y colecciones

No, ello no trabaja. Existe una regla muy simple aqu el tipo de la declaracin variable debe casar el tipo que usted pasa al tipo real de objeto. Si usted declare |foo| de lista entonces cualquier le cesionario al |foo| referencie MUST es del tipo <Foo> genrico. No un subtipo de . No un |supertype| de . Slo Foo. stos no tienen razn:
Liste objeto MyList = nuevo ArrayList < JButton>(); // NO ! liste nmero cuenta = nuevo ArrayList < el entero, nmero entero>(); // NINGN! // recuerde que entero, nmero entero es un subtipo del nmero

Pero stos son finos:


List<JButton> myList = new ArrayList<JButton>(); //

s Liste objeto MyList = nuevo ArrayList < oponga se>(); // s Liste entero, nmero entero MyList = nuevo ArrayList < el entero, nmero entero>(); // s

Hasta ahora todo va bien. Slo mantenga el tipo genrico de la referencia y el tipo genrico del objeto al que refiere idntico. En otros trminos, el polimorfismo se aplica aqu para slo la "base" teclea. Y por " base en, " significamos che el tipo de la coleccin se clasifica - la clase que puede ser acomodada segn especificaciones con un tipo. En este cdigo,
List<JButton> myList = new ArrayList<JButton>();

Liste y ArrayList es el tipo bajo y JButton es el tipo genrico. As un ArrayList se puede asignar a una lista, pero una coleccin de <JButton> no se puede asignar a una referencia de <objeto> , aunque JButton es un subtipo del objeto. La parte que sienten haga mal a para la mayor parte de los desarrolladores es se esto no es cmo trabaja con los conjuntos, donde es permitido para hacer esto,
importe java.util.*; padre de clase{ } el nio de clase extiende padre{ } el pblico clasifica TestPoly{ la parte principal vaca esttica pblica (| args| de cuerda){ El padre MyArray = nuevo Child 3; // s } }

que significa se permite tambin para hacer esto

Los mtodos genricos ( objetivos de examen 6.3 y 6.4 )

609

Objete MyArray = nuevo JButton 3;

// s

pero no esto:
Liste objeto lista = nuevo ArrayList < JButton>(); // NINGN!

Por qu es los reglamentos para teclear de conjuntos diferente de los reglamentos para la mecanografa genrica? Nosotros llega a ese en un minuto. Por ahora, slo quema lo en su cerebro que el polimorfismo hace no el trabajo la misma va para genricos como hace con conjuntos.

mtodos genricos
Si no era ya familiarizado con genricos, podra estar sintiendo muy incmodo con las implicaciones de la cosa de no-polymorphicassignment-for-generic-types previa. Y porque usted no debe ser incmodo? Uno de los beneficios ms grandes del polimorfismo son que puede declarar, digamos, un argumento de mtodo de un tipo particular y en |runtime| sea capaz de tener que argumento se refiere a cada subtipo incluyendo esos nunca hubo conocido casi al tiempo escribi el mtodo con el argumento de |supertype|. Por ejemplo, imagine un clsico ( simplifique ) el ejemplo de polimorfismo de una clase de veterinario (AnimalDoctor) con un examen de mtodo ().
Y en este momento, usted ha tres subtipos animales - siga, fustigue, y busque nidos - cada poniendo en prctica el mtodo de () abstracto de examen del animal: animal de clase abstracto{ el pblico resume el examen vaco(); } el perro de clase extiende animal{ examen vaco pblico () { // ponga en prctica el cdigo especfico inferior System.out.println ( " siga examen"); } } el gato de clase extiende animal{ examen vaco pblico () { // ponga en prctica el cdigo de gato especfico System.out.println ( " fustigue examen"); } } el pjaro de clase extiende animal{ examen vaco pblico () { // ponga en prctica el cdigo de pjaro especfico

System.out.println ( " examen de pjaro"); } }

610

Captulo 7:

Genricos y colecciones

Olvidando colecciones/conjuntos por un momento, slo imagine lo que la clase de AnimalDoctor necesita parecerse a fin de tener el cdigo que toma cada tipo del animal e invoque el mtodo de () animal de examen.
Tratar de sobrecargar la clase de AnimalDoctor con los mtodos de () de examen para cada tipo posible del animal es ridculo, y obviamente no extensible. Usted hubo tenido que cambiar la clase de AnimalDoctor cada vez alguien aadi un nuevo subtipo del animal. As en la clase de AnimalDoctor, usted tuvo probablemente tenga un mtodo polimorfo: vaco pblico CheckAnimal ( el animal un ){ a.checkup(); // no importe que el subtipo animal cada // el mtodo de () de examen de |overridden| de animal corre}

Y por supuesto nosotros queremos el AnimalDoctor para tener tambin el cdigo que puede tomar conjuntos de perros, gatos, o pjaros, para cuando el vet viene al perro, fustigue, o busque nidos perrera. De nuevo, no queremos los mtodos sobrecargados con conjuntos para cada subtipo animal potencial, as que usamos polimorfismo en la clase de AnimalDoctor:
vaco pblico CheckAnimals (animales animales){ para ( el A animal: los animales ){ a.checkup(); } }

Aqu est el ejemplo entero, complete con una prueba del polimorfismo de conjunto que tome cualquier tipo de conjunto animal ( siga, fustigue, busque nidos ).

importe java.util.*; animal de clase abstracto{ el pblico resume el examen vaco(); } el perro de clase extiende animal{ examen vaco pblico () { // ponga en prctica el cdigo especfico inferior System.out.println ( " siga examen"); } } el gato de clase extiende animal{ examen vaco pblico () { // ponga en prctica el cdigo de gato especfico System.out.println ( " fustigue examen"); } }

Los mtodos genricos ( objetivos de examen 6.3 y 6.4 )

611

el pjaro de clase extiende animal{ examen vaco pblico () { // ponga en prctica el cdigo de pjaro especfico System.out.println ( " examen de pjaro"); } } el pblico clasifica AnimalDoctor{ // el mtodo toma un conjunto de cualquier subtipo animal vaco pblico CheckAnimals (animales animales){ para ( el A animal: los animales ){ a.checkup(); } } la parte principal vaca esttica pblica (|args| de cuerda){ // prueba lo Siga los perros ={nuevo inferior (), nuevo Dog ()}; Fustigue los gatos ={nuevo gato (), nuevo Cat (), nuevo Cat ()}; Busque nidos los pjaros ={nuevo Bird ()}; AnimalDoctor doc = new AnimalDoctor(); doc.checkAnimals ( perros); // pase el perro doc.checkAnimals ( gatos); // pase el gato doc.checkAnimals ( pjaros); // pase el

pjaro } }

Estos trabajos se aclaran, por supuesto ( sabemos, nosotros sabe, estas son las noticias viejas ). Pero aqu est porque nosotros trajimos esta subida como el refresco - este acercamiento no trabaja la misma va con colecciones seguras de tipo ! En otros trminos, un mtodo que toma, digamos, un ArrayList no ser capaz de aceptar una coleccin de ningn subtipo animal ! esto significa que ArrayList no puede ser en espera de una vacante para ascender en un mtodo con un argumento de ArrayList, aunque sabemos ya que estos trabajos slo se aclaran con los conjuntos viejos simples. Obviamente esta diferencia entre conjuntos y ArrayList son consistentes con la asignacin de polimorfismo gobierne que nosotros ya parecido a - el hecho que no puede asignar un objeto de ArrayList de tipo <JButton> a una lista <objeto>. Pero esto es donde realmente empieza a sentir el dolor de la distincin entre los conjuntos representados y representar colecciones. Sabemos che que ello no trabajar correctamente, pero dejenos probar cambiando el cdigo de AnimalDoctor para usar genricos en lugar de los conjuntos:
el pblico clasifica AnimalDoctorGeneric {

612

Captulo 7:

Genricos y colecciones

// cambie el argumento de Animal a ArrayList <animal> vaco pblico CheckAnimals (ArrayListanimales){ para ( el A animal: los animales ){ a.checkup(); }

} la parte principal vaca esttica pblica (| args| de cuerda){ // haga ArrayLists en lugar de conjuntos para perro, fustigue, el pjaro Liste perro siguen = nuevo ArrayList < siga>(); dogs.add ( nuevo perro()); dogs.add ( nuevo perro()); Liste gato fustigan = nuevo ArrayList < el gato>(); cats.add ( nuevo gato()); cats.add ( nuevo gato()); Liste pjaro buscan nidos = nuevo ArrayList < el pjaro>(); birds.add ( nuevo pjaro()); // este cdigo es igual que la versin de conjunto AnimalDoctorGeneric doc = new AnimalDoctorGeneric(); // esto trabaj cuando nosotros usamos conjuntos en lugar de ArrayLists doc.checkAnimals ( perros); // envie una lista <perro> doc.checkAnimals ( gatos); // envie una lista <gato> doc.checkAnimals ( pjaros); // envie una lista <pjaro> } }

As qu sucede?
javac AnimalDoctorGeneric.java AnimalDoctorGeneric.java:51: checkAnimals(java.util. ArrayList ) en AnimalDoctorGeneric no pueda ser aplicado para (java.util.List perro) doc.checkAnimals ( perros); ^ AnimalDoctorGeneric.java:52: checkAnimals(java.util. ArrayList ) en AnimalDoctorGeneric no pueda ser aplicado para (java.util.List gato) doc.checkAnimals ( gatos); ^ AnimalDoctorGeneric.java:53: checkAnimals(java.util. ArrayList ) en AnimalDoctorGeneric no pueda ser aplicado para (java.util.List pjaro) doc.checkAnimals ( pjaros); ^ 3 errores

Los mtodos genricos ( objetivos de examen 6.3 y 6.4 )

613

El compilador para nos con los errores, no advertencias. Usted simplemente CANNOT asigne el individual ArrayLists de subtipos animales (, , o ) a un ArrayList del | supertype| , que es el tipo declarado del argumento. Esto es uno de los |gotchas| ms grandes para los programadores de Java que son as familiarizados con usar el polimorfismo con los conjuntos, donde el mismo guin ( el animal pueda referirse a inferior, fustigue , o busque nidos ) trabajan como esperara. As hemos dos asuntos reales: 1. Por qu no haga este trabajo? 2. Cmo se adelanta a lo? Usted nos tuvo odie y todo el sol disea si nosotros le dijo que no exista una va alrededor de ello -- que tuvo que aceptar ello y escriba cdigo horriblemente inflexible que prob para prever y el cdigo sobrecarg mtodos para cada especfico tipo. Afortunadamente, existe una va alrededor de ello. Pero primero, porque no puede hacer lo si trabaja para conjuntos? Por qu no puede pasar un ArrayList en un mtodo con un argumento de ArrayList? Nosotros llegaremos, pero el primero nos deja poner la parte posterior intermedia durante un minuto y considere que esto guin perfectamente jurdico:
Animales animal = nuevo Animal 3; los animales 0 = nuevo gato(); los animales 1 = nuevo perro();

Parte del beneficio de declarar un conjunto que usa un |supertype| ms abstracto es que el propio conjunto puede tener objetos de

subtipos mltiples del |supertype| , y entonces usted puede manipular el conjunto arrogante toda cosa en ello pueda responder al enlace animal ( en otros trminos, toda cosa en el conjunto pueda responder al mtodo llama defina en la clase animal ). As aqu, nosotros estamos usando el polimorfismo no para el objeto que la referencia de conjunto apunta a, pero ms bien lo que el conjunto puede en realidad HOLD - en este caso, ningn subtipo del animal. Puede hacer la misma cosa con los genricos:
Liste animal animales = nuevo ArrayList < el animal>(); animals.add ( nuevo gato()); // OK animals.add ( nuevo perro()); // APROBACIN

As esta parte trabaja con ambos conjuntos y las colecciones genricas -podemos aadir un caso de un subtipo en un conjunto o coleccin declarados con un |supertype|. Usted puede aadir perros y gatos a un conjunto animal (animal) o un animal de coleccin (ArrayList< animal > ).

614

Captulo 7:

Genricos y colecciones

Y con los conjuntos, esto aplique se a lo que suceda dentro de un mtodo:


vaco pblico AddAnimal (animales animales){ los animales 0 = nuevo perro(); // ningn de problema, cada animal trabaja // en el animal }

As si esto es verdadero, y si puede poner perros en un ArrayList animal, entonces porque no puede usar que mismo tipo del

guin de mtodo? Por qu no puede hacer esto?


vaco pblico AddAnimal (ArrayListanimales){ animals.add ( nuevo perro()); // a veces permitido... }

En realidad, usted CAN hacer este bajo ciertas condiciones. El cdigo sobre WILL compila multa justo IF lo que pasa en el mtodo es tambin un ArrayList . Esta es la parte donde difiere de los conjuntos, porque en la versin de conjunto, usted COULD pasar un perro en el mtodo que toma un animal. La cosa de ONLY que puede pasar a un argumento de mtodo de ArrayList <animal> es un ArrayList <animal> ! (Asumir que no est tratando de pasar un subtipo de ArrayList, desde recordar - el tipo de "base" puede ser polimorfo.) La pregunta es todava all afuera - por qu es malo esto? Y porque es lo el mal para ArrayList pero no conjuntos? Por qu no puede pasar un ArrayList a un argumento de ArrayList? En realidad, el problema IS justo cuando peligroso si est usando los conjuntos o una coleccin genrica. Es slo que el compilador y JVM se comportan diferentemente para las v de conjuntos. colecciones genricas. La razn es peligroso pasar una coleccin ( coloque en orden de batalla o ArrayList ) de un subtipo en un mtodo que tome una coleccin de un |supertype|, es porque podra aadir algo. Y esto significa que podra aadir la cosa de WRONG ! esto es probablemente realmente obvio, pero por si acaso ( y para reforzar ), dejenos repasar a la ligera ciertos guiones. El primero uno es simple:
|foo| vaco pblico () { Siga los perros ={nuevo inferior (), nuevo Dog ()}; AddAnimal ( perros); // ningn de problema, envie el perro al mtodo } vaco pblico AddAnimal (animales animales){ los animales 0 = nuevo perro(); // apruebe, cualquier subtipo animal trabaja }

Los mtodos genricos ( objetivos de examen 6.3 y 6.4 )

615

Esto no es ningn problema. Pasamos un en el mtodo, y aada un perro al conjunto ( que sea sido permitido desde entonces el parmetro de mtodo era el animal de tipo , que puede tener cualquier subtipo animal ). Pero qu ocurrira si nosotros cambiamos el cdigo llamado para
perro |foo| vaco pblico () { Fustigue los gatos ={nuevo Cat (), nuevo Cat ()}; AddAnimal ( gatos); // ningn de problema, envie el gato al mtodo }

y las permanencias originales de mtodo el mismo:


vaco pblico AddAnimal (animales animales){ los animales 0 = nuevo perro(); // Eeek ! que nosotros slo ponemos un perro / / en un conjunto de gato ! }

El compilador piensa es perfectamente fino aadir un perro a un conjunto animal, desde un


perro se pueda asignar a una referencia animal. El problema es, si usted pasara en un conjunto de un subtipo animal ( fustigue, siga, o busque nidos ), el compilador no sabe. El compilador no comprende que el exterior en el lugar de pila es un conjunto del gato de tipo , no el animal , y usted est a punto de tratar de

aadir un perro a ello. Al compilador, ha pasado en un conjunto de animal de tipo, as que ha nada para reconocer el problema. THIS es el guin que nosotros estamos tratando de impedir, a pesar de si es un conjunto o un ArrayList. La diferencia es, el compilador le deja salir triunfante para los conjuntos, pero no para las colecciones genricas.

La razn el compilador no le dejar pasar un ArrayList <perro> en un mtodo que toma un ArrayList animal, es porque dentro del mtodo, que parmetro es de ArrayList de tipo, y esto significa que usted pudo poner cada tipo del animal en ello. All podra estar nada para el compilador para pararle de poner un perro en una lista que es sido declarado originalmente como <gato> , pero referencie ahora de <animal> el parmetro. Todava hemos dos preguntas...cmo se adelanta a lo y porque el infierno hace el compilador le permita tomar que el riesgo para conjuntos pero no para ArrayList ( o ninguna otra coleccin genrica )? La razn usted pueda hacer con impunidad compilando este para conjuntos es porque existe una excepcin (ArrayStoreException) de |runtime| que impedir usted de poner el tipo malo del objeto en un conjunto. Si envie un conjunto inferior en el mtodo que toma un conjunto animal, y usted aade los perros slos
( incluyendo los subtipos inferiores, por supuesto ) en el conjunto ahora referenciado por Animal, ningn de problema. Pero si trate de

aadir un gato al objeto que est en realidad un conjunto inferior, conseguir la excepcin.

616

Captulo 7:

Genricos y colecciones

Pero all IS ninguna excepcin equivalente para los genricos, debido a la borradura de tipo ! En otros trminos, al |runtime| el JVM KNOWS el tipo de conjuntos, pero no sepa el tipo de una coleccin. Toda la informacin genrica de tipo es apartada durante compilacin, as en el momento ello llega al JVM, all est simplemente nada para reconocer el desastre de poner un gato en un ArrayList y viceversa ( y ello se convierte en exactamente como los problemas de que tenga cuando usa herencia,

caja fuerte de no-tipo codifica ). As este en realidad cdigo jurdico IS:


vaco pblico AddAnimal (listaanimales){ animals.add ( nuevo perro()); // esto es siempre jurdico, // desde el perro puede // asigne se a un animal // referencia } la parte principal vaca esttica pblica (| args| de cuerda){ Liste animal animales = nuevo ArrayList < el animal>(); animals.add ( nuevo perro()); animals.add ( nuevo perro()); AnimalDoctorGeneric doc = new AnimalDoctorGeneric(); doc.addAnimal ( los animales); // OK, desde los animales hacen juego // el |arg| de mtodo }

Mientras la nica cosa que pasa al addAnimals el animal > ) es un ArrayList, el compilador est satisfecho con -- conociendo que cualquier subtipo animal que usted aade ser vlido ( puede siempre aadir un perro para una coleccin animal, |yada| , |yada| , | yada| ). Pero si usted trata de invocar addAnimal () con un argumento de cualquier otro ArrayList teclee, el compilador le parar, desde entonces al |runtime| el JVM tendra nada para parar le de aadir un perro para lo que era creado como una coleccin de gato. Por ejemplo, este cdigo que cambia el tipo genrico a, pero sin cambiar el mtodo de addAnimal (), no compile:
(lista< vaco pblico AddAnimal (listaanimales) { animals.add ( nuevo perro()); // OK inmvil como siempre } la parte principal vaca esttica pblica (|args| de cuerda){ Liste perro animales = nuevo ArrayList < siga>(); animals.add ( nuevo perro()); animals.add ( nuevo perro()); AnimalDoctorGeneric doc = new AnimalDoctorGeneric(); doc.addAnimal ( los animales); // THIS es donde se rompe ! }

Los mtodos genricos ( objetivos de examen 6.3 y 6.4 )

617

El compilador dice algo as como:


javac AnimalDoctorGeneric.java AnimalDoctorGeneric.java:49: addAnimal (java.util.List< el animal > ) en AnimalDoctorGeneric no pueda ser aplicado para ( java.util. Liste perro ) doc.addAnimal ( los animales); ^ 1 error

El anuncio que este mensaje es virtualmente lo del mismo modo que tiene tratando de invocar cada mtodo con el argumento malo. Es el dicho que simplemente no puede invocar addAnimal (lista< el animal > ) usando algo cuya referencia se era sido declara como la lista <perro>. ( es el tipo de referencia, no el tipo real de objeto que materias - pero recuerde - el tipo genrico de un objeto es ALWAYS igual que el tipo genrico declare en la referencia. Liste puede referirse ONLY a colecciones que son subtipos de la lista, pero que eran ejemplificados concretamente como el genrico representa .) Una vez ms, recuerde que una vez dentro del mtodo de addAnimals (), todas
esas materias son el tipo del parmetro -- en este caso, liste . (Nosotros lo cambiamos de ArrayList a List para mantener nuestro limpiador de polimorfismo de tipo de "base".) De vuelta a la pregunta clave - cmo nos adelantamos a esto? Si el de problema es relacionado slo al peligro de aadir la cosa mala a la coleccin, qu se sabe del mtodo de () de examen que us la coleccin pas en como slo para lectura? En otros trminos, qu se sabe de mtodos que invoca los mtodos animales en cada cosa en la coleccin, que trabajar a pesar de que el tipo del subtipo de ArrayList es en espera de una vacante para ascender en? Y que es una pista! es el mtodo de add () que es el problema, as lo que necesitamos es una va para decir el compilador, " hey, yo

estoy usando la coleccin pase en slo para invocar mtodos en los elementos - y yo hago una promesa no a ADD algo en la coleccin." y existe un mecanismo para decir el compilador que puede tomar cualquier subtipo genrico del argumento declarado teclea porque no estar poniendo algo en la coleccin. Y que mecanismo es el |wildcard| <?>.

La firma de mtodo cambiara de

vaco pblico AddAnimal (listaanimales)

para
vaco pblico AddAnimal (lista<? extienda animal >animales)

618

Captulo 7:

Genricos y colecciones

Diciendo <? extienda animal >, estamos diciendo, " se puedo asignar una coleccin que soy un subtipo de lista y represent para <animal> o algo que extiende animal. Y |oh| s, yo SWEAR que no poder ADD algo en la coleccin." ( existe un poco ms a la historia, pero nosotros llegaremos.) As por supuesto el mtodo de addAnimal ()
sobre no compilar en realidad uniforme con la anotacin de |wildcard| , porque ese mtodo aade algo. vaco pblico AddAnimal (lista<? extienda animal >animales) { animals.add ( nuevo perro()); // NO ! no pueda sumar si nosotros // use <? extienda animal >}

Conseguir un error muy extrao que puede mirar algo as como esto:
javac AnimalDoctorGeneric.java AnimalDoctorGeneric.java:38: no pueda encontrar smbolo smbolo: el mtodo aade (perro) ubicacin: interacte java.util.List < la captura

de? extienda animal > animals.add ( nuevo perro()); ^ 1 error

que dice bsicamente, " no puede aadir un perro aqu."si cambiemos el mtodo de modo que ello no aade algo, trabaja. Pero espera - existe ms. (Y de paso, toda cosa nosotros ha cubierto en estas seccin de genricos sea probable que es ensayado para en el examen, a excepcin de " represente la borradura, " para que no es requerido para saber todos los detalles.) En primer lugar, el <? extienda animal > signifique que puede tomar cada subtipo del animal; sin embargo, que subtipo puede ser EITHER un subclase de una clase ( resuma o concrete ) OR un tipo que cumple el enlace despus que la palabra se extienda. En otros trminos, la palabra clave se extiende en el contexto de un |wildcard| represente ejecuciones de subclases de BOTH y enlace. No existe ningn <? los enseres publicar por entregas > la sintaxis. Si quiera declarar un mtodo que toma algo que es de un tipo que cumpla publicar por entregas, tiene el uso inmvil extienda se as:
el |foo| vaco (lista<? extienda publicar p o r e n t r e g a s > l i s t a ) / / i m p

a r , p e r o c o r r i j a / / p a r a u s a r " e x t i e n d e "

Esto parece extrao despus que usted podra nunca decir esto en una declaracin de clase porque publicar por entregas es un enlace, no una clase. Pero que es la sintaxis, as queme lo en!

Los mtodos genricos ( objetivos de examen 6.3 y 6.4 )

619

Otro tiempo ms

existe nica palabra

clave de |wildcard| de ONE que representa ambas ejecuciones de enlace y subclases. Y esa palabra clave es extenderse. Pero cuando ve lo, piense " es-un ", como en algo que pasa la prueba de |instanceof|. Sin embargo, existe
otro guin donde puede usar un |wildcard| AND todava aumente la coleccin, pero en una va segura -la palabra clave refuerza con capricho.

Imagine, por ejemplo, que usted declar el mtodo por este camino:

vaco pblico AddAnimal (lista<? refuerce con capricho el perro >animales){ animals.add ( nuevo perro()); // aadir es a veces OK con la alza } la parte principal vaca esttica pblica (| args| de cuerda){ Liste animal animales = nuevo ArrayList < el animal>(); animals.add ( nuevo perro()); animals.add ( nuevo perro()); AnimalDoctorGeneric doc = new AnimalDoctorGeneric(); doc.addAnimal ( los animales); // pasar una lista animal }

Ahora lo que ha dicho en esta lnea


vaco pblico AddAnimal (lista<? refuerce con capricho el perro >animales)

sea esencialmente, " compilador de hey, por favor acepte que cada lista con un tipo genrico que es del perro de tipo, o un | supertype| de perro nada inferior en el rbol de herencia pueda entrar, pero algo ms alto que perro es OK." Reconoce probablemente ya porque estos trabajos. Si pase en una lista de animal de tipo, entonces es perfectamente fino aadir un perro a ello. Si pase en una lista de perro de tipo, es perfectamente fino aadir un perro a ello. Y si pase en una lista de objeto de tipo, es STILL fino aadir un perro a ello. Cuando usa el <? alza...> sintaxis, est diciendo el compilador que puede aceptar el tipo en el lado de la mano derecha de excelente o cualquier de sus |supertypes| , desde entonces y esta es la parte clave que lo hacen trabajar una coleccin declar como cada | supertype| del perro ser capaz de aceptar un perro como un elemento. Lista puede tomar una lista inferior pueda tomar un perro y lista puede tomar un perro as pasajero cualquier

de esos en trabajar. As la palabra clave


excelente en la anotacin de |wildcard| le deja tener un limitado, pero la va todava posible para aumentar una coleccin. As, el |wildcard| le da las asignaciones polimorfas, pero con ciertas restricciones que no tiene para los conjuntos. Pregunta rpida: es estos dos idntico? el |foo| vaco pblico (lista<?> liste ){ } el |foo| vaco pblico (lista< objeta >lista){ }

620

Captulo 7:

Genricos y colecciones

Si existe una diferencia ( y no estamos diciendo all es ), lo que es lo? All IS una diferencia enorme. Liste <?>, qu es el |wildcard| <?> sin las palabras claves extienda se o refuerce con capricho, significa simplemente " cada tipo." de modo que signifique cualquier tipo de lista se puede asignar al argumento. Esa pudo ser una lista de, , JButton, , cualquier. Y usar el | wildcard| slo, sin la alza de palabra clave ( seguido por un tipo ), signifique que no puede ADD algo para la lista mencionado para como liste <?>. Liste <objeto> es completamente diferente de liste <?>. Lista significa que el mtodo puede tomar ONLY una lista . No una lista , o una lista . Ello hace, sin embargo, signifique que puede aumentar la lista, desde el compilador ha hecho ya cierto que est pasando slo una lista vlida <objeto> en el mtodo. Basado en las explicaciones previas, deduzca si la cosa siguiente trabajar:
importe java.util.*; el pblico clasifica TestWildcards{ la parte principal vaca esttica pblica (|args|

de cuerda){ Liste entero, nmero entero MyList = nuevo ArrayList < el entero, nmero entero>(); Excluya la barra = nueva barra(); bar.doInsert(myList); } } barra de clase{ doInsert vaco (lista<?> liste ){ list.add ( nuevo perro()); } }

De lo contrario, donde es el problema? El problema est en el mtodo de () list.add dentro de doInsert (). El <?> el | wildcard| permite una lista de cada tipo para ser en espera de una vacante para ascender al mtodo, pero el mtodo de add () no es
vlido, para las razones que nosotros exploramos ms temprano (que pudo poner el tipo malo de la cosa en la coleccin). As esta vez, la clase de TestWildcards es fina, pero la clase de barra no compilar porque ello hace un add () en un mtodo que usa un |wildcard| ( sin reforzar con capricho ). Qu ocurrira si nosotros cambiamos el mtodo de doInsert () para esto: el pblico clasifica TestWildcards{ la parte principal vaca esttica pblica (|args| de cuerda){ Liste entero, nmero entero MyList = nuevo ArrayList < el entero, nmero entero>(); Excluya la barra = nueva barra(); bar.doInsert(myList); } }

Los mtodos genricos ( objetivos de examen 6.3 y 6.4 )

621

barra de clase{ doInsert vaco (lista< objeta >lista){ list.add ( nuevo perro()); } }

Ahora lo puede trabajar? De lo contrario,

por qu no? Esta vez, clasifique la barra, con el mtodo de doInsert (), compila la multa justa. El
problema es que el cdigo de TestWildcards est tratando de pasar una lista en un mtodo que puede tomar ONLY una lista . Y nada ms se pueda substituir para <objeto>. De paso, liste <? extiende el objeto >y listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay listay lista<?> sea absolutamente idntico! ellos

ambos diga, " puedo referirse a cualquier tipo de objeto." pero como puede ver, ninguna de ellas es igual que lista <objeto>. Una va para recordar esto es que si vea la anotacin de | wildcard| ( un signo de interrogacin ?), este medios " muchas posibilidades". Si no vea el signo de interrogacin, entonces significa en los corchetes, y absolutamente nada ms. Liste perro medios lista y no liste sabueso, liste perro de lanas, o ningn otro subtipo del perro pero liste <? extienda el perro > pueda significar la lista, liste perro de lanas, y as en. Por supuesto liste <?> pueda ser... algo en modo alguno. Tenga presente que los | wildcards| pueden ser usados slo para las declaraciones de referencia ( incluyendo los argumentos, variables, tipos de retorno, y as en ). No pueden ser usados como el parmetro de tipo cuando usted crea una nueva coleccin representada. Considere se mientras que puede ser abstracta y polimorfa una referencia, el objeto real creado deba ser de un tipo especfico. Usted tenga que cerrarse abajo el tipo cuando usted hace el objeto usando nuevo. Como un poco revisin antes que nos movemos en con los genricos, mire a las declaraciones siguientes y deduzca que compile:
1) Liste siga>(); 2) Liste ArrayList 3) Liste <?> liste = nuevo ArrayList < <? extienda animal > AList = nuevo < siga>(); <?> foo = new ArrayList<? extienda

animal>(); 4) Liste <? extienda el perro > CList = nuevo ArrayList < el entero, nmero entero>(); 5) Liste <? refuerce con capricho el perro > BList = nuevo ArrayList < el animal>(); 6) Liste <? refuerce con capricho animal > DList = nuevo ArrayList < siga>();

Las respuestas correctas (las declaraciones que compilan) es 1, 2 , y 5. Los tres que no compilar es declaracin de n: Liste <?> foo = new ArrayList<? extienda animal>(); Problema: no puede usar anotacin de |wildcard| en la creacin de objeto. As el nuevo ArrayList <?
extienda animal > () no compilar.

622

Captulo 7:

Genricos y colecciones

declaracin de n: Liste <? extienda el perro >


CList = nuevo ArrayList < el entero, nmero entero>();

Problema: Usted no puede asignar una lista de entero, nmero entero a una referencia que toma slo un perro ( incluyendo todos los subtipos del perro, por supuesto ). declaracin de n: Liste <? refuerce con capricho
animal > DList = nuevo ArrayList < siga>();

Problema: Usted no puede asignar un perro para <? refuerce con capricho animal >. El inferior es demasiado "bajo" en la jerarqua de clase. Slo <animal> o <objeto> puede haber sido jurdico.

declaraciones genricas
Hasta ahora, nosotros tenemos de que se habla cmo crear colecciones seguro el tipo, y

cmo declarar las variables de referencia incluyendo argumentos y tipos de retorno usando la sintaxis genrica. Pero aqu est unas cuantas preguntas: Cmo an sabemos que somos allowed/ conjeture para especificar un tipo para estas clases de coleccin? Y haga el trabajo de mecanografa genrico con cualesquiera otras clases en el API? Y finalmente, podemos declarar nuestras propias clases como el genrico teclea? En otros trminos, podemos hacer una clase que requiere que alguien pasa un tipo en cuando declaran lo y lo ejemplifique concretamente? En primer lugar, el un le saber obviamente la respuesta a -- el API le dice cuando se espera un tipo de | parameterized|. Por ejemplo, esto es la declaracin de API para el enlace java.util.List:
el enlace pblico lista <e>

<e> es un |placeholder| para el tipo que usted pasa en casa. El enlace de lista se est comportando como una "plantilla" genrica ( en cierta medida como la c++ plantillas ), y cuando usted escribe su cdigo, usted cambia lo de una lista genrica a una lista perro o liste entero, nmero entero, y as en. La e, de paso, es slo una convencin. Cualquier identificador de Java vlido trabajara aqu, pero la e representan " elemento, " y ello es usado cuando la plantilla es una coleccin. La otra convencin principal es el T (representar el "tipo"), use para, bien, las cosas que no son colecciones. Ahora que ha visto la declaracin de enlace para lista, lo que hace piensa che las buenas apariencias de mtodo de add ()
quieren? booleana aada (o de e)

En otros trminos, cualquiera e es cuando usted declara la lista, que es lo que usted pueda sume para it. As imagine este cdigo:
Liste animal lista = nuevo ArrayList < el animal>();

Las declaraciones genricas ( objetivos de examen 6.3 y 6.4 )

623

La e en la lista API repentinamente tenga su forma de onda derrumbar, y marchar del resumen < su tipo vaya aqu > , a una lista de los animales. Y si es una lista de animales, entonces el mtodo de add ()
de la lista debe comportarse obviamente as: booleana sume ( el animal un )

Cuando usted mira a un API para unos genricos clasifique o interacte, pique un parmetro de tipo ( siga, JButton, an oponga ) y haga un hallazgo mental y reemplace en cada caso de la e (o cualquier identificador es usado como el |placeholder| para el parmetro de tipo).

Hacer su propio genrico clasifica

probamos la elaboracin nuestra propia clase genrica, para conseguir un feel for cmo trabaja, y entonces nosotros miraremos a unas cuantas sintaxis de genricos restantes detalles. Imagine a alguien crear un alquiler de clase, se maneja un estanque de los artculos alquilables.
alquiler de clase pblico{ lista privado RentalPool; private int maxNum; de alquiler pblico ( |int| MaxNum, liste RentalPool ){ this.maxNum = maxNum; this.rentalPool = rentalPool; } el pblico objeta getRental () { // bloques hasta hay algo disponibles retorne rentalPool.get ( 0); } vaco pblico ReturnRental (o de objeto){ rentalPool.add ( la o); } }

Ahora imagina le quiera hacer un subclase del alquiler que es slo se alquila automviles. Podra empezar con algo as como esto:
importe java.util.*; clase pblica CarRental extiende de alquiler{ public CarRental(int maxNum, List<Car> rentalPool) { super(maxNum, rentalPool); } automvil pblico getRental () { retorne (automvil) super.getRental(); }

624

Captulo 7:

Genricos y colecciones

vaco pblico ReturnRental (c de automvil){ super.returnRental ( la c); } vaco pblico ReturnRental (o de objeto){ si (automvil de |instanceof| de o){ super.returnRental ( la o); } de otro modo{ System.out.println ( " no pueda aadir un no-automvil"); // probablemente tire una excepcin } }

Pero entonces el ms le lo mirar, el ms comprende: 1. Est haciendo su propio tipo verificando en el mtodo de returnRental () . tomar un automvil, desde entonces es un override ( no una sobrecarga ) del mtodo del alquiler de clase. (Sobrecargar quitara su flexibilidad polimorfa con Rental). 2. Usted realmente no quiere hacer los subclases separados para cada tipo posible de la cosa alquilable ( los automviles, computadoras, zapatos, nios de juego de bochas, y as en ).
Usted no puede cambiar el tipo de argumento de returnRental () para

Pero dado su brillo natural ( aumentado por esto invent el guin ), comprende rpidamente que puede hacer la clase de alquiler un tipo genrico -- una plantilla para cualquier tipo de cosa alquilable - y est bueno para ir. ( dijimos artificiales...desde en verdad, podra muy bien querer tener los comportamientos diferentes para los tipos diferentes de las cosas alquilables, pero an que se pueda resolver limpiamente por cierta composicin de comportamiento en oposicin a la herencia ( usando la estrategia disea el modelo, por ejemplo ). Y ningn, disee modelos no estn en el examen, pero nosotros todava pensamos deba leer nuestro diseo decore libro. Considere los gatitos.) As aqu sea su nuevo y mejorado genrico alquiler clasifica:
importe java.util.*; el pblico clasifica RentalGeneric <T>{ // el "T" es para el tipo // parmetro la lista privada rentalPool; // Use la clase teclea para el // Tipo de lista private int maxNum; RentalGeneric pblico ( int maxNum, List<T> rentalPool) { // el constructor toma A // Lista del tipo de clase this.maxNum = maxNum; this.rentalPool = rentalPool; }

Las declaraciones genricas ( objetivos de examen 6.3 y 6.4 )

625

T pblico getRental () { // alquilamos el exterior un T // bloques hasta hay algo disponibles retorne rentalPool.get ( 0); } vaco pblico ReturnRental (returnedThing de T){ // y el arrendatario // resultados un T rentalPool.add(returnedThing);

} }

lo ponemos a la prueba:
clasifique TestRental{ la parte principal vaca esttica pblica (| args| de cuerda){ //haga ciertos automviles para el estanque El automvil c1 = nuevo automvil(); El automvil c2 = nuevo automvil(); Liste automvil carlista = nuevo ArrayList < el automvil>(); carList.add ( c1); carList.add ( c2); RentalGeneric automvil CarRental = nuevo RentalGeneric ( 2, carlista); // ahora consiga un exterior de automvil, y ello no necesitar un lanzamiento El automvil CarToRent = carRental.getRental(); carRental.returnRental(carToRent); // podemos pegar algo diferente en el carlista original? carList.add (nuevo gato( " velloso")); } }

Conseguimos un error:
kathy% javac1.5 RentalGeneric.java RentalGeneric.java:38: no pueda encontrar el smbolo simboliza: el mtodo aade (gato) ubicacin: interacte java.util.List automvil carList.add (nuevo gato( " velloso")); ^ 1 error

Ahora nosotros tenemos una clase de alquiler que podemos ser tecleados a sea lo que sea el programador escogen, y el compilador lo impondr. En otros trminos, ello trabaja justo cuando el

626

Captulo 7:

Genricos y colecciones

Las colecciones clasifican haga. Parecemos a ms los ejemplos de la sintaxis genrica usted pueda proporcionar en el API o el cdigo fuente. Aqu est otra clase simple que usa el tipo de |parameterized| de la clase en varias vas:
el pblico clasifica TestGenerics <T>{ T anInstance; T anArrayOfTs; // como la clase represente // como una variable de caso teclea // como un tipo de conjunto

TestGenerics(T anInstance) { // como un tipo de argumento this.anInstance = anInstance; } T getT () { // como un tipo de retorno retorne anInstance; } }

Obviamente esto es un uso ridculo de genricos, y en realidad ver los genricos slo raramente fuera de las colecciones. Pero, necesita comprender los tipos diferentes de la sintaxis genrica que podra encontrar, as que nosotros continuaremos con estos ejemplos hasta que nosotros les hemos cubierto todo. Usted puede usar ms de un |parameterized| teclea en una definicin de clase sencilla:
el pblico clasifica UseTwo <T, x>{ el T un; x dos; UseTwo ( el T un, x dos ){ this.one = un; this.two = dos; } T getT () { retorne un; } x getX () { retorno dos; } // prueba lo creando lo con < encuerde, el entero, nmero entero > la parte principal vaca esttica pblica (|args| de cuerda){ UseTwo < encuerde, el entero, nmero entero > dos =

nuevo UseTwo < encuerde, el entero, nmero entero > ( "|foo|", 42); Encuerde TheT = twos.getT(); // resultados una cuerda int theX = twos.getX(); // entero, nmero entero de resultados, unboxes al |int| } }

Las declaraciones genricas ( objetivos de examen 6.3 y 6.4 )

627

Y puede usar una forma de la anotacin de |wildcard| en una definicin de clase, para especificar un rango ("lmites" llamados) para el tipo que pueden ser usados para el parmetro de tipo:
el pblico clasifica AnimalHolder < el T extiende animal >{ // use el "T" en vez // de "?" animal de T; la parte principal vaca esttica pblica (| args| de cuerda){ AnimalHolder perro DogHolder = nuevo AnimalHolder < siga>(); // APROBACIN AnimalHolder entero, nmero entero x = nuevo AnimalHolder < el entero, nmero entero>(); // NINGN! } }

Crear los mtodos genricos

Hasta ahora, cada ejemplo que hemos visto usa el tipo de clase de parmetro - el tipo declar con el nombre de clase. Por ejemplo, en el UseTwo <T, x> la declaracin, nosotros usamos el T y | placeholders| de x a lo largo del cdigo. Pero es posible definir un tipo de | parameterized| a un nivel ms granular un mtodo. Imagina le quiera crear un mtodo que toma un caso de cada tipo, ejemplifique concretamente un ArrayList de ese tipo, y aada el caso al ArrayList. La propia clase no necesita ser genrica; bsicamente slo queremos un mtodo de uso prctico que

podemos pasar un tipo para y que pueda usar que represente para construir una coleccin de caja fuerte de tipo. Usando un mtodo genrico, podemos declarar el mtodo sin un tipo especfico y entonces consiga la informacin de tipo basada en el tipo del objeto pas al mtodo. Por ejemplo:
importe java.util.*; el pblico clasifica CreateAnArrayList{ el pblico makeArrayList vaco (T de T){ // tome un objeto de un // la incgnita teclea y usa A // "T" para representar el tipo Liste T lista = nuevo ArrayList < el T>(); // ahora nosotros puede crear el // liste usando "T" list.add ( el T); } }

En el cdigo precedente, si invoque el mtodo de makeArrayList () con un caso


inferior, el mtodo se comportar embargo pareca que este siempre: vaco pblico MakeArrayList (T inferior){ Liste perro lista = nuevo ArrayList < siga>(); list.add ( el T); } como sin

628

Captulo 7:

Genricos y colecciones

Y por supuesto si usted invoca el mtodo con un entero, nmero entero, entonces el T es reemplazado por Integer ( no en el | bytecode|, recuerde nosotros estamos describiendo cmo que ello parezca comportarse, no cmo lo en realidad conseguir lo hacer ). La cosa extraa sobre los mtodos genricos es que debe declarar la variable de tipo BEFORE el tipo de retorno del

mtodo:
el pblico makeArrayList vaco (T de T)

T antes de vaco define simplemente lo que el T es antes que lo usa como un tipo en el argumento. Usted MUST declara el tipo gusta de que a menos que el tipo es especificado para la clase. En CreateAnArrayList, la clase no es genrica, as no existe ningn |placeholder| de parmetro de tipo que podemos usar. Es tambin libre para poner lmites en el tipo que declara, por ejemplo, si quiere restringir el mtodo de makeArrayList () a
nico nmero o sus subtipos ( entero, nmero entero, flote, y as en ) dira pblico makeArrayList vaco (T de T)

Est tentando para olvidar que el argumento de mtodo no es donde declara la variable de parmetro de tipo T. a fin de usar una variable de tipo como el T, usted lo debe haber declarado o como el parmetro de clase teclea o en el mtodo, antes del retorno type.The siguiendo pueda parecer derecho,
vaco pblico MakeList (T de T){ }

Pero la nica va para este para ser el valor de inversin legal es si existe en realidad un T nombrado de clase, en cuyo caso el argumento se parece cualquiera otra declaracin de tipo para una variable. Y qu se sabe de los argumentos de constructor? Ellos, demasiado, se pueda declarar con un tipo genrico, pero entonces ello parece el forastero uniforme desde constructores no tenga ningn retorno teclea en modo alguno:
radio de clase pblico{ el pblico el radio (T de T){ } } // constructor jurdico

Las declaraciones genricas ( objetivos de examen 6.3 y 6.4 )

629

Si usted REALLY quiere conseguir ridculo (o dispar), puede declarar una clase con un nombre que es igual que el | placeholder| de parmetro de tipo:
x de clase{ el pblico la x (x de x){ } }

S, este x works.The que es el nombre de constructor no tiene ninguna relacin a represente la declaracin, que no tiene ninguna relacin al identificador de argumento de constructor, que es tambin, por supuesto, X. el compilador es capaz de analizar este y trate cada uno de los usos diferentes de x independientemente. As all no est ningn conflicto de nombramiento entre nombres de clase, represente |placeholders| de parmetro, y los identificadores variables.

Una de las equivocaciones ms comnes programadores hacen al crear las clases o mtodos genricas sea usar un <?> en la sintaxis de |wildcard| antes que una variable de tipo, , y as on.This cdigo podra parecer derecho, pero no es:
el pblico clasifica NumberHolder <?

extienda el nmero >{ }

Mientras que el signo de interrogacin trabaja al declarar una referencia para una variable, ello no trabaja para clase genrica y el mtodo declarations.This cdigo no es jurdico:
el pblico clasifica NumberHolder <?> { ? aNum; } // NINGN!

Pero si usted reemplaza el <?> con un identificador jurdico, est bueno:


el pblico clasifica NumberHolder <T>{ T aNum; } // S

98% de lo que es probable que hace con genricos son simplemente declare y use colecciones seguro el tipo, incluyendo usar ( y pasando ) les como argumentos. Pero ahora usted sabe mucho ms ( sino por ningunos medios toda cosa ) sobre los genricos intermedios trabajan.

630

Captulo 7:

Genricos y colecciones

Si esto era claro y fcil para usted, que es excelente. Si ello era...doloroso...slo sepa que los genricos sumadores al idioma de Java muy casi causaron una revuelta entre algunos de los desarrolladores de Java ms experimentados. La mayor parte de los crticos francos son simplemente infelices con la complejidad, o no convenza que ganando colecciones seguras de tipo vale el diez milln gobierne poco tiene que aprender ahora. Ello es verdadero ese con Java 5, aprendiendo Java slo consegua ms duro. Pero confia en nos...nosotros nunca lo ha visto tomar ms de dos das para "conseguir"

genricos. Esa es 48 horas consecutivas.

resumen de certificacin
Empezamos con una revisin rpida del mtodo de toString () . El mtodo de
toString () cuando usted se llama de forma automtica pregunta System.out.println ()

para imprimir un objeto -- usted lo hace caso de para retornar una cuerda de los datos significativos sobre sus objetos. Despus repasamos el propsito de == ( para ver si dos referencien variables refiera al mismo objeto ) y los iguales el mtodo de () (para ver si dos objetos son significativa equivalentes). Usted aprendi el |downside| de no haciendo caso de igualan () - no puede ser
capaz de encontrar el objeto en una coleccin. Nosotros discutimos un poco sobre cmo escribir un bien iguale mtodo de () - no olvide para usar |instanceof| y referirse a los atribuir

significativos del objeto. Nosotros repasamos los contract for hacer caso de iguala a () y
hashCode (). Nosotros aprendimos sobre la teora detrs de |hashcodes| , la diferencia entre jurdico, aproprie de, y |hashcoding| eficiente. Vemos tambin que aunque violentamente ineficiente, es jurdico para un mtodo de hashCode () para siempre retornar el mismo valor. Despus giramos a colecciones, donde nosotros aprendimos sobre las listas, los conjuntos, y mapas, y la diferencia entre las colecciones ordenadas y clasificadas. Nosotros aprendimos los atributos claves de la coleccin comn clasifican, y cuando para usar que. Cubrimos los que estn en el poder y fuera de las colecciones y conjuntos clases: cmo clasificar, y cmo buscar. Nosotros aprendimos sobre convertir conjuntos a listas y retrocedemos de nuevo. Finalmente agarramos genricos. Los genricos le deja imponer compile-cronometre seguridad de tipo en las colecciones u otras clases. Los genricos le ayuda a asegurar que cuando usted consigue un artculo de una coleccin ser del tipo usted espere se, sin lanzando requerido. Puede mezclar cdigo de herencia con cdigo de genricos, pero esto puede causar excepciones. Los reglamentos para el cambio de polimorfismo cuando usa genricos, aunque usando |wildcards| puede todava crear las colecciones polimorfas. Ciertos genricos declaraciones permiten la lectura de una coleccin, pero permita la actualizacin muy limitada de la coleccin. Todo en todo, un captulo de fascinar.

Taladro de dos minutos

631

3
dedo

tWo-MinUte
Aqu est alguna de la llave sealan con el

Drill
haciendo caso de hashCode () e igualan () ( el objetivo 6.2 )
la q iguala (), hashCode (), y toString () es pblico. la q hace caso de toString () de modo que System.out.println ()

de este captulo.

u otros mtodos puede ver algo til, como el estado de su objeto. la q usa == para determinar si dos referencian variables se refieren al mismo objeto. el uso de q iguala () para determinar si dos objetos son significativa equivalentes. q si usted no hace caso de igualan (), sus objetos no sern las llaves de
Hashing tiles.

q si usted no hace caso de igualan (), diferente objetos no pueden ser


considerado iguales.

las cuerdas y envolturas de q hacen caso de iguales ()

y compense por las llaves de Hashing. q al haciendo caso de los iguales (), use el operador de |instanceof| sin duda
q al haciendo caso de los iguales (), compare los atribuir significativos de
los objetos. est evaluando una clase apropiada.

los rasgos salientes de q de los iguales el contrato de () :

pronombre reflexivo de q: x.equals (x) es verdadera. la q simtrico: Si x.equals (y) es verdadero, entonces y.equals (x) debe ser verdadera. verbo transitivo de q: Si x.equals (y) es verdadero , y y.equals (z) es verdadero, entonces z.equals (x) es verdadera. la q consistente: El mltiple llama para x.equals (y) retornar el mismo
resultado.

cero de q: Si la x no es nulo, entonces x.equals (cero) es falso. q si x.equals (y) es verdadero, entonces x.hashCode () == y.hashCode () es verdadero. q si usted hace caso de igualan (), haga caso de hashCode (). q HashMap, HashSet, Hashtable, LinkedHashMap, and LinkedHashSet

use hashing. la q un apropiado hashCode ()


()

hace caso de ramitas al contrato de hashCode

la q un eficiente hashCode ()

haga caso de distribuya las llaves igualmente a travs de sus cubos. la q un |overridden| iguala () deba ser al menos tan preciso como su camarada de hashCode () . q para reiterar: si dos objetos son iguales, sus |hashcodes| deben ser iguales. la q es jurdico para un mtodo de hashCode () para retornar el mismo valor
para todos los casos (aunque en la prctica es muy ineficiente).

632

los rasgos salientes de q del contrato de hashCode () : la q consistente: el mltiple llama para x.hashCode () retorna el mismo

Captulo 7:

Genricos y colecciones

entero, nmero entero.

q si x.equals (y) es verdadero, x.hashCode ()

== y.hashCode ()

es verdadero.

q si x.equals (y) es falso, entonces x.hashCode ()


mejor.

== y.hashCode () puede ser o ciertamente o falsamente , pero falsamente tienda a crear la eficiencia

variables pasajeras de q no son apropiadas para igualan ()

Colecciones ( el objetivo 6.1 )

y hashCode ().

actividades de coleccin comnes de q incluyen aadir los objetos, quitando

objetos, el |fying| de |veri| objeta inclusin, recuperando los objetos, e iterando. tres significados de q para la "coleccin": q coleccin representa la estructura de datos en que los objetos son almacenados
coleccin q

java.util interacte de que conjunto y lista se una clase que tiene los mtodos de uso prctico

extienden
colecciones q

estticos de coleccin
la q cuatro sabores bsicos de colecciones incluye listas, conjuntos, mapas,

colas:
listas q conjuntos q

de las cosas ordenado, duplican permita, con un ndice. de las cosas puede o no pueda ser ordenado

y/o clasificado; duplicados no permitido.


mapas q

de cosas con las llaves puede o no pueda ser ordenado y/o clasificado; las llaves duplicadas no son permitidas. de cosas para procesar ordenado por FIFO o por la

colas q

prioridad.
la q cuatro bsico sub sabores de las colecciones clasificado, Unsorted,

ordenado, desordenado. q ordene iterando por una coleccin en una orden especfica, no casual.
q

clasifique iterando por una coleccin en una orden

clasificada.
la clasificacin de q puede ser alfabtica, numrica, o de programador

definido.

Teclee los atributos de las clases de coleccin comnes ( el objetivo 6.1 )


ArrayList de q: Rpidamente iteracin y el acceso al azar rpido. vector de q: Ello se parece un lento ArrayList, pero ha sincronizado mtodos. LinkedList de q: Bien para aadir elementos a los fines, i.e., pilas y colas. HashSet de q: Rpidamente acceso, no asegura ningunos duplicados, no proporcione ningn orden. LinkedHashSet de q: Ningunos duplicados; itera por la orden de insercin. TreeSet de q: Ningunos duplicados; itera en la orden clasificada.

Taladro de dos minutos

633

HashMap de q: Rpidamente actualizan ( teclee/valores); permita un cero teclear, muchos valores de cero. Hashtable de q: Como un lento HashMap ( como con Vector, debido a sus mtodos sincronizados ). Ningunos valores nulos o llaves nulo permitido. LinkedHashMap de q: Iteraciones rpidas; itera por orden de insercin o ltimo acceso; permita un cero teclear, muchos valores de cero. TreeMap de q: un mapa clasificado. PriorityQueue de q: una alharaca lista ordenado por la prioridad de los elementos.

Usar las clases de coleccin ( el objetivo 6.3 )


ser el |autoboxed|.

las colecciones de q se mantienen slo oponga se, pero los primitivos pueden

la q itera con el mejorado para , o con un Iterator por la via de hasNext ()

() prximo.
hasNext ()

mueve.

de q

determina si ms elementos existen; el Iterator no se

q despus () retorna el elemento prximo AND mueve el Iterator adelante. q para trabajar correctamente, las llaves de un mapa deben hacer caso de ()

y hashCode () de iguales. las colas de q usan () de oferta para aadir un elemento, obtenga votos () para quitar la cabeza de la cola, y atisbo () para mirar a la cabeza de una cola. q a partir de Java 6 TreeSets y TreeMaps tenga nuevos mtodos de navegacin quiera derribe () y ms alto (). la q usted puede crear / extender "apoyado" sub copias de treesets y TreeMaps.

clasificar y buscar conjuntos y listas ( el objetivo 6.5 )

la clasificacin de q puede estar en orden natural, o por la via de un

comparable o muchos comparadores. la q pone en prctica comparable usando compareTo () ; proporcione los slos
clasifican orden.

la q crea muchos comparadores para clasificar una clase muchas vas; el

instrumento compara (). q para estar clasificado y buscado, los elementos de una lista deben ser comparables. q para buscarse, un conjunto o lista deben clasificarse primero.

Clases de uso prctico: Colecciones y conjuntos ( el objetivo 6.5 )


o clase usando la orden natural.

la q ambos de estos java.util clases proporcionan q un mtodo de () de clase. Clasifique usando un comparador q

un mtodo de binarySearch () . Busque un conjunto pre-

clasificado o lista.

634

Captulo 7:

Genricos y colecciones

la q Arrays.asList () crea una lista de un conjunto y les vincula en conjunto. la q Collections.reverse () da marcha atrs la orden de elementos en una

lista.

retorna un comparador que clases en marcha atrs. las listas y conjuntos de q tienen un mtodo de toArray () para crear
la q Collections.reverseOrder ()
conjuntos.

genricos ( el objetivo 6.4 )

los genricos de q le deja imponer compile-tiempo representa de seguridad

en colecciones ( u otras clases y mtodos declar usando el genrico teclee los parmetros ). la q un ArrayList puede aceptar referencias del tipo siga, fustigue, o cualquier otro subtipo del animal ( el subclase, o si el animal es un enlace, ejecucin ).
q al usar las colecciones genricas, un lanzamiento no es necesitar conseguir (tipo declarado) los |ements| de ferrocarril elevado fuera de la coleccin. Con colecciones no genricas, un lanzamiento es exigido:
Liste cuerda GList = nuevo ArrayList < avance en lnea>(); Liste la lista = nuevo ArrayList(); // ms cdigo Encuerde la s = gList.get ( 0); // ningn lanzamiento necesitado encuerde la s = (cuerda) list.get ( 0); // tire el anzuelo exija

la q que puede pasar una coleccin genrica en un mtodo que toma una leccin de desfiladero no genrica, pero los resultados pueden ser desastrosos. El compilador no puede parar el mtodo de insertar el tipo malo en el represente previamente la coleccin segura. q si el compilador puede reconocer que cdigo de caja fuerte de no-tipo es

potencialmente peligre-e algo le declarar originalmente como la caja fuerte de tipo, conseguir una advertencia de compilador. Por ejemplo, si usted pasa una lista <cuerda> en un mtodo declare como
el |foo| vaco (listar aList){ aList.add(anInteger); }

Usted conseguir una advertencia porque aade () es potencialmente "inseguro". la q " compila sin error " no es igual que " compila sin advertencias."una advertencia de compilacin no es considerada un error de compilacin o falta. el genrico de q teclea informacin no existe a |runtime| -- ello es para compilar-cronometre de seguridad slo. Mezclar genricos con el cdigo de herencia puede crear compile codifique que pueda tirar una excepcin al |runtime|. asignaciones polimorfas de q se aplican slo para el tipo de base, no el parmetro genrico de tipo. Puede decir
Liste animal AList = nuevo ArrayList < el animal>();

No puede decir

Liste animal AList = nuevo ArrayList < siga>(); // s // ning n

Taladro de dos minutos

635

la q la regla polimorfa de asignacin se aplica en todas partes una asignacin

se puede hacer. La cosa siguiente no es permitido:


el |foo| vaco (listaaList){ } // no pueda tomar una lista <perro> Lista excluye a () { } // no pueda retornar una lista <perro>

la sintaxis de Wildcard de q permite un mtodo genrico, acepte subtipos ( o |

supertypes| ) del tipo declarado del argumento de mtodo:


addD vaco (lista< sigue >d){} // pueda tomar slo perro addD vaco (lista<? extienda el perro > ){} // tome un <perro> o <sabueso> la q la palabra clave de |wildcard| se extiende est acostumbrado a querer decir "extienda" o " |ments| de |imple|." as en <? extienda el perro > , perro puede ser una clase o un enlace. q al usar un |wildcard|, liste <? extienda el perro >, la coleccin se puede

acceder pero no modifique se.

q al usar un |wildcard|, liste <?>, cualquier tipo genrico se puede asignar a la

referencia, pero para acceso slo, ningunas transformaciones.


liste <? extienda el objeto >

la q lista <objeto> refiera slo a una lista objeto, mientras que liste <?> o

pueda tener cualquier tipo de objeto, pero

para el acceso slo. para el elemento:


el enlace pblico // declaracin de booleana aada (o // declaracin de

las convenciones de declaracin de q para genricos usan el T para tipo y e


lista <e> API para la lista de e) () List.add

la q los genricos representa el identificador pueda usado en clase, mtodo, y

las declaraciones variables:


clasifique Foo <T>{ } T anInstance; Foo(T aRef) {} el vaco excluye (aRef de T) {} () de |baz| de T{} // una clase // una variable de caso // un argumento de constructor // un argumento de mtodo // un tipo de retorno

El compilador substituir el tipo real.


el pblico clasifica UseTwo <T, x>{ }

la q que puede usar ms de un |parameterized| teclea en una declaracin: la q que puede declarar un mtodo genrico que usa un tipo no definido en la clase:
el pblico makeList vaco (T de T){ }

no est usando T como el tipo de retorno. Este mtodo tiene un tipo de retorno vaco, pero para usar T dentro del argumento del mtodo que debe
declarar, que sucede antes del tipo de retorno.

636

Captulo 7:

Genricos y colecciones

propia prueba
1. Dado:
la parte principal vaca esttica pblica (|args| de cuerda){ // INSERTE LA DECLARACIN AQU para ( el |int| yo = 0; yo < = 10; yo++) { Liste entero, nmero entero reme = nuevo ArrayList < el entero, nmero entero>(); para ( J de |int| = 0; el J < = 10; J++) row.add ( yo * j); table.add ( reme); } para (lista< el entero, nmero entero > reme: tabule ) System.out.println ( reme); }

Qu declaraciones pudieron ser insertadas a HERE de declaracin de // INSERT para permitir este cdigo para compilar y correr? (Escoja todo ese apply.) A. Liste lista de entero, nmero entero tabula = nueva lista
<lista< el entero, nmero entero>>();

B. Liste lista de entero, nmero entero tabula = nuevo


ArrayList <lista< el entero, nmero entero>>();

C. Liste lista de entero, nmero entero tabula = nuevo


ArrayList <ArrayList< el entero, nmero entero>>();

D. Liste < liste, el entero, nmero entero > tabule = nueva


lista < liste, el entero, nmero entero>();

E. Liste < liste, el entero, nmero entero > tabule = nuevo


ArrayList < liste, el entero, nmero entero>();

F. Liste < liste, el entero, nmero entero > tabule = nuevo


ArrayList < ArrayList, el entero, nmero entero>();

G. Ninguno del arriba

2. Qu declaraciones son verdaderas sobre comparar dos casos de la misma clase, suponiendo que los iguales () y mtodos de hashCode () han sido correctamente
|overridden|? (Escoja todo ese apply.) A. Si los iguales el mtodo de comparacin de hashCode ()

() retornan ciertamente, la == podra retornar falso B. Si los iguales el mtodo de () retornan falsamente, la comparacin de hashCode () == podra retornar verdadero C. Si la comparacin de hashCode () == retorna ciertamente, los iguales el mtodo de () deben retornar verdaderos D. Si la comparacin de hashCode () == retorna ciertamente,

los iguales el mtodo de () podran retornar verdaderos E. Si la comparacin de hashCode () != resultados ciertamente, los iguales el mtodo de () podran retornar verdaderos

Propia prueba

637

3. Dado:
el vaco esttico pblico antes de () { Ponga el conjunto = nuevo TreeSet(); set.add ( " 2"); set.add ( 3); set.add ( " 1"); Iterator lo = set.iterator(); mientras que ( it.hasNext ()) System.out.print ( it.next() + " "); }

Qu declaraciones son verdaderas? A. El antes del mtodo de () imprima 1 2 B. El antes del mtodo de () imprima 1 2 3 C. El antes del mtodo de () imprima tres nmeros, pero la orden no se puede determinar D. El antes del mtodo de () no compile E. El antes del mtodo de () tire una excepcin al | runtime| 4. Dado:
importe java.util.*; clasifique MapEQ{ la parte principal vaca esttica pblica (|args| de cuerda){ Combine < ToDos, encuerde > la m = nuevo HashMap < ToDos, avance en lnea>(); ToDos t1 = nuevo ToDos ( " lunes"); ToDos t2 = nuevo ToDos ( " lunes"); ToDos t3 = nuevo ToDos ( " martes"); m.put(t1, "doLaundry"); m.put(t2, "payBills"); m.put(t3, "cleanAttic"); System.out.println ( m.size()); } }

clasifique ToDos{ Da de cuerda; ToDos (d de cuerda){ el da = d; } los iguales booleanas pblicos (o de objeto){ retorne (( ToDos )o).el da == this.day; } // public int hashCode() { retorno 9; } }

638

Captulo 7:

Genricos y colecciones

Qu es correcto? (Escoja todo ese apply.) A. Como el cdigo apunte no compilar B. Como el cdigo apunte la salida ser 2 C. Como el cdigo apunte la salida ser 3 D. Si el mtodo de hashCode () es uncommented la salida
ser 2

E. Si el mtodo de hashCode ()
ser 3

es uncommented la salida es uncommented el cdigo no

F. Si el mtodo de hashCode ()
compilar

5. Dado:
12. el pblico clasifica AccountManager{ 13. mapa privado AccountTotals = nuevo HashMap(); 14. private int retirementFund; 15. 16. public int getBalance(String accountName) { 17. El entero, nmero entero suma = (entero, nmero entero) accountTotals.get ( AccountName); 18. si (sumar el cero de ==) 19. sume = Integer.valueOf ( 0); 20. retorne total.intValue(); 21. } 23. vaco pblico SetBalance ( encuerde AccountName, cantidad de |int| ){ 24. accountTotals.put ( AccountName, Integer.valueOf ( la cantidad)); 25. } 26. }

Esta clase va a ser actualizada para hacer uso de tipos de genrico apropiado, sin cambios en el comportamiento ( para mejorar o el algo peor ).

Cuales de estos pasos se pudieron ejecutarse? (Escoja tres.) A. Reemplace la lnea 13 con
el mapa privado < encuerde, |int| > AccountTotals = nuevo HashMap < encuerde, |int|>();

B. Reemplace la lnea 13 con


el mapa privado < encuerde, el entero, nmero entero > AccountTotals = nuevo HashMap < encuerde, el entero, nmero entero>();

C. Reemplace la lnea 13 con


el mapa privado <cuerda< entero, nmero entero >> accountTotals = nuevo HashMap <cuerda< el entero, nmero entero>>();

D. Reemplace las lneas 1720 con


int total = accountTotals.get(ac countName); si (sumar el cero de ==) sume = 0; total de retorno;

Propia prueba

639

E. Reemplace las lneas 1720 con


El entero, nmero entero suma = accountTotals.get ( AccountName); si (sumar el cero de ==) sume = 0; total de retorno;

F. Reemplace las lneas 1720 con


retorne accountTotals.get ( AccountName);

G. Reemplace la lnea 24 con


accountTotals.put ( AccountName, la cantidad);

H. Reemplace la lnea 24 con


accountTotals.put(accountName, amount.intValue());

6. Dado:
interacte hambriento e{ el vaco ronza ( la x de e); } interacte el carnvoro < la e extiende

animal > extienda hambriento e{} interacte el herbvoro la e extiende la planta extienda hambriento e{} planta de clase abstracta{} la hierba de clase extiende planta{} animal de clase abstracto{} el carnero de clase extiende los herbvoro de enseres animales <carnero>{ el vaco pblico ronza (x de carnero){} } el lobo de clase extiende los carnvoro de enseres animales <carnero>{ el vaco pblico ronza (x de carnero){} }

Qu de los cambios siguientes ( tomado separadamente ) permita este cdigo para compilar? (Escoja todo ese apply.) A. Cambie el carnvoro interacta para
interacte el carnvoro la e extiende la planta extienda hambriento e{}

B. Cambie el herbvoro interacta para


interacte el herbvoro < la e extiende animal > extienda hambriento e{}

C. Cambie el carnero clasifica para


el carnero de clase extiende los herbvoro de enseres animales <planta>{ el vaco pblico ronza (x de hierba){}

D. Cambie el carnero clasifica para


el carnero de clase se extiende la planta cumple el carnvoro { el vaco pblico ronza (x de lobo) {} }

640

Captulo 7:

Genricos y colecciones

E. Cambie el lobo clasifica para


el lobo de clase extiende los herbvoro de enseres animales <hierba>{ el vaco pblico ronza (x de hierba){}

F. Ningunos cambios son necesarios 7. Qu coleccin clasifica (ees) permiten le para criar o contraer su tamao y proporcione el acceso indexado a sus elementos, pero de quin mtodos no se son sincrnico? (Escoja todo ese apply.) A. java.util.HashSet B. java.util.LinkedHashSet C. java.util.List D. java.util.ArrayList E. java.util.Vector F. java.util.PriorityQueue 8. Dado un mtodo declar como
esttico pblico < la e extiende el nmero >lista< la e > procese (lista|nums|)

un programador quiere usar este mtodo as


// INSERTE LAS DECLARACIONES AQU la salida = procese ( la entrada);

Qu pares de declaraciones pudieron ser situados a HERE de declaraciones de // INSERT para permitir el cdigo para compilar? (Escoja todo ese apply.) A. ArrayList entra
= cero; ArrayList entero, nmero entero salida = cero;

B.

ArrayList entra = cero; Liste entero, nmero entero salida = cero; ArrayList entra = cero; Liste nmero salida = cero;

C.

Propia prueba

641

D.

Liste nmero entra = cero; ArrayList entero, nmero entero salida = cero; Liste nmero entra = cero; Liste nmero salida = cero;

E.

F. Liste entero, nmero entero entra = cero;


Liste entero, nmero entero salida = cero;

G. Ninguno del arriba

9. Dado la declaracin(s) de importacin apropiada, y


13. PriorityQueue cuerda |pq| = nuevo PriorityQueue < avance en lnea>(); 14. 15. 16. 17. 18. 19. 20. pq.add ( " 2"); pq.add ( " 4"); System.out.print ( pq.peek() + " "); pq.offer ( " 1"); pq.add ( " 3"); pq.remove ( " 1"); System.out.print ( pq.poll() + " ");

21. si (pq.remove( " 2 " )) System.out.print ( pq.poll() + " "); 22. System.out.println ( pq.poll() + " " + pq.peek());

Qu es el resultado? A. 2 3 B. 2 3 4 C. 4 3 4

D. 2 3 E. 4 3 F. 2 3 4 G. La compilacin fracasa H. Una excepcin es tirada al |runtime|

10. Dado:
3. 4. 5. de importe java.util.*; el pblico clasifica Mixup{ la parte principal vaca esttica pblica (|args| cuerda){

642

Captulo 7:

Genricos y colecciones

6. 7. 8. 9. 10. 11.

Objete la o = nuevo objeto(); // inserte el cdigo aqu s.add ( " o"); s.add ( la o); } }

Y estos tres fragmentos:


I. Ponga la s = nuevo HashSet(); II. s de TreeSet = nuevo TreeSet(); III. s de LinkedHashSet = nuevo LinkedHashSet();

Cuando fragmentos que yo, II, o III son insertados, independientemente, a lnea 7 , que es verdadero? (Escoja todo ese apply.) A. Fragmento compilo B. Fragmente II compila C. Fragmente III compila D. Fragmento ejecuto sin excepcin E. Fragmente II ejecuta sin excepcin F. Fragmente III ejecuta sin excepcin

11. Dado:
3. importe java.util.*; 4. tortuga de clase{ 5. tamao de |int|; 6. la tortuga pblica (s de |int|){ el tamao = s; } 7. los iguales booleanas pblicos (o de objeto){ retorne ( this.size tortuga de == (( )o).tamao); } 8. // inserte el cdigo aqu 9. } 10. el pblico clasifica TurtleTest{ 11. la parte principal vaca esttica pblica (|args| de cuerda) { 12. LinkedHashSet tortuga T = nuevo LinkedHashSet < la tortuga>(); 13. t.add (nueva tortuga( 1)); t.add (nueva tortuga( 2)); t.add (nueva tortuga( 1)); 14. System.out.println ( t.size()); 15. } 16. }

Propia prueba

643

Y estos dos fragmentos:


I. II. public int hashCode() { retorne el tamao/5; } // no se declara ningn mtodo de hashCode

Si fragmente que yo o II es insertado, independientemente, a lnea 8 , que es verdadero? (Escoja todo ese apply.) A. Si fragmente soy insertado, la salida es 2 B. Si fragmente soy insertado, la salida es 3 C. Si II de fragmento es insertado, la salida es 2 D. Si II de fragmento es insertado, la salida es 3 E. Si fragmente soy insertado, compilacin fracasa F. Si II de fragmento es insertado, compilacin fracasa 12. Dado la declaracin(s) de importacin apropiada, y:
13. TreeSet cuerda s = nuevo TreeSet < avance en lnea>(); 14. TreeSet aplican una base de gelatina a = nuevo TreeSet < avance en lnea>();

15. s.add ( " A"); s.add ( " b"); s.add ( " c"); s.add ( " d"); s.add ( " e"); 16. 17. los submarinos = (TreeSet) s.subSet ( la "b" , ciertamente, la "d" , ciertamente); 18. 19. 20. 21. s.add ( " g"); s.pollFirst(); s.pollFirst(); s.add ( " c2");

22. System.out.println ( s.size() +""+ subs.size());

Qu es verdadero? (Escoja todo ese apply.) A. El tamao de la s es 4 B. El tamao de la s es 5 C. El tamao de la s es 7 D. El tamao de submarinos es 1 E. El tamao de submarinos es 2 F. El tamao de submarinos es 3 G. El tamao de submarinos es 4 H. Una excepcin es tirada al |runtime|

644

Captulo 7:

Genricos y colecciones

13. Dado:
3. importe java.util.*; 4. el pblico clasifica Magallanes{ 5. la parte principal vaca esttica pblica (|args| de cuerda){ 6. TreeMap < encuerde, encuerde > MyMap = nuevo TreeMap < encuerde, avance en lnea>(); 7. myMap.put ( " un ", " manzano"); myMap.put ( "d", " fecha"); 8. myMap.put ( "f", " higo"); myMap.put ( "p", " pera"); 9. System.out.println ( " 1 despus del mango: " + //

sopa 1 10. myMap.higherKey ( " f")); 11. System.out.println ( " 1 despus del mango: " + // sopa 2 12. myMap.ceilingKey ( " f")); 13. System.out.println ( " 1 despus del mango: " + // sopa 3 14. myMap.floorKey ( " f")); 15. SortedMap < encuerde, encuerde > aplique una base de gelatina a = nuevo TreeMap < encuerde, avance en lnea>(); 16. aplique una base de gelatina a = myMap.tailMap ( " f"); 17. System.out.println ( " 1 despus del mango: " + // sopa 4 18. sub.firstKey()); 19. } 20. }

Que de las declaraciones System.out.println produzca la salida 1 despus del mango: p? (Escoja todo ese apply.) A. sopa 1 B. sopa 2 C. sopa 3 D. sopa 4 E. Ninguno; la compilacin fracasa F. Ninguno; una excepcin es tirada al |runtime| 14. Dado:
3. 4. 5. 6. 7. 8. 9. 10. 11. importe java.util.*; negocio de clase{ } el hotel de clase extiende negocio{ } la posada de clase extiende hotel{ } viaje de clase pblico{ ArrayList ir () { // inserte el cdigo aqu } }

Propia prueba

645

Qu, insertado independientemente a lnea 9, compile? (Escoja todo ese apply.)

A. retorne B. retorne C. retorne D. retorne 15. Dado:

nuevo ArrayList < la posada>(); nuevo ArrayList < el hotel>(); nuevo ArrayList < oponga se>(); nuevo ArrayList < el negocio>();

3. importe java.util.*; 4. perro de clase{ tamao de |int|; Siga (s de | int|){ el tamao = s; } } 5. el pblico clasifica FirstGrade{ 6. la parte principal vaca esttica pblica (|args| de cuerda){ 7. TreeSet yo = nuevo TreeSet < el entero, nmero entero>(); 8. TreeSet perro d = nuevo TreeSet < siga>(); 9. 10. d.add (nuevo perro( 1)); d.add (nuevo perro( 2)); d.add (nuevo perro( 1)); 11. i.add ( 1); i.add ( 2); i.add ( 1); 12. System.out.println ( d.size() + " " + i.size()); 13. } 14. }

Qu es el resultado? A. 1 2 B. 2 C. 2 3 D. 3 2 E. 3 F. La compilacin fracasa G. Una excepcin es tirada al |runtime|

16. Dado:
3. importe java.util.*; 4. el pblico clasifica GeoCache{ 5. la parte principal vaca esttica pblica (|args| de cuerda){ 6. Encuerde la s ={"combine ", "pluma" , "mrmol", " teclee"}; 7. O de Othello = nuevo Othello();

646

Captulo 7:

Genricos y colecciones

8. Arrays.sort ( s, o); 9. para ( s2 de cuerda: s) System.out.print ( s2 + " "); 10. System.out.println (Arrays.binarySearch( s, " mapa")); 11. } 12. Othello de clase esttico cumple el comparador <cuerda>{ 13. el |int| pblico compara ( encuerde A, encuerde la b ){ retorne b.compareTo ( el A); } 14. } 15. }

Qu es verdadero? (Escoja todo ese apply.) A. La compilacin fracasa B. La salida contendr unos 1 C. La salida contendr unos 2 D. La salida contendr A1 E. Una excepcin es tirada al |runtime| F. La salida contendr " teclee el mapa marmolea la pluma " G. La salida contendr " pluma marmolea el mapa teclea "

Las respuestas de propia prueba

647

respuestas de propia prueba


1. Dado:
la parte principal vaca esttica pblica (|args| de cuerda){ // INSERTE LA DECLARACIN AQU para ( el |int| yo = 0; yo < = 10; yo++) { Liste entero, nmero entero reme = nuevo ArrayList < el entero, nmero entero>(); para ( J de |int| = 0; el J < = 10; J++) row.add ( yo * j); table.add ( reme); } para (lista< el entero, nmero entero > reme: tabule ) System.out.println ( reme);

Qu declaraciones pudieron ser insertadas a HERE de declaracin de // INSERT para permitir este cdigo para compilar y correr? (Escoja todo ese apply.) A. Liste lista de entero, nmero entero tabula = nueva
lista <lista< el entero, nmero entero>>();

B. Liste lista de entero, nmero entero tabula = nuevo


ArrayList <lista< el entero, nmero entero>>();

C. Liste lista de entero, nmero entero tabula = nuevo


ArrayList <ArrayList< el entero, nmero entero>>();

D. Liste < liste, el entero, nmero entero > tabule =


nueva lista < liste, el entero, nmero entero>();

E. Liste < liste, el entero, nmero entero > tabule =


nuevo ArrayList < liste, el entero, nmero entero>();

F. Liste < liste, el entero, nmero entero > tabule =


nuevo ArrayList < ArrayList, el entero, nmero entero>();

G. Ninguno del arriba Respuesta:


3

b es correcta.

un est incorrecto porque la lista es un enlace, as que no puede decir nuevo List () a pesar de todos los tipos genricos. d, e , y f son incorrectas porque liste despida se slo el parmetro de tipo ( un mapa tomara dos, no una lista ). la c est tentando, pero incorrecto. El argumento de tipo > de entero, nmero entero debe ser el mismo para ambos lados de la asignacin, aunque el constructor nuevo ArrayList () a la derecha el lado es un subtipo del declarado represente la lista a la izquierda. (Objetivo 6.4)

648

Captulo 7:

Genricos y colecciones

2. Qu declaraciones son verdaderas sobre comparar dos casos de la misma clase, suponiendo que los iguales () y mtodos de hashCode () han sido correctamente
|overridden|? (Escoja todo ese apply.)

A. Si los iguales el mtodo de comparacin de hashCode ()

() retornan ciertamente, la == podra retornar falso B. Si los iguales el mtodo de () retornan falsamente, la comparacin de hashCode () == podra retornar verdadero C. Si la comparacin de hashCode () == retorna ciertamente, los iguales el mtodo de () deben retornar verdaderos D. Si la comparacin de hashCode () == retorna ciertamente, los iguales el mtodo de () podran retornar verdaderos E. Si la comparacin de hashCode () != resultados ciertamente, los iguales el mtodo de () podran retornar verdaderos Respuesta: 3 b y d. la b es verdadera porque a menudo dos objetos dismiles pueden retornar el mismo valor de |hashcode|. la d es verdadera porque si la comparacin de hashCode () retorna
a == , los dos objetos no podran o no podran ser iguales. A, c , y e son incorrectos. la c es incorrecta porque el mtodo de hashCode () es muy flexible en sus valores de retorno, y a menudo dos objetos dismiles pueden retornar el mismo valor de cdigo de picadillo. A y e son una negacin del hashCode ()

de () . (Objetivo 6.2) 3. Dado:

y igualan contrato

el vaco esttico pblico antes de () { Ponga el conjunto = nuevo TreeSet(); set.add ( " 2"); set.add ( 3); set.add ( " 1"); Iterator lo = set.iterator(); mientras que ( it.hasNext ()) System.out.print ( it.next() + " "); }

Qu declaraciones son verdaderas? A. El antes del mtodo de () imprima 1 2 B. El antes del mtodo de () imprima 1 2 3 C. El antes del mtodo de () imprima tres nmeros, pero la orden no se puede determinar D. El antes del mtodo de () no compile E. El antes del mtodo de () tire una excepcin al |runtime|

Las respuestas de propia prueba

649

Respuesta: 3 e es correcta. No puede poner ambas cuerdas y s de |int| en el mismo TreeSet.


Sin los genricos, el compilador tiene nada de conocer lo que el tipo es apropiado para este TreeSet, as que permite toda cosa para compilar. A |runtime| , el TreeSet tratar de clasificar los elementos como son aadidos, y cuando prueba para comparar un entero, nmero entero con una cuerda tirar un ClassCastException. Note que aunque el antes de mtodo de () no usa genricos, usa |

autoboxing|. Est a la mira del cdigo que usa ciertas nuevas caractersticas y ciertas caractersticas viejas mezcladas en conjunto. A, b, c , y d son incorrectos basados en el arriba. (Objetivo 6.5)

4. Dado:
importe java.util.*; clasifique MapEQ{ la parte principal vaca esttica pblica (|args| de cuerda){ Combine < ToDos, encuerde > la m = nuevo HashMap < ToDos, avance en lnea>(); ToDos t1 = nuevo ToDos ( " lunes"); ToDos t2 = nuevo ToDos ( " lunes"); ToDos t3 = nuevo ToDos ( " martes"); m.put(t1, "doLaundry"); m.put(t2, "payBills"); m.put(t3, "cleanAttic"); System.out.println ( m.size()); } } clasifique ToDos{ Da de cuerda; ToDos (d de cuerda){ el da = d; } los iguales booleanas pblicos (o de objeto){ retorne (( ToDos )o).el da == this.day; } // public int hashCode() { retorno 9; } }

Qu es correcto? (Escoja todo ese apply.) A. Como el cdigo apunte no compilar B. Como el cdigo apunte la salida ser 2 C. Como el cdigo apunte la salida ser 3

D. Si el mtodo de hashCode ()
ser 2

es uncommented la salida es uncommented la salida es uncommented el cdigo

E. Si el mtodo de hashCode ()
ser 3

F. Si el mtodo de hashCode ()
no compilar

650

Captulo 7:

Genricos y colecciones

Respuesta: 3 c y d es correcta. Si hashCode () no es |overridden| entonces cada entrada examinar su propio cubo, y el |overridden| iguale el mtodo de () tendr ningn efecto en determinar equivalencia. Si hashCode () es |overridden| , entonces el | overridden| iguala el mtodo de () mire t1 y t2 como duplicados. A, b, e , y f son incorrectos basados en el arriba. (Objetivo 6.2)

5. Dado:
12. el pblico clasifica AccountManager{ 13. mapa privado AccountTotals = nuevo HashMap(); 14. private int retirementFund; 15. 16. public int getBalance(String accountName) { 17. El entero, nmero entero suma = (entero, nmero entero) accountTotals.get ( AccountName); 18. si (sumar el cero de ==) 19. sume = Integer.valueOf ( 0); 20. retorne total.intValue(); 21. } 23. vaco pblico SetBalance ( encuerde AccountName, cantidad de |int| ){ 24. accountTotals.put ( AccountName, Integer.valueOf ( la cantidad)); 25. } }

Esta clase va a ser actualizada para hacer uso de tipos de genrico apropiado, sin cambios en el

comportamiento ( para mejorar o el algo peor ). Cuales de estos pasos se pudieron ejecutarse? (Escoja tres.) A. Reemplace la lnea 13 con
el mapa privado < encuerde, |int| > AccountTotals = nuevo HashMap < encuerde, |int|>();

B. Reemplace la lnea 13 con


el mapa privado < encuerde, el entero, nmero entero > AccountTotals = nuevo HashMap < encuerde, el entero, nmero entero>();

C. Reemplace la lnea 13 con


el mapa privado <cuerda< entero, nmero entero >> accountTotals = nuevo HashMap <cuerda< el entero, nmero entero>>();

D. Reemplace las lneas 1720 con


int total = accountTotals.get(ac countName); si (sumar el cero de ==) sume = 0; total de retorno;

E. Reemplace las lneas 1720 con


El entero, nmero entero suma = accountTotals.get ( AccountName); si (sumar el cero de ==) sume = 0; total de retorno;

Las respuestas de propia prueba

651

F. Reemplace las lneas 1720 con


retorne accountTotals.get ( AccountName);

G. Reemplace la lnea 24 con


accountTotals.put ( AccountName, la cantidad);

H. Reemplace la lnea 24 con


accountTotals.put(accountName, amount.intValue());

Respuesta:
3

b, e , y la g es correcta.

un be wrong porque no puede usar un tipo primitivo como un parmetro de tipo. la c no tiene razn porque un mapa toma dos teclee los parmetros separados por una coma. la d no tiene razn porque un |int| no puede el |autobox| a un

cero, y f no tenga razn porque un cero no puede unbox a 0. H no tenga razn porque no puede el | autobox| un primitivo slo tratando de invocar un mtodo con ello. (Objetivo 6.4)

6. Dado:
interacte hambriento e{ el vaco ronza ( la x de e); } interacte el carnvoro < la e extiende animal > extienda hambriento e{} interacte el herbvoro la e extiende la planta extienda hambriento e{} planta de clase abstracta{} la hierba de clase extiende planta{} animal de clase abstracto{} el carnero de clase extiende los herbvoro de enseres animales <carnero>{ el vaco pblico ronza (x de carnero){} } el lobo de clase extiende los carnvoro de enseres animales <carnero>{ el vaco pblico ronza (x de carnero){} }

Qu de los cambios siguientes ( tomado separadamente ) permita este cdigo para compilar? (Escoja todo ese apply.) A. Cambie el carnvoro interacta para
interacte el carnvoro la e extiende la planta extienda hambriento e{}

B. Cambie el herbvoro interacta para


interacte el herbvoro < la e extiende animal > extienda hambriento e{}

C. Cambie el carnero clasifica para


el carnero de clase extiende los herbvoro de enseres animales <planta>{ el vaco pblico ronza (x de hierba){}

652

Captulo 7:

Genricos y colecciones

D. Cambie el carnero clasifica para


el carnero de clase se extiende la planta cumple el carnvoro { el vaco pblico ronza (x de lobo) {} }

E. Cambie el lobo clasifica para


el lobo de clase extiende los herbvoro de enseres animales <hierba>{ el vaco pblico ronza (x de hierba){}

F. Ningunos cambios son necesarios Respuesta: 3 b es correcta. El problema con el cdigo original es que carnero prueba para poner en prctica el herbvoro <carnero> y herbvoro declaran que su e de parmetro de tipo puede ser cada tipo que extiende planta. Desde un carnero no es una planta, herbvoro <carnero> hacen ningn sentido -el carnero de tipo es fuera el rango permitido de la e de parmetro de herbvoro. Las soluciones slas que altere la definicin de un carnero o altere la definicin del herbvoro ser capaz de fijar este. As A, e , y f son eliminados. trabajos de b, cambiando la definicin de un herbvoro para permitirlo comer el carnero resuelve el problema. c no trabaja porque un herbvoro debe tener un munch (planta) mtodo, no ronce (hierba). Y la d no trabaja, porque en la d nosotros hicimos el carnero extender planta, ahora el lobo clasifica las roturas porque su ronce (carnero) el mtodo ya no cumple el contrato del carnvoro. (Objetivo 6.4) 7. Qu coleccin clasifica (ees) permiten le para criar o contraer su tamao y proporcione el acceso indexado a sus elementos, pero de quin mtodos no se son sincrnico? (Escoja todo ese apply.) A. java.util.HashSet B. java.util.LinkedHashSet C. java.util.List D. java.util.ArrayList E. java.util.Vector F. java.util.PriorityQueue Respuesta: el 3D es correcto. Todas las clases de coleccin le permiten para criar o contraer el

tamao de su coleccin. ArrayList proporciona un ndice a sus elementos. Las nuevas clases de coleccin se dirigen no para haber sincronizado mtodos. El vector es una ejecucin ms vieja de la funcionalidad de ArrayList y ha sincronizado mtodos; ello atrasa que ArrayList. A, b, c, e , y f son incorrectos basados en la lgica descrita ms arriba; Notas: C, lista es un enlace, y f , PriorityQueue no ofrece acceso por el
ndice. (Objetivo 6.1)

Las respuestas de propia prueba

653

8. Dado un mtodo declar como


esttico pblico < la e extiende el nmero >lista< la e > procese (lista|nums|)

un programador quiere usar este mtodo as


// salida de HERE de declarac iones de INSERT = procese ( la entrada) ;

Qu pares de declaraciones pudieron ser situados a HERE de declaraciones de // INSERT para permitir el cdigo para compilar? (Escoja todo ese apply.) A. ArrayList entra
= cero; ArrayList entero, nmero entero salida = cero;

B.

ArrayList entra = cero; Liste entero, nmero entero salida = cero;

C.

ArrayList entra = cero; Liste nmero salida = cero; Liste nmero entra = cero; ArrayList entero, nmero entero salida = cero; Liste nmero entra = cero; Liste nmero salida = cero;

D.

E.

F. Liste entero, nmero entero entra = cero;


Liste entero, nmero entero salida = cero;

G. Ninguno del arriba Respuesta:


3

b, e , y la f es correcta.

El tipo de retorno del proceso se declara claramente como una lista , no un ArrayList , as A y d no tienen razn. la c no tiene razn porque el tipo de retorno evala a List entero, nmero entero , y que no se pueda asignar a una variable del tipo liste nmero. Por supuesto todo esto probablemente causara un NullPointerException desde las variables es todava nulo - pero la pregunta slo pregunta nosotros para conseguir el cdigo para compilar. (Objetivo 6.4)

9. Dado la declaracin(s) de importacin apropiada, y


13. PriorityQueue cuerda |pq| = nuevo PriorityQueue < avance en lnea>(); 14. 15. pq.add ( " 2"); pq.add ( " 4");

654

Captulo 7:

Genricos y colecciones

16. System.out.print ( 17. pq.offer ( " 1"); 18. pq.add ( " 3"); 19. pq.remove ( " 1"); 20. System.out.print ( 21. si (pq.remove( " 2 ( pq.poll() + " "); 22. System.out.println

pq.peek() + " ");

pq.poll() + " "); " )) System.out.print ( pq.poll() + " " + pq.peek());

Qu es el resultado? A. 2 3 B. 2 3 4 C. 4 3 4 D. 2 3 E. 4 3 F. 2 3 4 G. La compilacin fracasa H. Una excepcin es tirada al |runtime| Respuesta: 3 b es correcta. Por el bien del examen, aada () y ofrezca () ambos aumentan (en este caso), naturalmente clasificado forman fila. Las llamadas para obtener votos () ambos retorne y entonces quite el primer artculo de la cola, as el si la prueba suspende. A, c, d, e, f, g , y h son incorrectos basados en el arriba. (Objetivo 6.1)

10. Dado:
3. importe java.util.*; 4. el pblico clasifica Mixup{ 5. la parte principal vaca esttica pblica (|args| de cuerda){ 6. Objete la o = nuevo objeto(); 7. // inserte el cdigo aqu 8. s.add ( " o"); 9. s.add ( la o); 10. }

11. }

Las respuestas de propia prueba

655

Y estos tres fragmentos:


I. Ponga la s = nuevo HashSet(); II. s de TreeSet = nuevo TreeSet(); III. s de LinkedHashSet = nuevo LinkedHashSet();

Cuando fragmentos que yo, II, o III son insertados, independientemente, a lnea 7 , que es verdadero? (Escoja todo ese apply.) A. Fragmento compilo B. Fragmente II compila C. Fragmente III compila D. Fragmento ejecuto sin excepcin E. Fragmente II ejecuta sin excepcin F. Fragmente III ejecuta sin excepcin Respuesta: A, b, c, d , y la f es todo correcto.

La e sla es incorrecta. Elementos de un TreeSet deben poner en prctica de alguna forma comparable. (Objetivo 6.1)

11. Dado:
3. importe java.util.*; 4. tortuga de clase{ 5. tamao de |int|; 6. la tortuga pblica (s de |int|){ el tamao = s; } 7. los iguales booleanas pblicos (o de objeto){ retorne ( this.size tortuga de == (( )o).tamao); } 8. // inserte el cdigo aqu 9. } 10. el pblico clasifica TurtleTest{ 11. la parte principal vaca esttica pblica (|args| de cuerda){ 12. LinkedHashSet tortuga T = nuevo LinkedHashSet < la tortuga>(); 13. t.add (nueva tortuga( 1)); t.add (nueva tortuga( 2)); t.add (nueva tortuga( 1)); 14. System.out.println ( t.size()); 15. }

16. }

656

Captulo 7:

Genricos y colecciones

Y estos dos fragmentos:


I. II. public int hashCode() { retorne el tamao/5; } // no se declara ningn mtodo de hashCode

Si fragmente que yo o II es insertado, independientemente, a lnea 8 , que es verdadero? (Escoja todo ese apply.) A. Si fragmente soy insertado, la salida es 2 B. Si fragmente soy insertado, la salida es 3 C. Si II de fragmento es insertado, la salida es 2 D. Si II de fragmento es insertado, la salida es 3 E. Si fragmente soy insertado, compilacin fracasa F. Si II de fragmento es insertado, compilacin fracasa Respuesta: 3 A y d es correcto. Mientras que II de fragmento no podra cumplir el contrato de
hashCode () ( como usted pueda ver por los resultados ), es Java jurdico. Para el propsito del examen, si usted no hace caso de hashCode (), cada objeto tendr un |hashcode| nico. b, c, e , y f son incorrectas basadas en el arriba. (Objetivo 6.2)

12. Dado la declaracin(s) de importacin apropiada, y:


13. TreeSet cuerda s = nuevo TreeSet < avance en lnea>(); 14. TreeSet aplican una base de gelatina a = nuevo TreeSet < avance en lnea>(); 15. s.add ( " A"); s.add ( " b"); s.add ( " c"); s.add ( " d"); s.add ( " e"); 16. 17. los submarinos = (TreeSet) s.subSet ( la "b" ,

ciertamente, la "d" , ciertamente); 18. 19. 20. 21. 22. s.add ( " g"); s.pollFirst(); s.pollFirst(); s.add ( " c2"); System.out.println ( s.size() +""+ subs.size());

Qu es verdadero? (Escoja todo ese apply.) A. El tamao de la s es 4 B. El tamao de la s es 5 C. El tamao de la s es 7 D. El tamao de submarinos es 1

Las respuestas de propia prueba

657

E. El tamao de submarinos es 2 F. El tamao de submarinos es 3 G. El tamao de submarinos es 4 H. Una excepcin es tirada al |runtime| Respuesta: 3 b y f es correcta. Despus de la "g" es aadido, s de TreeSet contiene seis elementos y TreeSet aplican una base de gelatina a contiene tres (b , c , d), porque la "g" est ausente del rango de submarinos. El primero pollFirst () encuentran y quita slo el " un ". El secundar pollFirst () encuentran y quite la "b" de ambos TreeSets ( recuerde son apoyados ). El final aade () est en rango de ambos TreeSets. Los contenidos finales son c,c2,d,e,g y c,c2,d. A, c, d, e, g , y h son incorrectos basados en el arriba. (Objetivo 6.3)

13. Dado:
3. importe java.util.*; 4. el pblico clasifica Magallanes{ 5. la parte principal vaca esttica pblica (|args| de cuerda){ 6. TreeMap < encuerde, encuerde > MyMap = nuevo TreeMap < encuerde, avance en lnea>(); 7. myMap.put ( " un ", " manzano"); myMap.put ( "d", " fecha"); 8. myMap.put ( "f", " higo"); myMap.put ( "p", " pera"); 9. System.out.println ( " 1 despus del mango: " + // sopa 1 10. myMap.higherKey ( " f")); 11. System.out.println ( " 1 despus del mango: " + // sopa 2 12. myMap.ceilingKey ( " f")); 13. System.out.println ( " 1 despus del mango: " + // sopa 3 14. myMap.floorKey ( " f")); 15. SortedMap < encuerde, encuerde > aplique una base de gelatina a = nuevo TreeMap < encuerde, avance en lnea>(); 16. aplique una base de gelatina a = myMap.tailMap ( " f"); 17. System.out.println ( " 1 despus del mango: " + // sopa 4 18. sub.firstKey()); 19. } 20. }

Que de las declaraciones System.out.println produzca la salida 1 despus del mango: p? (Escoja todo ese apply.) A. sopa 1 B. sopa 2 C. sopa 3

658

Captulo 7:

Genricos y colecciones

D. sopa 4 E. Ninguno; la compilacin fracasa F. Ninguno; una excepcin es tirada al |runtime|

Respuesta:

3 un es correcto. El ceilingKey () el argumento de mtodo es inclusivo. El mtodo de floorKey () estara acostumbrado a encontrar llaves antes de la llave especificada. El firstKey () el argumento de mtodo es tambin inclusivo.

b, c, d, e , y f son incorrectas basadas en el arriba. (Objetivo 6.3)

14. Dado:
3. 4. 5. 6. 7. 8. 9. 10. 11. importe java.util.*; negocio de clase{ } el hotel de clase extiende negocio{ } la posada de clase extiende hotel{ } viaje de clase pblico{ ArrayList ir () { // inserte el cdigo aqu } }

Qu, insertado independientemente a lnea 9, compile? (Escoja todo ese apply.) A. retorne nuevo ArrayList < la posada>(); B. retorne nuevo ArrayList < el hotel>(); C. retorne nuevo ArrayList < oponga se>(); D. retorne nuevo ArrayList < el negocio>(); Respuesta: b es correcta.

un est incorrecto porque las asignaciones polimorfas no se aplican a los parmetros de tipo genricos. c y d son incorrectas porque no siguen los reglamentos de polimorfismo bsicos. (Objetivo 6.4)

Las respuestas de propia prueba

659

15. Dado:

3. importe java.util.*; 4. perro de clase{ tamao de |int|; Siga (s de | int|){ el tamao = s; } } 5. el pblico clasifica FirstGrade{ 6. la parte principal vaca esttica pblica (|args| de cuerda){ 7. TreeSet yo = nuevo TreeSet < el entero, nmero entero>(); 8. TreeSet perro d = nuevo TreeSet < siga>(); 9. 10. d.add (nuevo perro( 1)); d.add (nuevo perro( 2)); d.add (nuevo perro( 1)); 11. i.add ( 1); i.add ( 2); i.add ( 1); 12. System.out.println ( d.size() + " " + i.size()); 13. } 14. }

Qu es el resultado? A. 1 2 B. 2 C. 2 3 D. 3 2 E. 3 F. La compilacin fracasa G. Una excepcin es tirada al |runtime| Respuesta: 3 g es correcta. El perro de clase necesita poner en prctica comparable para un TreeSet ( que guarde sus elementos clasificados ) para ser capaz de contener los objetos inferiores.
A, b, c, d, e , y f son incorrectos basados en el arriba. (Objetivo 6.5)

16. Dado:
3. importe java.util.*; 4. el pblico clasifica GeoCache{ 5. la parte principal vaca esttica pblica (|args| de cuerda){ 6. Encuerde la s ={"combine ", "pluma" , "mrmol", " teclee"}; 7. O de Othello = nuevo Othello(); 8. Arrays.sort ( s, o);

660

Captulo 7:

Genricos y colecciones

9. para ( s2 de cuerda: s) System.out.print ( s2 + " "); 10. System.out.println (Arrays.binarySearch( s, " mapa")); 11. } 12. Othello de clase esttico cumple el comparador <cuerda>{ 13. el |int| pblico compara ( encuerde A, encuerde la b ){ retorne b.compareTo ( el A); } 14. } 15. }

Qu es verdadero? (Escoja todo ese apply.) A. La compilacin fracasa B. La salida contendr unos 1 C. La salida contendr unos 2 D. La salida contendr A1 E. Una excepcin es tirada al |runtime| F. La salida contendr " teclee el mapa marmolea la pluma " G. La salida contendr " pluma marmolea el mapa teclea " Respuesta: 3D y g son correctos. En primer lugar, el mtodo de compareTo () dar marcha atrs la clase normal. En segundo lugar, la clase () es vlido. Tercero, el binarySearch () da1 porque se necesita invocar usando el mismo comparador (o), tal cual acostumbre a clasificar el conjunto. Note que cuando el binarySearch () retorna un "resultado indefinido" oficialmente no tiene que ser un -1 , pero ello normalmente es, as si escogi nica g, consigue el crdito completo ! A, b, c, e , y f son incorrectos basados en el arriba. (Objetivo 6.5)

Anda mungkin juga menyukai