 |
 |
9) Stockage des objets |
|
 |
|
Texte original |
 |
Traducteur :
Jérome Quelin |
|
 |
|
 |
 |
 |
 |
 |
 |
|
 |
|
 |
 |
 |
The size parameter has a default
value, but you can also set it from the command
line.
|
 |
Le paramètre size a une valeur par défaut, mais il est
possible de le fixer depuis la ligne de commande.
|
 |
 |
 |
Filling an array
|
 |
Remplir un tableau
|
 |
 |
 |
The Java standard library Arrays
also has a fill( ) method, but that is rather trivial—it only
duplicates a single value into each location, or in the case of objects, copies
the same reference into each location. Using Arrays2.print( ), the
Arrays.fill( ) methods can be easily
demonstrated:
|
 |
La bibliothèque standard Java Arrays propose aussi une
méthode fill(), mais celle-ci est relativement triviale : elle ne fait que
dupliquer une certaine valeur dans chaque cellule, ou dans le cas d'objets, copier la même
référence dans chaque cellule. En utilisant Arrays2.print(), les
méthodes Arrays.fill() peuvent être facilement illustrées :
|
 |
 |
 |
//: c09:FillingArrays.java
// Using Arrays.fill()
import com.bruceeckel.util.*;
import java.util.*;
public class FillingArrays {
public static void main(String[] args) {
int size = 6;
// Or get the size from the command line:
if(args.length != 0)
size = Integer.parseInt(args[0]);
boolean[] a1 = new boolean[size];
byte[] a2 = new byte[size];
char[] a3 = new char[size];
short[] a4 = new short[size];
int[] a5 = new int[size];
long[] a6 = new long[size];
float[] a7 = new float[size];
double[] a8 = new double[size];
String[] a9 = new String[size];
Arrays.fill(a1, true);
Arrays2.print("a1 = ", a1);
Arrays.fill(a2, (byte)11);
Arrays2.print("a2 = ", a2);
Arrays.fill(a3, 'x');
Arrays2.print("a3 = ", a3);
Arrays.fill(a4, (short)17);
Arrays2.print("a4 = ", a4);
Arrays.fill(a5, 19);
Arrays2.print("a5 = ", a5);
Arrays.fill(a6, 23);
Arrays2.print("a6 = ", a6);
Arrays.fill(a7, 29);
Arrays2.print("a7 = ", a7);
Arrays.fill(a8, 47);
Arrays2.print("a8 = ", a8);
Arrays.fill(a9, "Hello");
Arrays2.print("a9 = ", a9);
// Manipulating ranges:
Arrays.fill(a9, 3, 5, "World");
Arrays2.print("a9 = ", a9);
}
} ///:~
|
 |
