Java N-Tuple de la mise en œuvre
Je viens de faire une Java n-tuple qui est de type sécurisé.
Je suis en utilisant des méthodes non conventionnelles pour atteindre la sécurité du type (j'ai juste fait ça pour le plaisir).
Quelqu'un peut-il peut donner quelques commentaires sur l'amélioration ou de certains d'éventuelles failles.
public class Tuple {
private Object[] arr;
private int size;
private static boolean TypeLock = false;
private static Object[] lastTuple = {1,1,1}; //default tuple type
private Tuple(Object ... c) {
//TODO Auto-generated constructor stub
size=c.length;
arr=c;
if(TypeLock)
{
if(c.length == lastTuple.length)
for(int i = 0; i<c.length; i++)
{
if(c[i].getClass() == lastTuple[i].getClass())
continue;
else
throw new RuntimeException("Type Locked");
}
else
throw new RuntimeException("Type Locked");
}
lastTuple = this.arr;
}
public static void setTypeLock(boolean typeLock) {
TypeLock = typeLock;
}
@Override
public boolean equals(Object obj) {
//TODO Auto-generated method stub
if (this == obj)
return true;
Tuple p = (Tuple)obj;
for (int i = 0; i < size; i++)
{
if (p.arr[i].getClass() == this.arr[i].getClass())
{
if (!this.arr[i].equals(p.arr[i]))
return false;
}
else
return false;
}
return true;
}
@Override
public int hashCode() {
//TODO Auto-generated method stub
int res = 17;
for(int i = 0; i < size; i++)
res = res*37+arr[i].hashCode();
return res;
}
@Override
public String toString() {
//TODO Auto-generated method stub
return Arrays.toString(arr);
}
public static void main(String[] args) {
HashMap<Tuple,String> birthDay = new HashMap<Tuple,String>();
Tuple p = new Tuple(1,2,1986);
Tuple.setTypeLock(true);
Tuple p2 = new Tuple(2,10,2009);
Tuple p3 = new Tuple(1,2,2010);
Tuple p4 = new Tuple(1,2,2010);
birthDay.put(p,"Kevin");
birthDay.put(p2,"Smith");
birthDay.put(p3,"Sam");
birthDay.put(p4, "Jack");
System.out.println(birthDay);
System.out.println(birthDay.get(new Tuple(1,2,1986)));
birthDay.put(new Tuple(1,2,""),"");
}
}
- Comment peut-on même récupérer des données à partir de la n-uplet?
- Les Tuples peuvent avoir des éléments hétérogènes avec les types. Que
TypeLock
et tout ce quigetClass
choses donc n'a pas de sens. - Je vais voter pour fermer cette question hors-sujet, car la question est sur la révision du code du travail, code utilisable; il n'y a pas clairement énoncé du problème et pas de solution claire possible.
Vous devez vous connecter pour publier un commentaire.
Félicitations sur l'apprentissage par la pratique. Voici quelques suggestions de "chances" d'amélioration:
Un seul type de n-uplet peut jamais exister (une fois Typelock est réglé). Cela fait mal de réutilisabilité et l'évolutivité dans les programmes de vouloir utiliser plusieurs types de Tuples, sauf si vous recourir à des cut-n-coller de la réutilisation (BirthdayTuple, DimensionsTuple, StreetAddressTuple, ...). Considérons un TupleFactory classe qui accepte les types de cibles et crée un tuple objet builder pour générer des n-uplets.
La validité de la valeur "null" comme une valeur dans un Tuple n'est pas documenté. Je pense qu'avant de Typelock est définie, la valeur null est permis; mais après Typelock est défini, le code va générer une exception NullPointerException - ce qui est incompatible. Si ils ne sont pas autorisés, le constructeur doit l'attraper et de la rejeter (indépendamment de Typelock). Si elles sont autorisées, le code de l'ensemble (constructeur, d'égal à égal, hashcode, etc) doit être modifié pour permettre à pour cela.
Décider si les Tuples sont destinés à être immuable des objets de valeur. Basé sur son manque de méthodes de définition, je suppose donc. Si oui, alors soyez prudent de "l'adoption" de la future baie
lastTuple=this.arr
. Même si c'est un var arg constructeur, le constructeur pourrait être appelée avec un tableau directement. La classe adopte le tableau (conserve une référence à elle), et les valeurs dans le tableau pourrait être modifié en dehors de la classe par la suite. Je ferais une copie de la matrice, mais également de documenter le problème potentiel avec les Tuples avec les non-valeurs inaltérables (qui peut être changée à l'extérieur de la n-uplet).Votre
equals
méthode n'est pas la valeur null check (if (obj == null) return false
) et la vérification de classe (soitobj instanceof Tuple
outhis.getClass().equals(object.getClass())
). L'égale de l'idiome est bien documenté.Il n'y a pas moyen d'afficher les valeurs d'un Tuple, sauf par l'intermédiaire
toString
. Cela protège les valeurs et l'ensemble de l'immutabilité de la , mais je pense qu'il limite l'utilité de la classe.Alors que je me rends compte à sa juste un exemple, je ne m'attends pas à utiliser cette classe pour quelque chose comme les anniversaires, les dates. Dans les domaines de solution fixe les types d'objets, de classes (comme la Date) sont tellement mieux. J'imagine que cette classe pour être utile dans des domaines spécifiques où les tuples sont des objets de première classe.
Modifier
Été de penser à ce sujet. Voici mon point de vue sur certains de code (sur github + tests):
TypeType.getNthType()
est droit; la signature deTupleTypeImpl.getNthType()
l'est pas; de Changer de signature de la méthode de TupleTypeImpl.getNthType() pour correspondre à TypeType.getNthType(). Fixe dans le code maintenant.production
. (désolé, je suis juste venu pour quelque chose de plus comme le python tuples)Comment est-ce typesafe? Vous jeter des exceptions d'exécution au lieu de déclaration des erreurs de type au moment de la compilation.
Vous essayez de résumé sur arité qui est (encore) possible dans les langages statiquement typés, sans perdre typesafety.
Addendum:
Tuples peuvent être constitués d'éléments hétérogènes (c'est à dire des éléments de différents types). Donc même "rutime typesafety" n'est pas possible, pour cette
Tuple
classe. Les Clients de la classe sont responsables pour le jette.C'est le meilleur que vous pouvez faire en Java :(Edit: Voir Brent post pour une meilleure mise en œuvre deTuple
. (Il ne nécessite pas typecasts sur le côté client.))(a, a)
et(a, a, a)
sont de divers types.Tuple2
àTuple22
les classes définies dans la bibliothèque standard (Il est très peu probable que quelqu'un aura besoin de tuples avec une plus grande arities). En tant que programmeur, vous n'avez pas à s'en soucier - bibliothèque des écrivains ont fait le travail pour vous. Où est le mal?! 🙂C'est la solution la plus simple et c'est aussi le meilleur. Il est similaire à la façon dont les Tuples sont représentés dans les .NET. Il élude soigneusement java effacement. Il est fortement typé. Il ne jette pas des exceptions. Il est très facile à utiliser.
Vous devriez regarder .NET n-uplet de la mise en œuvre. Ils sont de la compilation de type sécurisé.
Tuple
), ils sont toujours définis comme des types distincts (tout comme dans la Scala). Le seul problème de l'effacement pose, c'est qu'il ne permet pas d'avoir des classes avec le même nom, mais un nombre différent de paramètres de type (Réifiée types dans .NET permet de le faire).Quel est le but de
typeLock
? Pour permettre à quelqu'un pour empêcher la construction de plus de ces objets? Cette partie n'a pas beaucoup de sens.Pourquoi voudriez-vous jamais eu envie de laisser quelqu'un prévenir la poursuite de l'instanciation de vos objets? Si, pour quelque raison que c'est quelque chose que vous avez besoin, au lieu de "verrouillage" d'une classe et de lever des exceptions, assurez-vous que le chemin d'accès du code ... ne pas créer plusieurs objets de ce type.
Quel est le but de la statique
lastTuple
qui est une référence de la dernière instanciéTuple
? C'est une mauvaise pratique de mélanger les références statiques comme ça.Franchement le code est assez déroutant, même si la nécessité de cette classe est source de confusion. Si d'une certaine façon c'était le code que je passais en revue dans un environnement de travail, je ne le permettrait pas.
Tuple
classe comme ça, et puis l'écriture de la classe pour répondre à ces cas d'utilisation. Certaines "caractéristiques" vous avez ajouté sembler complètement inutile et si quoi que ce soit, à l'envers.vu ce code dans le vague projet
Ici est vraiment une terrible n-tuple de mise en œuvre qui utilise des génériques pour fournir le type de compilation des contrôles. La méthode main (fourni à des fins de démonstration) montre à quel horrible ce qui serait d'utiliser:
Si vous êtes vraiment intéressé par l'écriture de type-la sécurité des conteneurs, regarder dans les génériques:
Il serait préférable d'utiliser des génériques pour la compilation de sécurité de type. Vous pouvez définir une interface par arité. Ensuite, vous pouvez définir séparé Appelable interfaces pour accéder aux valeurs du tuple.