Bonjour à tous,

J'ai implémenté une classe Tuple dont l'utilité est de pouvoir rassembler des éléments homogènes dans un conteneur non modifiable qui peut servir de clé à une map.

Il y a une classe abstraite Tuple et deux sous-classes OrderedTuple et UnorderedTuple. Pour ces deux dernières, les éléments en nombre variables sont passés en arguments à l'unique constructeur (par la suite, on ne peut donc les modifier).

J'ai introduit des méthodes hashCode et equals, et cette classe semble fonctionner. Le problème est que je souhaiterais en faire une classe comparable. Pour effectuer la comparaison, on itère sur les éléments du tuple. Il faudrait donc pouvoir comparer ceux-ci, mais c'est là que ça coince, vu que la méthode compareTo n'est pas connue pour le type de ces éléments.

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public abstract class Tuple<K> implements Comparable {
 
  protected K[] elements;
 
  public K get (int n) throws RuntimeException {
    try {
      return ((K) elements[n]);
    } catch (ArrayIndexOutOfBoundsException e) {
      throw new RuntimeException("elements[" + n + "] not in tuple");
    }
  }
 
  public int hashCode () {
    Long L = new Long(elements[0].hashCode());
    for (int i=1; i < elements.length; i++) {
      long l = ((long) L.hashCode()) << 23; // ça semble meilleur avec un premier
      l     += elements[i].hashCode();
      L      = new Long(l); 
    }
    return L.hashCode();
  }
 
  public boolean equals(Tuple t) {
    if (t == null) {
      return false;
    } else if (this.elements.length != t.elements.length) {
      return false;
    } else {
      for (int i=0; i < elements.length; i++) {
        if (! this.elements[i].equals(t.elements[i])) {
          return false;
        }
      }
    }
    return true;
  }
 
  public String toString () {
    StringBuffer sb = new StringBuffer("[");
    sb.append(elements[0]);
    for (int i=1; i < elements.length; i++) {
      sb.append("," + elements[i]);
    }
    sb.append("]");
    return sb.toString();
  }
 
  public int compareTo(Object o) throws ClassCastException {
    Tuple t;
    if (! (o instanceof Tuple)) {
      throw new ClassCastException(o + " is not a Tuple");
    } else {
      t = (Tuple) o;
    }
    int i = 0;
    try {             // on itère sur les éléments   
      while (true) {  // tant qu'on n'a pas atteint la fin d'un tableau
                      // on compare les éléments
        if (! this.elements[i].equals(t.elements[i])) {
 
          // s'ils sont différents, on renvoie leur comparaison
          return this.get(i).compareTo(t.get(i));
 
        } else {
 
          // sinon, on compare les suivants
          i++;
 
        }
      }
    } catch (Exception e) {
      if (this.elements.length < t.elements.length)
        return -1;
      else
        return 1;
    }
  }
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
Graph/Tuple.java:66: cannot find symbol
symbol  : method compareTo(java.lang.Object)
location: class java.lang.Object
          return this.get(i).compareTo(t.get(i));
                            ^
1 error
Il me semblerait aussi logique que compareTo renvoie une exception si le type des éléments de l'instance est différent de celui du tuple passé en argument, mais, je ne vois pas du tout comment faire.

Merci d'avance pour toute réponse,

G.