//: c09:FillingArrays.java // Utilisation de Arrays.fill() import com.bruceeckel.util.*; import java.util.*;
public class FillingArrays { public static void main(String[] args) { int size = 6; // Ou récupère la taille depuis la ligne de commande : if(args.length != 0) size = Integer.parseInt(args[0]); boolean[] a1 = new boolean[size]; byte[] a2 = new byte[size]; char[] a3 = new char[size]; short[] a4 = new short[size]; int[] a5 = new int[size]; long[] a6 = new long[size]; float[] a7 = new float[size]; double[] a8 = new double[size]; String[] a9 = new String[size]; Arrays.fill(a1, true); Arrays2.print("a1 = ", a1); Arrays.fill(a2, (byte)11); Arrays2.print("a2 = ", a2); Arrays.fill(a3, 'x'); Arrays2.print("a3 = ", a3); Arrays.fill(a4, (short)17); Arrays2.print("a4 = ", a4); Arrays.fill(a5, 19); Arrays2.print("a5 = ", a5); Arrays.fill(a6, 23); Arrays2.print("a6 = ", a6); Arrays.fill(a7, 29); Arrays2.print("a7 = ", a7); Arrays.fill(a8, 47); Arrays2.print("a8 = ", a8); Arrays.fill(a9, "Hello"); Arrays2.print("a9 = ", a9); // Manipulation de plages d'index : Arrays.fill(a9, 3, 5, "World"); Arrays2.print("a9 = ", a9); } } ///:~
|
 |
 |
 |
You can either fill the entire array,
or—as the last two statements show—a range of elements. But since
you can only provide a single value to use for filling using
Arrays.fill( ), the Arrays2.fill( ) methods produce much
more interesting results.
|
 |
On peut soit remplir un tableau complètement, soit - comme le montrent les
deux dernières instructions - une certaine plage d'indices. Mais comme il n'est possible de ne
fournir qu'une seule valeur pour le remplissage dans Arrays.fill(), les méthodes
Arrays2.fill() sont bien plus intéressantes.
|
 |
 |
 |
Copying an array
|
 |
Copier un tableau
|
 |
 |
 |
The Java standard library provides a
static method, System.arraycopy( ),
which can make much faster copies of an array than if you use a for loop
to perform the copy by hand. System.arraycopy( ) is overloaded to
handle all types. Here’s an example that manipulates arrays of
int:
|
 |
La bibliothèque standard Java propose une méthode
static, System.arraycopy(), qui réalise des copies de
tableau bien plus rapidement qu'une boucle for.
System.arraycopy() est surchargée afin de gérer tous les types. Voici un exemple
qui manipule des tableaux d'int :
|
 |
 |
 |
//: c09:CopyingArrays.java
// Using System.arraycopy()
import com.bruceeckel.util.*;
import java.util.*;
public class CopyingArrays {
public static void main(String[] args) {
int[] i = new int[25];
int[] j = new int[25];
Arrays.fill(i, 47);
Arrays.fill(j, 99);
Arrays2.print("i = ", i);
Arrays2.print("j = ", j);
System.arraycopy(i, 0, j, 0, i.length);
Arrays2.print("j = ", j);
int[] k = new int[10];
Arrays.fill(k, 103);
System.arraycopy(i, 0, k, 0, k.length);
Arrays2.print("k = ", k);
Arrays.fill(k, 103);
System.arraycopy(k, 0, i, 0, k.length);
Arrays2.print("i = ", i);
// Objects:
Integer[] u = new Integer[10];
Integer[] v = new Integer[5];
Arrays.fill(u, new Integer(47));
Arrays.fill(v, new Integer(99));
Arrays2.print("u = ", u);
Arrays2.print("v = ", v);
System.arraycopy(v, 0,
u, u.length/2, v.length);
Arrays2.print("u = ", u);
}
} ///:~
|
 |
//: c09:CopyingArrays.java // Utilisation de System.arraycopy() import com.bruceeckel.util.*; import java.util.*;
public class CopyingArrays { public static void main(String[] args) { int[] i = new int[25]; int[] j = new int[25]; Arrays.fill(i, 47); Arrays.fill(j, 99); Arrays2.print("i = ", i); Arrays2.print("j = ", j); System.arraycopy(i, 0, j, 0, i.length); Arrays2.print("j = ", j); int[] k = new int[10]; Arrays.fill(k, 103); System.arraycopy(i, 0, k, 0, k.length); Arrays2.print("k = ", k); Arrays.fill(k, 103); System.arraycopy(k, 0, i, 0, k.length); Arrays2.print("i = ", i); // Objects : Integer[] u = new Integer[10]; Integer[] v = new Integer[5]; Arrays.fill(u, new Integer(47)); Arrays.fill(v, new Integer(99)); Arrays2.print("u = ", u); Arrays2.print("v = ", v); System.arraycopy(v, 0, u, u.length/2, v.length); Arrays2.print("u = ", u); } } ///:~
|
 |
 |
 |
The arguments to arraycopy( )
are the source array, the offset into the source array from whence to start
copying, the destination array, the offset into the destination array where the
copying begins, and the number of elements to copy. Naturally, any violation of
the array boundaries will cause an exception.
|
 |
arraycopy() accepte comme arguments le tableau source, le
déplacement dans le tableau source à partir duquel démarrer la copie, le tableau destination, le
déplacement dans le tableau destination à partir duquel démarrer la copie, et le nombre d'éléments
à copier. Bien entendu, toute violation des frontières du tableau générera une
exception.
|
 |
 |
 |
The example shows that both primitive
arrays and object arrays can be copied. However, if you copy arrays of objects
then only the references get copied—there’s no duplication of the
objects themselves. This is called a shallow copy (see Appendix
A).
|
 |
L'exemple montre bien qu'on peut copier des tableaux de scalaires comme des
tableaux d'objets. Cependant, dans le cas de la copie de tableaux d'objets, seules les références
sont copiées - il n'y a pas duplication des objets eux-mêmes. C'est ce qu'on appelle une copie
superficielle (voir l'Annexe A).
|
 |
 |
 |
Comparing arrays
|
 |
Comparer des tableaux
|
 |
 |
 |
Arrays provides the overloaded
method equals( ) to compare entire arrays for equality. Again, these
are overloaded for all the primitives, and for Object. To be equal, the
arrays must have the same number of elements and each element must be equivalent
to each corresponding element in the other array, using the equals( )
for each element. (For primitives, that primitive’s wrapper class
equals( ) is used; for example, Integer.equals( ) for
int.) Here’s an example:
|
 |
Arrays fournit la méthode surchargée
equals() pour comparer des tableaux entiers. Encore une fois, ces méthodes sont
surchargées pour chacun des types de base, ainsi que pour les Objects. Pour être
égaux, les tableaux doivent avoir la même taille et chaque élément doit être équivalent (au sens de
la méthode equals()) à l'élément correspondant dans l'autre tableau (pour les
types scalaires, la méthode equals() de la classe d'encapsulation du type concerné
est utilisé ; par exemple, Integer.equals() est utilisé pour les
int). Voici un exemple :
|
 |
 |
 |
//: c09:ComparingArrays.java
// Using Arrays.equals()
import java.util.*;
public class ComparingArrays {
public static void main(String[] args) {
int[] a1 = new int[10];
int[] a2 = new int[10];
Arrays.fill(a1, 47);
Arrays.fill(a2, 47);
System.out.println(Arrays.equals(a1, a2));
a2[3] = 11;
System.out.println(Arrays.equals(a1, a2));
String[] s1 = new String[5];
Arrays.fill(s1, "Hi");
String[] s2 = {"Hi", "Hi", "Hi", "Hi", "Hi"};
System.out.println(Arrays.equals(s1, s2));
}
} ///:~
|
 |
//: c09:ComparingArrays.java // Utilisation de Arrays.equals() import java.util.*;
public class ComparingArrays { public static void main(String[] args) { int[] a1 = new int[10]; int[] a2 = new int[10]; Arrays.fill(a1, 47); Arrays.fill(a2, 47); System.out.println(Arrays.equals(a1, a2)); a2[3] = 11; System.out.println(Arrays.equals(a1, a2)); String[] s1 = new String[5]; Arrays.fill(s1, "Hi"); String[] s2 = {"Hi", "Hi", "Hi", "Hi", "Hi"}; System.out.println(Arrays.equals(s1, s2)); } } ///:~
|
 |
 |
 |
Originally, a1 and a2 are
exactly equal, so the output is “true,” but then one of the elements
is changed so the second line of output is “false.” In the last
case, all the elements of s1 point to the same object, but s2 has
five unique objects. However, array equality is based on contents (via
Object.equals( )) and so the result is
“true.”
|
 |
Au début du programme, a1 et a2 sont
identiques, donc le résultat est « true » ; puis l'un des éléments est changé donc
la deuxième ligne affichée est « false ». Dans le dernier cas, tous les éléments de
s1 pointent sur le même objet, alors que s2 contient cinq objets
différents. Cependant, l'égalité de tableaux est basée sur le contenu (via
Object.equals()) et donc le résultat est « true ».
|
 |
 |
 |
Array element comparisons
|
 |
Comparaison d'éléments de tableau
|
 |
 |
 |
One of the missing features in the Java
1.0 and 1.1 libraries is algorithmic operations—even simple
sorting. This was a rather confusing situation to someone
expecting an adequate standard library. Fortunately, Java 2 remedies the
situation, at least for the sorting problem.
|
 |
L'une des fonctionnalités manquantes dans les bibliothèques Java 1.0 et 1.1
sont les opérations algorithmiques - y compris les simples tris. Ceci était relativement
frustrant pour quiconque s'attendait à une bibliothèque standard conséquente. Heureusement, Java 2
a corrigé cette situation, au moins pour le problème du tri.
|
 |
 |
 |
A problem with writing generic sorting
code is that sorting must perform comparisons based on the actual type of the
object. Of course, one approach is to write a different sorting method for every
different type, but you should be able to recognize that this does not produce
code that is easily reused for new types.
|
 |
Le problème posé par l'écriture d'une méthode de tri générique est que le
tri doit réaliser des comparaisons basées sur le type réel de l'objet. Bien sûr, l'une des
approches consiste à écrire une méthode de tri différente pour chaque type, mais cela va à
l'encontre du principe de réutilisabilité du code pour les nouveaux types.
|
 |
 |
 |
A primary goal of programming design is
to “separate things that change from things that stay the same,” and
here, the code that stays the same is the general sort algorithm, but the thing
that changes from one use to the next is the way objects are compared. So
instead of hard-wiring the comparison code into many different sort routines,
the technique of the callback is used. With a
callback, the part of the code that varies from case to case is encapsulated
inside its own class, and the part of the code that’s always the same will
call back to the code that changes. That way you can make different objects to
express different ways of comparison and feed them to the same sorting
code.
|
 |
L'un des buts principaux de la conception est de « séparer les choses
qui changent de celles qui ne bougent pas » ; ici, le code qui reste le même est
l'algorithme général de tri, alors que la manière de comparer les objets entre eux est ce qui
change d'un cas d'utilisation à l'autre. Donc au lieu de coder en dur le code de comparaison dans
différentes procédures de tri, on utilise ici la technique des callbacks. Avec un callback, la partie du code qui varie d'un cas à l'autre
est encapsulé dans sa propre classe, et la partie du code qui ne change pas appellera ce code pour
réaliser les comparaisons. De cette manière, il est possible de créer différents objets pour
exprimer différentes sortes de comparaisons et de les passer au même code de tri.
|
 |
 |
 |
In Java 2, there are two ways to provide
comparison functionality. The first is with the natural comparison method
that is imparted to a class by implementing the java.lang.Comparable
interface. This is a very simple interface with a single method,
compareTo( ). This method takes another
Object as an argument, and produces a negative value if the argument is
less than the current object, zero if the argument is equal, and a positive
value if the argument is greater than the current object.
|
 |
Dans Java 2, il existe deux manières de fournir des fonctionnalités de
comparaison. La méthode naturelle de comparaison constitue la première, elle est annoncée
dans une classe en implémentant l'interface java.lang.Comparable. C'est une
interface très simple ne disposant que d'une seule méthode, compareTo().
Cette méthode accepte un autre Object comme argument, et renvoie une valeur
négative si l'argument est plus grand que l'objet courant, zéro si ils sont égaux, ou une valeur
positive si l'argument est plus petit que l'objet courant.
|
 |
 |
 |
Here’s a class that implements
Comparable and demonstrates the comparability by
using the Java standard library method
Arrays.sort( ):
|
 |
Voici une classe qui implémente Comparable et
illustre la comparaison en utilisant la méthode Arrays.sort() de la bibliothèque
standard Java :
|
 |
 |
 |
//: c09:CompType.java
// Implementing Comparable in a class.
import com.bruceeckel.util.*;
import java.util.*;
public class CompType implements Comparable {
int i;
int j;
public CompType(int n1, int n2) {
i = n1;
j = n2;
}
public String toString() {
return "[i = " + i + ", j = " + j + "]";
}
public int compareTo(Object rv) {
int rvi = ((CompType)rv).i;
return (i < rvi ? -1 : (i == rvi ? 0 : 1));
}
private static Random r = new Random();
private static int randInt() {
return Math.abs(r.nextInt()) % 100;
}
public static Generator generator() {
return new Generator() {
public Object next() {
return new CompType(randInt(),randInt());
}
};
}
public static void main(String[] args) {
CompType[] a = new CompType[10];
Arrays2.fill(a, generator());
Arrays2.print("before sorting, a = ", a);
Arrays.sort(a);
Arrays2.print("after sorting, a = ", a);
}
} ///:~
|
 |
//: c09:CompType.java // Implémenter Comparable dans une classe. import com.bruceeckel.util.*; import java.util.*;
public class CompType implements Comparable { int i; int j; public CompType(int n1, int n2) { i = n1; j = n2; } public String toString() { return "[i = " + i + ", j = " + j + "]"; } public int compareTo(Object rv) { int rvi = ((CompType)rv).i; return (i < rvi ? -1 : (i == rvi ? 0 : 1)); } private static Random r = new Random(); private static int randInt() { return Math.abs(r.nextInt()) % 100; } public static Generator generator() { return new Generator() { public Object next() { return new CompType(randInt(),randInt()); } }; } public static void main(String[] args) { CompType[] a = new CompType[10]; Arrays2.fill(a, generator()); Arrays2.print("before sorting, a = ", a); Arrays.sort(a); Arrays2.print("after sorting, a = ", a); } } ///:~
|
 |
 |
 |
When you define the comparison function,
you are responsible for deciding what it means to compare one of your objects to
another. Here, only the i values are used in the comparison, and the
j values are ignored.
|
 |
Lorsque la fonction de comparaison est définie, il vous incombe de décider
du sens à donner à la comparaison entre deux objets. Ici, seules les valeurs i
sont utilisées dans la comparaison, les valeurs j sont ignorées.
|
 |
 |
 |
The static randInt( ) method
produces positive values between zero and 100, and the generator( )
method produces an object that implements the Generator interface, by
creating an anonymous inner class (see Chapter 8). This builds CompType
objects by initializing them with random values. In main( ), the
generator is used to fill an array of CompType, which is then sorted. If
Comparable hadn’t been implemented, then you’d get a
compile-time error message when you tried to call
sort( ).
|
 |
La méthode static randInt() produit des valeurs positives
entre zéro et 100, et la méthode generator() produit un objet implémentant
l'interface Generator, en créant une classe interne anonyme (cf. Chapitre 8).
Celui-ci génére des objets CompType en les initialisant avec des valeurs
aléatoires. Dans main(), le générateur est utilisé pour remplir un tableau de
CompType, qui est alors trié. Si Comparable n'avait pas été
implémentée, une erreur de compilation aurait été générée lors d'un appel à
sort().
|
 |
 |
 |
Now suppose someone hands you a class
that doesn’t implement Comparable, or they hand you this class that
does implement Comparable, but you decide you don’t like the
way it works and would rather have a different comparison function for the type.
To do this, you use the second approach for comparing objects, by creating a
separate class that implements an interface called
Comparator. This has two methods,
compare( ) and equals( ). However, you don’t have
to implement equals( ) except for special performance needs, because
anytime you create a class it is implicitly inherited from Object, which
has an equals( ). So you can just use the default Object
equals( ) and satisfy the contract imposed by the
interface.
|
 |
Dans le cas où une classe n'implémente pas Comparable, ou
qu'elle l'implémente d'une manière qui ne vous satisfait pas (c'est à dire que vous souhaitez une
autre fonction de comparaison pour ce type), il faut utiliser une autre approche pour comparer des
objets. Cette approche nécessite de créer une classe séparée qui implémente
l'interface Comparator, comportant les deux méthodes
compare() et equals(). Cependant, sauf cas particuliers (pour des
raisons de performance notamment), il n'est pas nécessaire d'implémenter equals()
car chaque classe dérive implicitement de Object, qui fournit déjà cette méthode.
On peut donc se contenter de la méthode Object.equals() pour satisfaire au contrat
imposé par l'interface.
|
 |
 |
 |
The Collections class (which
we’ll look at more later) contains a single Comparator that
reverses the natural sorting order. This can easily be applied to the
CompType:
|
 |
La classe Collections (que nous étudierons plus en détails
par la suite) dispose d'un Comparator qui inverse l'ordre de tri. Ceci peut
facilement être appliqué à CompType :
|
 |
 |
 |
//: c09:Reverse.java
// The Collecions.reverseOrder() Comparator.
import com.bruceeckel.util.*;
import java.util.*;
public class Reverse {
public static void main(String[] args) {
CompType[] a = new CompType[10];
Arrays2.fill(a, CompType.generator());
Arrays2.print("before sorting, a = ", a);
Arrays.sort(a, Collections.reverseOrder());
Arrays2.print("after sorting, a = ", a);
}
} ///:~
|
 |
//: c09:Reverse.java // Le Comparator Collecions.reverseOrder(). import com.bruceeckel.util.*; import java.util.*;
public class Reverse { public static void main(String[] args) { CompType[] a = new CompType[10]; Arrays2.fill(a, CompType.generator()); Arrays2.print("before sorting, a = ", a); Arrays.sort(a, Collections.reverseOrder()); Arrays2.print("after sorting, a = ", a); } } ///:~
|
 |
 |
 |
The call to
Collections.reverseOrder( ) produces the reference to the
Comparator.
|
 |
L'appel à Collections.reverseOrder() produit une référence
sur le Comparator.
|
 |
 |
 |
As a second example, the following
Comparator compares CompType objects based on their j
values rather than their i values:
|
 |
Voici un deuxième exemple dans lequel un Comparator
compare des objets CompType en se basant cette fois sur la valeur de leur
j plutôt que sur celle de i :
|
 |
 |
 |
//: c09:ComparatorTest.java
// Implementing a Comparator for a class.
import com.bruceeckel.util.*;
import java.util.*;
class CompTypeComparator implements Comparator {
public int compare(Object o1, Object o2) {
int j1 = ((CompType)o1).j;
int j2 = ((CompType)o2).j;
return (j1 < j2 ? -1 : (j1 == j2 ? 0 : 1));
}
}
public class ComparatorTest {
public static void main(String[] args) {
CompType[] a = new CompType[10];
Arrays2.fill(a, CompType.generator());
Arrays2.print("before sorting, a = ", a);
Arrays.sort(a, new CompTypeComparator());
Arrays2.print("after sorting, a = ", a);
}
} ///:~
|
 |
//: c09:ComparatorTest.java // Implémenter un Comparator pour une classe. import com.bruceeckel.util.*; import java.util.*;
class CompTypeComparator implements Comparator { public int compare(Object o1, Object o2) { int j1 = ((CompType)o1).j; int j2 = ((CompType)o2).j; return (j1 < j2 ? -1 : (j1 == j2 ? 0 : 1)); } } public class ComparatorTest { public static void main(String[] args) { CompType[] a = new CompType[10]; Arrays2.fill(a, CompType.generator()); Arrays2.print("before sorting, a = ", a); Arrays.sort(a, new CompTypeComparator()); Arrays2.print("after sorting, a = ", a); } } ///:~
|
 |
 |
 |
The compare( ) method must
return a negative integer, zero, or a positive integer if the first argument is
less than, equal to, or greater than the second,
respectively.
|
 |
La méthode compare() doit renvoyer un entier négatif, zéro
ou un entier positif selon que le premier argument est respectivement plus petit, égal ou plus
grand que le second.
|
 |
 |
 |
Sorting an array
|
 |
Trier un tableau
|
 |
 |
 |
With the built-in sorting methods, you
can sort any array of primitives, and any array of objects that either
implements Comparable or has an associated Comparator. This fills
a big hole in the Java libraries—believe it or not, there was no support
in Java 1.0 or 1.1 for sorting Strings! Here’s an example that
generates random String objects and sorts them:
|
 |
Avec les méthodes de tri intégrées, il est maintenant possible de trier
n'importe quel tableau de scalaires ou d'objets implémentant Comparable ou
disposant d'une classe Comparator associée. Ceci comble un énorme trou dans les
bibliothèques de Java - croyez-le ou non, Java 1.0 ou 1.1 ne fournissait aucun moyen de trier des
Strings ! Voici un exemple qui génére des objets String
aléatoirement et les trie :
|
 |
 |
 |
//: c09:StringSorting.java
// Sorting an array of Strings.
import com.bruceeckel.util.*;
import java.util.*;
public class StringSorting {
public static void main(String[] args) {
String[] sa = new String[30];
Arrays2.fill(sa,
new Arrays2.RandStringGenerator(5));
Arrays2.print("Before sorting: ", sa);
Arrays.sort(sa);
Arrays2.print("After sorting: ", sa);
}
} ///:~
|
 |
//: c09:StringSorting.java // Trier un tableau de Strings. import com.bruceeckel.util.*; import java.util.*;
public class StringSorting { public static void main(String[] args) { String[] sa = new String[30]; Arrays2.fill(sa, new Arrays2.RandStringGenerator(5)); Arrays2.print("Before sorting: ", sa); Arrays.sort(sa); Arrays2.print("After sorting: ", sa); } } ///:~
|
 |
 |
 |
One thing you’ll notice about the
output in the String sorting algorithm is that it’s
lexicographic,
so it puts all the words starting with uppercase letters first, followed by all
the words starting with lowercase letters. (Telephone books are typically sorted
this way.) You may also want to group the words together regardless of case, and
you can do this by defining a Comparator class, thereby overriding the
default String Comparable behavior. For reuse, this will be added to the
“util” package:
|
 |
Il est bon de noter que le tri effectué sur les Strings
est lexicographique, c'est à dire que les mots commençant par
des majuscules apparaissent avant ceux débutant par une minuscule (typiquement les annuaires sont
triés de cette façon). Il est toutefois possible de redéfinir ce comportement et d'ignorer la casse
en définissant une classe Comparator. Cette classe sera placée dans le package
« util » à des fins de réutilisation :
|
 |
 |
 |
//: com:bruceeckel:util:AlphabeticComparator.java
// Keeping upper and lowercase letters together.
package com.bruceeckel.util;
import java.util.*;
public class AlphabeticComparator
implements Comparator{
public int compare(Object o1, Object o2) {
String s1 = (String)o1;
String s2 = (String)o2;
return s1.toLowerCase().compareTo(
s2.toLowerCase());
}
} ///:~
|
 |
//: com:bruceeckel:util:AlphabeticComparator.java // Garder les lettres majuscules et minuscules ensemble. package com.bruceeckel.util; import java.util.*;
public class AlphabeticComparator implements Comparator{ public int compare(Object o1, Object o2) { String s1 = (String)o1; String s2 = (String)o2; return s1.toLowerCase().compareTo( s2.toLowerCase()); } } ///:~
|
 |
 |
 |
Each String is converted to
lowercase before the comparison. String’s built-in
compareTo( ) method provides the desired
functionality.
|
 |
Chaque String est convertie en minuscules avant la
comparaison. La méthode compareTo() de String fournit ensuite le
comparateur désiré.
|
 |
 |
 |
Here’s a test using
AlphabeticComparator:
|
 |
Voici un exemple d'utilisation
d'AlphabeticComparator :
|
 |
 |
 |
//: c09:AlphabeticSorting.java
// Keeping upper and lowercase letters together.
import com.bruceeckel.util.*;
import java.util.*;
public class AlphabeticSorting {
public static void main(String[] args) {
String[] sa = new String[30];
Arrays2.fill(sa,
new Arrays2.RandStringGenerator(5));
Arrays2.print("Before sorting: ", sa);
Arrays.sort(sa, new AlphabeticComparator());
Arrays2.print("After sorting: ", sa);
}
} ///:~
|
 |
//: c09:AlphabeticSorting.java // Garder les lettres majuscules et minuscules ensemble. import com.bruceeckel.util.*; import java.util.*;
public class AlphabeticSorting { public static void main(String[] args) { String[] sa = new String[30]; Arrays2.fill(sa, new Arrays2.RandStringGenerator(5)); Arrays2.print("Before sorting: ", sa); Arrays.sort(sa, new AlphabeticComparator()); Arrays2.print("After sorting: ", sa); } } ///:~
|
 |
 |
 |
The sorting algorithm that’s used
in the Java standard library is designed to be optimal for the particular type
you’re sorting—a Quicksort for primitives, and a stable merge sort
for objects. So you shouldn’t need to spend any time worrying about
performance unless your profiling tool points you to the sorting process as a
bottleneck.
|
 |
L'algorithme de tri utilisé dans la bibliothèque standard de Java est conçu
pour être optimal suivant le type d'objets triés : un Quicksort pour les scalaires, et un
tri-fusion stable pour les objets. Vous ne devriez donc pas avoir à vous soucier des performances à
moins qu'un outil de profilage ne vous démontre explicitement que le goulot d'étranglement de votre
programme soit le processus de tri.
|
 |
 |
 |
Searching a sorted array
|
 |
Effectuer une recherche sur un tableau trié
|
 |
 |
 |
Once an array is sorted, you can perform
a fast search for a particular item using
Arrays.binarySearch( ). However, it’s
very important that you do not try to use
binarySearch( ) on an unsorted array; the
results will be unpredictable. The following example uses a
RandIntGenerator to fill an array, then to produces values to search
for:
|
 |
Une fois un tableau trié, il est possible d'effectuer une recherche rapide
sur un item en utilisant Arrays.binarySearch(). Il est toutefois très
important de ne pas utiliser binarySearch() sur un tableau non trié ; le
résultat en serait imprévisible. L'exemple suivant utilise un RandIntGenerator
pour remplir un tableau et produire des valeurs à chercher dans ce tableau :
|
 |
 |
 |
//: c09:ArraySearching.java
// Using Arrays.binarySearch().
import com.bruceeckel.util.*;
import java.util.*;
public class ArraySearching {
public static void main(String[] args) {
int[] a = new int[100];
Arrays2.RandIntGenerator gen =
new Arrays2.RandIntGenerator(1000);
Arrays2.fill(a, gen);
Arrays.sort(a);
Arrays2.print("Sorted array: ", a);
while(true) {
int r = gen.next();
int location = Arrays.binarySearch(a, r);
if(location >= 0) {
System.out.println("Location of " + r +
" is " + location + ", a[" +
location + "] = " + a[location]);
break; // Out of while loop
}
}
}
} ///:~
|
 |
//: c09:ArraySearching.java // Utilisation de Arrays.binarySearch(). import com.bruceeckel.util.*; import java.util.*;
public class ArraySearching { public static void main(String[] args) { int[] a = new int[100]; Arrays2.RandIntGenerator gen = new Arrays2.RandIntGenerator(1000); Arrays2.fill(a, gen); Arrays.sort(a); Arrays2.print("Sorted array: ", a); while(true) { int r = gen.next(); int location = Arrays.binarySearch(a, r); if(location >= 0) { System.out.println("Location of " + r + " is " + location + ", a[" + location + "] = " + a[location]); break; // Sortie de la boucle while } } } } ///:~
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |