Bonjour,
J'ai comme exercice à faire l'implémentation d'une classe représentant une "clef". Une clef étant une chaîne de caractères :
- pouvant comporter des espaces et tabulations en début et/ou fin de chaîne
- composées de lettres, chiffres et underscore
Lors de la comparaison de deux clefs, on ne doit pas tenir compte ni des espaces, ni des tabulations, ni de la casse
Également, on doit conserver (et pouvoir retourner) la valeur initiale de la clef
Ci-dessous la classe telle que je l'ai implémentée :
Questions :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 package Config; public class Key implements Comparable<Key> { private String _value; public String getValue() { return this._value; } private void setValue( String value ) { this._value = value; } public int compareTo(Key ck) { return this._value.trim().toUpperCase().compareTo(ck.getValue().trim().toUpperCase()); } @Override public boolean equals(Object o) { if( o == this ) return true; if( ! ( o instanceof Key ) ) return false; return 0 == this.compareTo(((Key) o) ); } @Override public int hashCode() { return this._value.trim().toUpperCase().hashCode(); } /** * Constructeur * @param value valeur * @throws Exception si format incorrect */ public Key(String value) throws Exception { if( ! value.matches("^[ \t]*[a-zA-Z0-9_]+[ \t]*$") ) throw new Exception("Clef invalide : [" + value + "]"); this.setValue( value ); } }
- L'EDI m'indique un warning s'agissant de la méthode compareTo() : il me suggère d'ajouter l'annotation @Override, ce qui ne me semble pas pertinent (Object n'implémente pas compareTo(), donc je ne vois pas en quoi il y aurait surcharge)
- S'agissant de la méthode equals(), peut-on passer plutôt un argument de type Key ?
- L'interface Comparable<T> m'oblige à redéfinir compareTo() : existe-t-il une interface obligeant à redéfinir equals() et hashCode() ? Également, quand est-il nécessaire de redéfinir ces deux méthodes ? Si je commente compareTo() et/ou equals() et/ou hashCode() et que j'utilise mon petit programme de test fourni en fin de post, j'arrive aux conclusions suivantes : ArrayList.sort() utilise compareTo(), ArraySort.contains() se base plutôt sur equals()… Finalement, je peux toujours implémenter systématiquement les 3 fonctions, et c'est sans doute une bonne pratique, mais pour ma culture j'aimerais savoir quand l'une ou l'autre est utilisée ? Peut-être existe-t-il une interface imposant de redéfinir le package des 3 fonctions ?
- Au niveau de mon programme de test, si je remplace if( 0 == arrKey.get(i).compareTo(arrKey.get(j)) ) par if( arrKey.get(i) == arrKey.get(j) ) : ça compile, mais à l'exécution c'est tout faux : aucune égalité dans les clefs : sans doute parce qu'il y a comparaison de "pointeurs" ? Pour que ça fonctionne, il faudrait en plus une surcharge de l'opérateur "==" comme en C# ?
- Globalement, que pensez-vous du code de la classe Key ? Ai-je loupé quelque chose qui aurait rendu ce code plus fiable / élégant / … ?
D'avance merci pour vos remarques bienvenues.
Petit programme de test :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 package testkey; import java.util.*; import Config.Key; public class TestKey { public static void main(String[] args) throws Exception { ArrayList<Key> arrKey = new ArrayList<Key>(); final String[] arrStr = { "CLEF_1", "\tCLEF_2", "CLEF_3\t", "Clé incorrecte", "\t\t\tclef_1", " ClEf_2\t\t\t", " \t cLeF_3\t \t" }; for(String str : arrStr ) { System.out.print("Test chaine \"" + str + "\" : "); try { arrKey.add( new Key( str ) ); System.out.println("est une clef valide"); } catch( Exception e ) { System.out.println("n'est PAS une clef valide : " + e.toString() ); } } System.out.println( "--- COMPARAISON ---" ); for( int i=0; i<arrKey.size(); i++ ) { System.out.println( "Clé(s) égale(s) à \"" + arrKey.get(i).getValue() + "\""); for( int j=0; j<arrKey.size(); j++ ) { if( i == j ) continue; if( 0 == arrKey.get(i).compareTo(arrKey.get(j)) ) { System.out.println("\t\t >>> \"" + arrKey.get(j).getValue() + "\""); } } } System.out.println( "--- TRI ---" ); arrKey.sort(null); for( Key k : arrKey ) { System.out.println( k.getValue() ); } Key keyTestContains = new Key( "\t\t\t\tCLef_2 "); System.out.print( "*** Test contains : " ); System.out.println( arrKey.contains( keyTestContains ) ? "OK" : "pas ok..." ); } }
Partager