 |
 |
9) Stockage des objets |
|
 |
|
Texte original |
 |
Traducteur : Jérome QUELIN |
|
 |
|
 |
 |
 |
 |
 |
 |
|
 |
|
 |
 |
 |
Unsupported
operations
|
 |
Opérations non supportées
|
 |
 |
 |
It’s possible to turn an array into
a List with the Arrays.asList( ) method:
|
 |
Il est possible de transformer un tableau en List grâce à
la méthode Arrays.asList() :
|
 |
 |
 |
//: c09:Unsupported.java // Sometimes methods defined in the // Collection interfaces don't work! import java.util.*;
public class Unsupported { private static String[] s = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", }; static List a = Arrays.asList(s); static List a2 = a.subList(3, 6); public static void main(String[] args) { System.out.println(a); System.out.println(a2); System.out.println( "a.contains(" + s[0] + ") = " + a.contains(s[0])); System.out.println( "a.containsAll(a2) = " + a.containsAll(a2)); System.out.println("a.isEmpty() = " + a.isEmpty()); System.out.println( "a.indexOf(" + s[5] + ") = " + a.indexOf(s[5])); // Traverse backwards: ListIterator lit = a.listIterator(a.size()); while(lit.hasPrevious()) System.out.print(lit.previous() + " "); System.out.println(); // Set the elements to different values: for(int i = 0; i < a.size(); i++) a.set(i, "47"); System.out.println(a); // Compiles, but won't run: lit.add("X"); // Unsupported operation a.clear(); // Unsupported a.add("eleven"); // Unsupported a.addAll(a2); // Unsupported a.retainAll(a2); // Unsupported a.remove(s[0]); // Unsupported a.removeAll(a2); // Unsupported } } ///:~
|
 |
//: c09:Unsupported.java // Quielquefois les méthodes définies dans les // interfaces Collection ne fonctionnent pas! import java.util.*;
public class Unsupported { private static String[] s = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", }; static List a = Arrays.asList(s); static List a2 = a.subList(3, 6); public static void main(String[] args) { System.out.println(a); System.out.println(a2); System.out.println( "a.contains(" + s[0] + ") = " + a.contains(s[0])); System.out.println( "a.containsAll(a2) = " + a.containsAll(a2)); System.out.println("a.isEmpty() = " + a.isEmpty()); System.out.println( "a.indexOf(" + s[5] + ") = " + a.indexOf(s[5]));
// Traversée à reculons : ListIterator lit = a.listIterator(a.size()); while(lit.hasPrevious()) System.out.print(lit.previous() + " "); System.out.println(); // Modification de la valeur des éléments : for(int i = 0; i < a.size(); i++) a.set(i, "47"); System.out.println(a); // Compiles, mais ne marche pas : lit.add("X"); // Opération non supportée a.clear(); // Non supporté a.add("eleven"); // Non supporté a.addAll(a2); // Non supporté a.retainAll(a2); // Non supporté a.remove(s[0]); // Non supporté a.removeAll(a2); // Non supporté } } ///:~
|
 |
 |
 |
You’ll discover that only a portion
of the Collection and List interfaces are actually implemented.
The rest of the methods cause the unwelcome appearance of something called an
UnsupportedOperationException. You’ll learn all about exceptions in
the next chapter, but the short story is that the Collection
interface—as well as some of the other interfaces in the
Java containers library—contain “optional” methods, which
might or might not be “supported” in the concrete class that
implements that interface. Calling an unsupported method causes an
UnsupportedOperationException to indicate a programming
error.
|
 |
En fait, seule une partie des interfaces Collection et
List est implémentée. Le reste des méthodes provoque l'apparition déplaisante
d'une chose appelée UnsupportedOperationException. Vous en apprendrez plus sur les
exceptions dans le chapitre suivant, mais pour résumer l'interface Collection - de
même que certaines autres interfaces de la bibliothèque de conteneurs Java -
contient des méthodes « optionnelles », qui peuvent ou non être « supportées »
dans la classe concrète qui implémente cette interface. Appeler une méthode non
supportée provoque une UnsupportedOperationException pour indiquer une erreur de
programmation.
|
 |
 |
 |
“What?!?” you say,
incredulous. “The whole point of interfaces and base classes is
that they promise these methods will do something meaningful! This breaks that
promise—it says that not only will calling some methods not perform
a meaningful behavior, they will stop the program! Type safety was just thrown
out the window!”
|
 |
« Comment ?!? » vous exclamez-vous, incrédule. « Tout
l'intérêt des interfaces et des classes de base provient du fait qu'elles
promettent que ces méthodes feront quelque chose d'utile ! Cette affirmation rompt cette
promesse - non seulement ces méthodes ne réalisent pas d'opération intéressante, mais en
plus elles arrêtent le programme ! Qu'en est-il du contrôle de type ? »
|
 |
 |
 |
It’s not quite that bad. With a
Collection, List, Set, or Map, the compiler still
restricts you to calling only the methods in that interface, so
it’s not like Smalltalk (in which you can call any method for any object,
and find out only when you run the program whether your call does anything). In
addition, most methods that take a Collection as an argument only read
from that Collection—all the “read” methods of
Collection are not optional.
|
 |
Ce n'est pas si grave que ça. Avec une Collection, une
List, un Set ou une Map, le compilateur empêche
toujours d'appeler des méthodes autres que celles présentes dans cette interface,
ce n'est donc pas comme Smalltalk (qui permet d'appeler n'importe quelle méthode sur n'importe
objet, appel dont on ne verra la pertinence que lors de l'exécution du programme). De plus, la
plupart des méthodes acceptant une Collection comme argument ne font que lire
cette Collection - et les méthodes de « lecture » de
Collection ne sont pas optionnelles.
|
 |
 |
 |
This approach prevents an explosion of
interfaces in the design. Other designs for container libraries always seem to
end up with a confusing plethora of interfaces to describe each of the
variations on the main theme and are thus difficult to learn. It’s not
even possible to capture all of the special cases in interfaces, because
someone can always invent a new interface. The “unsupported
operation” approach achieves an important goal of the Java containers
library: the containers are simple to learn and use; unsupported operations are
a special case that can be learned later. For this approach to work,
however:
|
 |
Cette approche empêche l'explosion du nombre d'interfaces dans la
conception. Les autres conceptions de bibliothèques de conteneurs semblent toujours se terminer par
une pléthore d'interfaces pour décrire chacune des variations sur le thème principal et sont donc
difficiles à appréhender. Il n'est même pas possible de capturer tous les cas spéciaux dans les
interfaces, car n'importe qui peut toujours créer une nouvelle
interface. L'approche « opération non supportée » réalise l'un des buts
fondamentaux de la bibliothèque de conteneurs Java : les conteneurs sont simples à apprendre et à
utiliser ; les opérations non supportées sont des cas spéciaux qui peuvent être appris par la
suite. Pour que cette approche fonctionne, toutefois :
|
 |
 |
 |
- The
UnsupportedOperationException must be a rare event. That is, for most
classes all operations should work, and only in special cases should an
operation be unsupported. This is true in the Java containers library, since the
classes you’ll use 99 percent of the time—ArrayList,
LinkedList, HashSet, and HashMap, as well as the other
concrete implementations—support all of the operations. The design does
provide a “back door” if you want to create a new Collection
without providing meaningful definitions for all the methods in the
Collection interface, and yet still fit it into the existing
library.
- When an
operation is unsupported, there should be reasonable likelihood that an
UnsupportedOperationException will appear at implementation time, rather
than after you’ve shipped the product to the customer. After all, it
indicates a programming error: you’ve used an implementation incorrectly.
This point is less certain, and is where the experimental nature of this design
comes into play. Only over time will we find out how well it
works.
|
 |
- Une UnsupportedOperationException doit être un événement
rare. C'est à dire que toutes les opérations doivent être supportées dans la majorité des classes,
et seuls quelques rares cas spéciaux peuvent ne pas supporter une certaine opération. Ceci est vrai
dans la bibliothèque de conteneurs Java, puisque les classes que vous utiliserez dans 99 pour cent
des cas - ArrayList, LinkedList, HashSet et
HashMap, de même que les autres implémentations concrètes - supportent toutes les
opérations. Cette conception fournit une « porte dérobée » si on veut créer une nouvelle
Collection sans fournir de définition sensée pour toutes les méthodes de
l'interface Collection, et s'intégrer tout de même dans la
bibliothèque.
- Quand une opération n'est pas supportée, il faut une probabilité
raisonnable qu'une UnsupportedOperationException apparaisse lors de
l'implémentation plutôt qu'une fois le produit livré au client. Après tout, elle indique une erreur
de programmation : une implémentation a été utilisée de manière incorrecte. Ce point est moins
certain, et c'est là où la nature expérimentale de cette conception entre en jeu. Nous ne nous
apercevrons de son intérêt qu'avec le temps.
|
 |
 |
 |
In the example above,
Arrays.asList( ) produces a List that
is backed by a fixed-size array. Therefore it makes sense that the only
supported operations are the ones that don’t change the size of the array.
If, on the other hand, a new interface were required to express this
different kind of behavior (called, perhaps,
“FixedSizeList”), it would throw open the door to complexity
and soon you wouldn’t know where to start when trying to use the
library.
|
 |
Dans l'exemple précédent, Arrays.asList() produit une
List supportée par un tableau de taille fixe. Il est donc sensé que les seules
opérations supportées soient celles qui ne changent pas la taille du tableau. D'un autre côté, si
une nouvelle interface était requise pour exprimer ce différent type de
comportement (peut-être appelée « FixedSizeList »), cela laisserait la porte
ouverte à la complexité et bientôt on ne saurait où donner de la tête lorsqu'on voudrait utiliser
la bibliothèque.
|
 |
 |
 |
The documentation for a method that takes
a Collection, List, Set, or Map as an argument
should specify which of the optional methods must be implemented. For example,
sorting requires the set( ) and Iterator.set( ) methods,
but not add( ) and remove( ).
|
 |
La documentation d'une méthode qui accepte une Collection,
une List, un Set ou une Map en argument doit
spécifier quelles méthodes optionnelles doivent être implémentées. Par exemple, trier requiert les
méthodes set() et Iterator.set(), mais pas add()
ou remove().
|
 |
 |
 |
Java 1.0/1.1 containers
|
 |
Les conteneurs Java 1.0 / 1.1
|
 |
 |
 |
Unfortunately, a lot of code was written
using the Java 1.0/1.1 containers, and even new code is sometimes written using
these classes. So although you should never use the old containers when writing
new code, you’ll still need to be aware of them. However, the old
containers were quite limited, so there’s not that much to say about them.
(Since they are in the past, I will try to refrain from overemphasizing some of
the hideous design
decisions.)
|
 |
Malheureusement, beaucoup de code a été écrit en utilisant les conteneurs
Java 1.0 / 1.1, et ajourd'hui encore ces classes continuent d'être utilisées dans du nouveau code.
Bien qu'il faille éviter d'utiliser les anciens conteneurs lorsqu'on produit du code nouveau, il
faut toutefois être conscient qu'ils existent. Cependant, les anciens conteneurs étaient plutôt
limités, il n'y a donc pas tellement à en dire sur eux (puisqu'ils appartiennent au passé,
j'éviterais de trop me pencher sur certaines horribles décisions de conception).
|
 |
 |
 |
Vector & Enumeration
|
 |
Vector & Enumeration
|
 |
 |
 |
The only self-expanding sequence in Java
1.0/1.1 was the Vector, and so it saw a lot of
use. Its flaws are too numerous to describe here (see the first edition of this
book, available on this book’s CD ROM and as a free download from
www.BruceEckel.com). Basically, you can think of it as an
ArrayList with long, awkward method names. In the Java 2 container
library, Vector was adapted so that it could fit as a Collection
and a List, so in the following example the
Collections2.fill( ) method is successfully used. This turns out to
be a bit perverse, as it may confuse some people into thinking that
Vector has gotten better, when it is actually included only to support
pre-Java 2 code.
|
 |
Le Vector était la seule séquence
auto-redimensionnable dans Java 1.0 / 1.1, ce qui favorisa son utilisation. Ses défauts sont trop
nombreux pour être décrits ici (se référer à la première version de ce livre, disponible sur le CD
ROM de ce livre et téléchargeable sur www.BruceEckel.com). Fondamentalement, il s'agit
d'une ArrayList avec des noms de méthodes longs et maladroits. Dans la
bibliothèque de conteneurs Java 2, la classe Vector a été adaptée afin de pouvoir
s'intégrer comme une Collection et une List, et donc dans
l'exemple suivant la méthode Collections2.fill() est utilisée avec succès. Ceci
peut mener à des effets pervers, car on pourrait croire que la classe Vector a été
améliorée alors qu'elle n'a été incluse que pour supporter du code pré-Java2.
|
 |
 |
 |
The Java 1.0/1.1 version of the iterator
chose to invent a new name, “enumeration,” instead of using a term
that everyone was already familiar with. The
Enumeration interface is smaller than
Iterator, with only two methods, and it uses longer method names:
boolean hasMoreElements( ) produces true if this
enumeration contains more elements, and Object nextElement( )
returns the next element of this enumeration if there are any more
(otherwise it throws an exception).
|
 |
La version Java 1.0 / 1.1 de l'itérateur a choisi d'inventer un nouveau
nom, « énumération », au lieu d'utiliser un terme déjà familier pour tout le monde.
L'interface Enumeration est plus petite qu'Iterator, ne
possédant que deux méthodes, et utilise des noms de méthodes plus longs : boolean
hasMoreElements() renvoie true si l'énumération contient encore des
éléments, et Object nextElement() renvoie l'élément suivant de cette énumération
si il y en a encore (autrement elle génére une exception).
|
 |
 |
 |
Enumeration is only an interface,
not an implementation, and even new libraries sometimes still use the old
Enumeration—which is unfortunate but generally harmless. Even
though you should always use Iterator when you can in your own code, you
must be prepared for libraries that want to hand you an
Enumeration.
|
 |
Enumeration n'est qu'une interface, et non une
implémentation, et même les nouvelles bibliothèques utilisent encore quelquefois l'ancienne
Enumeration - ce qui est malheureux mais généralement sans conséquence. Bien qu'il
faille utiliser un Iterator quand on le peut, on peut encore rencontrer des
bibliothèques qui renvoient des Enumerations.
|
 |
 |
 |
In addition, you
can produce an Enumeration for any Collection by using the
Collections.enumeration( ) method, as seen in this
example:
|
 |
Toute Collection peut produire une
Enumeration via la méthode Collections.enumerations(), comme le
montre cet exemple :
|
 |
 |
 |
//: c09:Enumerations.java // Java 1.0/1.1 Vector and Enumeration. import java.util.*; import com.bruceeckel.util.*;
class Enumerations { public static void main(String[] args) { Vector v = new Vector(); Collections2.fill( v, Collections2.countries, 100); Enumeration e = v.elements(); while(e.hasMoreElements()) System.out.println(e.nextElement()); // Produce an Enumeration from a Collection: e = Collections.enumeration(new ArrayList()); } } ///:~
|
 |
//: c09:Enumerations.java // Vectors et Enumerations de Java 1.0 / 1.1. import java.util.*; import com.bruceeckel.util.*;
class Enumerations { public static void main(String[] args) { Vector v = new Vector(); Collections2.fill( v, Collections2.countries, 100); Enumeration e = v.elements(); while(e.hasMoreElements()) System.out.println(e.nextElement()); // Produit une Enumeration à partir d'une Collection: e = Collections.enumeration(new ArrayList()); } } ///:~
|
 |
 |
 |
The Java 1.0/1.1 Vector has only
an addElement( ) method, but fill( ) uses the
add( ) method that was pasted on as Vector was turned into a
List. To produce an Enumeration, you call elements( ),
then you can use it to perform a forward iteration.
|
 |
La classe Vector de Java 1.0 / 1.1 ne dispose que d'une
méthode addElement(), mais fill() utilise la méthode
add() qui a été copiée quand Vector a été transformé en
List. Pour produire une Enumeration, il faut appeler
elements(), on peut alors l'utiliser pour réaliser une itération en
avant.
|
 |
 |
 |
The last line creates an ArrayList
and uses enumeration( ) to adapt an Enumeration from the
ArrayList Iterator. Thus, if you have old code that wants an
Enumeration, you can still use the new
containers.
|
 |
La dernière ligne crée une ArrayList et utilise
enumeration() pour adapter une Enumeration à partir de
l'Iterator de l'ArrayList. Ainsi, si on a du vieux code qui
requiert une Enumeration, on peut tout de même utiliser les nouveaux
conteneurs.
|
 |
 |
 |
Hashtable
|
 |
Hashtable
|
 |
 |
 |
As you’ve seen in the performance
comparison in this chapter, the basic Hashtable
is very similar to the HashMap, even down to the method names.
There’s no reason to use Hashtable instead of HashMap in new
code.
|
 |
Comme on a pu le voir dans les tests de performances de ce chapitre,
la Hashtable de base est très similaire au
HashMap, et ce même jusqu'aux noms des méthodes. Il n'y a aucune raison d'utiliser
Hashtable au lieu de HashMap dans du nouveau code.
|
 |
 |
 |
Stack
|
 |
Stack
|
 |
 |
 |
The concept of the stack was introduced
earlier, with the LinkedList. What’s rather odd about the
Java 1.0/1.1 Stack is that instead of using a
Vector as a building block,
Stack is inherited from Vector. So
it has all of the characteristics and behaviors of a Vector plus some
extra Stack behaviors. It’s difficult to know whether the designers
explicitly decided that this was an especially useful way of doing things, or
whether it was just a naive design.
|
 |
Le concept de la pile a déjà été introduit plus tôt avec les
LinkedLists. Ce qui est relativement étrange à propos de la
classe Stack Java 1.0 / 1.1 est qu'elle est dérivée de
Vector au lieu d'utiliser un Vector comme composant de base.
Elle possède donc toutes les caractéristiques et comportements d'un Vector en plus
des comportements additionnels d'une Stack. Il est difficile de savoir si les
concepteurs ont choisi délibérément cette approche en la jugeant particulièrement pratique ou si
c'était juste une conception naïve.
|
 |
 |
 |
Here’s a simple demonstration of
Stack that pushes each line from a String array:
|
 |
Voici une simple illustration de Stack qui
« pousse » chaque ligne d'un tableau String :
|
 |
 |
 |
//: c09:Stacks.java // Demonstration of Stack Class. import java.util.*;
public class Stacks { static String[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; public static void main(String[] args) { Stack stk = new Stack(); for(int i = 0; i < months.length; i++) stk.push(months[i] + " "); System.out.println("stk = " + stk); // Treating a stack as a Vector: stk.addElement("The last line"); System.out.println( "element 5 = " + stk.elementAt(5)); System.out.println("popping elements:"); while(!stk.empty()) System.out.println(stk.pop()); } } ///:~
|
 |
//: c09:Stacks.java // Illustration de la classe Stack. import java.util.*;
public class Stacks { static String[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; public static void main(String[] args) { Stack stk = new Stack(); for(int i = 0; i < months.length; i++) stk.push(months[i] + " "); System.out.println("stk = " + stk); // Traiter une pile comme un Vector : stk.addElement("The last line"); System.out.println( "element 5 = " + stk.elementAt(5)); System.out.println("popping elements:"); while(!stk.empty()) System.out.println(stk.pop()); } } ///:~
|
 |
 |
 |
Each line in the months array is
inserted into the Stack with push( ), and later fetched from
the top of the stack with a pop( ). To make a point, Vector
operations are also performed on the Stack object. This is possible
because, by virtue of inheritance, a Stack is a Vector.
Thus, all operations that can be performed on a Vector can also be
performed on a Stack, such as elementAt( ).
|
 |
Chaque ligne du tableau months est insérée dans la
Stack avec push(), et récupérée par la suite au sommet de la pile
avec un pop(). On peut aussi réaliser des opérations de Vector
sur l'objet Stack. Ceci est possible car, de par les propriétés de l'héritage, une
Stack est un Vector. Donc toutes les opérations qui
peuvent être effectuées sur un Vector peuvent aussi être réalisées sur une
Stack, comme elementAt().
|
 |
 |
 |
As mentioned earlier, you should use a
LinkedList when you want stack
behavior.
|
 |
Ainsi que mentionné précédemment, il vaut mieux utiliser une
LinkedList si on souhaite un comportement de pile.
|
 |
 |
 |
BitSet
|
 |
BitSet
|
 |
 |
 |
A BitSet
is used if you want to efficiently store a lot of on-off information. It’s
efficient only from the standpoint of size; if you’re looking for
efficient access, it is slightly slower than using an array of some native
type.
|
 |
Un BitSet est utile si on veut stocker efficacement
un grand nombre d'informations on-off. Cette classe n'est efficace toutefois que sur le plan de la
taille ; si le but recherché est un accès performant, mieux vaut se tourner vers un tableau de
quelque type natif.
|
 |
 |
 |
In addition, the minimum size of the
BitSet is that of a long: 64 bits. This implies that if
you’re storing anything smaller, like 8 bits, a BitSet will be
wasteful; you’re better off creating your own class, or just an array, to
hold your flags if size is an issue.
|
 |
De plus, la taille minimum d'un BitSet est celle d'un
long, soit 64 bits. Ce qui implique que si on stocke n'importe quelle quantité
plus petite, telle que 8 bits, un BitSet introduira du gaspillage ; il
vaudrait donc mieux créer sa propre classe, ou utiliser un tableau, pour stocker les flags si la
taille est un problème.
|
 |
 |
 |
A normal container expands as you add
more elements, and the BitSet does this as well. The following example
shows how the BitSet works:
|
 |
Un conteneur normal se redimensionne si on ajoute de nouveaux éléments, et
un BitSet n'échappe pas à la règle. L'exemple suivant montre comme le
BitSet fonctionne :
|
 |
 |
 |
//: c09:Bits.java // Demonstration of BitSet. import java.util.*;
public class Bits { static void printBitSet(BitSet b) { System.out.println("bits: " + b); String bbits = new String(); for(int j = 0; j < b.size() ; j++) bbits += (b.get(j) ? "1" : "0"); System.out.println("bit pattern: " + bbits); } public static void main(String[] args) { Random rand = new Random(); // Take the LSB of nextInt(): byte bt = (byte)rand.nextInt(); BitSet bb = new BitSet(); for(int i = 7; i >=0; i--) if(((1 << i) & bt) != 0) bb.set(i); else bb.clear(i); System.out.println("byte value: " + bt); printBitSet(bb);
short st = (short)rand.nextInt(); BitSet bs = new BitSet(); for(int i = 15; i >=0; i--) if(((1 << i) & st) != 0) bs.set(i); else bs.clear(i); System.out.println("short value: " + st); printBitSet(bs);
int it = rand.nextInt(); BitSet bi = new BitSet(); for(int i = 31; i >=0; i--) if(((1 << i) & it) != 0) bi.set(i); else bi.clear(i); System.out.println("int value: " + it); printBitSet(bi);
// Test bitsets >= 64 bits: BitSet b127 = new BitSet(); b127.set(127); System.out.println("set bit 127: " + b127); BitSet b255 = new BitSet(65); b255.set(255); System.out.println("set bit 255: " + b255); BitSet b1023 = new BitSet(512); b1023.set(1023); b1023.set(1024); System.out.println("set bit 1023: " + b1023); } } ///:~
|
 |
//: c09:Bits.java // Illustration des BitSets. import java.util.*;
public class Bits { static void printBitSet(BitSet b) { System.out.println("bits: " + b); String bbits = new String(); for(int j = 0; j < b.size() ; j++) bbits += (b.get(j) ? "1" : "0"); System.out.println("bit pattern: " + bbits); } public static void main(String[] args) { Random rand = new Random(); // Récupère les LSB (Less Significant Bits - NdT: bit de poids fort) de nextInt() : byte bt = (byte)rand.nextInt(); BitSet bb = new BitSet(); for(int i = 7; i >=0; i--) if(((1 << i) & bt) != 0) bb.set(i); else bb.clear(i); System.out.println("byte value: " + bt); printBitSet(bb);
short st = (short)rand.nextInt(); BitSet bs = new BitSet(); for(int i = 15; i >=0; i--) if(((1 << i) & st) != 0) bs.set(i); else bs.clear(i); System.out.println("short value: " + st); printBitSet(bs);
int it = rand.nextInt(); BitSet bi = new BitSet(); for(int i = 31; i >=0; i--) if(((1 << i) & it) != 0) bi.set(i); else bi.clear(i); System.out.println("int value: " + it); printBitSet(bi);
// Teste les bitsets >= 64 bits: BitSet b127 = new BitSet(); b127.set(127); System.out.println("set bit 127: " + b127); BitSet b255 = new BitSet(65); b255.set(255); System.out.println("set bit 255: " + b255); BitSet b1023 = new BitSet(512); b1023.set(1023); b1023.set(1024); System.out.println("set bit 1023: " + b1023); } } ///:~
|
 |
 |
 |
The random number generator is used to
create a random byte, short, and int, and each one is
transformed into a corresponding bit pattern in a BitSet. This works fine
because a BitSet is 64 bits, so none of these cause it to increase in
size. Then a BitSet of 512 bits is created. The constructor allocates
storage for twice that number of bits. However, you can still set bit 1024 or
greater.
|
 |
Le générateur de nombres aléatoires est utilisé pour générer un
byte, un short et un int au hasard, et chacun
est transformé en motif de bits dans un BitSet. Ceci fonctionne bien puisque la
taille d'un BitSet est de 64 bits, et donc aucune de ces opérations ne nécessite
un changement de taille. Un BitSet de 512 bits est alors créé. Le constructeur
alloue de la place pour deux fois ce nombre de bits. Cependant, on peut tout de même positionner le
bit 1024 ou même au delà.
|
 |
 |
 |
Summary
|
 |
Résumé
|
 |
 |
 |
To review the containers provided in the
standard Java library:
|
 |
Pour résumer les conteneurs fournis dans la bibliothèque standard
Java :
|
 |
 |
 |
- An array associates
numerical indices to objects. It holds objects of a known type so that you
don’t have to cast the result when you’re looking up an object. It
can be multidimensional, and it can hold primitives. However, its size cannot be
changed once you create
it.
- A
Collection holds single elements, while a Map holds associated
pairs.
- Like an
array, a List also associates numerical indices to objects—you can
think of arrays and Lists as ordered containers. The List
automatically resizes itself as you add more elements. But a List can
hold only Object references, so it won’t hold primitives and you
must always cast the result when you pull an Object reference out of a
container.
- Use an
ArrayList if you’re doing a lot of random accesses, and a
LinkedList if you will be doing a lot of insertions and removals in the
middle of the
list.
- The behavior
of queues, deques, and stacks is provided via the
LinkedList.
- A
Map is a way to associate not numbers, but objects with other
objects. The design of a HashMap is focused on rapid access, while a
TreeMap keeps its keys in sorted order, and thus is not as fast as a
HashMap.
- A
Set only accepts one of each type of object. HashSets provide
maximally fast lookups, while TreeSets keep the elements in sorted
order.
- There’s
no need to use the legacy classes Vector, Hashtable and
Stack in new code.
|
 |
- Un tableau associe des indices numériques à des objets. Il stocke des
objets d'un type connu afin de ne pas avoir à transtyper le résultat quand on récupère un objet. Il
peut être multidimensions, et peut stocker des scalaires. Cependant, sa taille ne peut être
modifiée une fois créé.
- Une Collection stocke des éléments, alors qu'une
Map stocke des paires d'éléments associés.
- Comme un tableau, une List associe aussi des indices
numériques à des objets - on peut penser aux tableaux et aux Lists comme à des
conteneurs ordonnés. Une List se redimensionne automatiquement si on y ajoute des
éléments. Mais une List ne peut stocker que des références sur des
Objects, elle ne peut donc stocker des scalaires et il faut toujours transtyper le
résultat quand on récupère une référence sur un Object du conteneur.
- Utiliser une ArrayList si on doit effectuer un grand
nombre d'accès aléatoires, et une LinkedList si on doit réaliser un grand nombre
d'insertions et de suppressions au sein de la liste.
- Le comportement de files, files doubles et piles est fourni via les
LinkedLists.
- Une Map est une façon d'associer non pas des nombres,
mais des objets à d'autres objets. La conception d'un HashMap est
focalisée sur les temps d'accès, tandis qu'un TreeMap garde ses clefs ordonnées,
et n'est donc pas aussi rapide qu'un HashMap.
- Un Set n'accepte qu'une instance de valeur de chaque
objet. Les HashSets fournissent des temps d'accès optimaux, alors que les
TreeSets gardent leurs éléments ordonnés.
- Il n'y a aucune raison d'utiliser les anciennes classes
Vector, Hashtable et Stack dans du nouveau
code.
|
 |
 |
 |
The
containers are tools that you can use on a day-to-day basis to make your
programs simpler, more powerful, and more
effective.
|
 |
Les conteneurs sont des outils qu'on peut utiliser jour après jour pour
rendre les programmes plus simples, plus puissants et plus efficaces.
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |