Je crois qu'il y a deux utilisations liées de la canonique: les formes et les instances.
Une forme canonique signifie que les valeurs d'un type particulier de ressource peuvent être décrites ou représentées de plusieurs manières, et l'une de ces manières est choisie comme forme canonique préférée. (Cette forme est canonisée , comme les livres qui en ont fait la Bible, et les autres formes ne le sont pas.) Un exemple classique de forme canonique est les chemins dans un système de fichiers hiérarchique, où un seul fichier peut être référencé de plusieurs manières. :
myFile.txt # in current working dir
../conf/myFile.txt # relative to the CWD
/apps/tomcat/conf/myFile.txt # absolute path using symbolic links
/u1/local/apps/tomcat-5.5.1/conf/myFile.txt # absolute path with no symlinks
La définition classique de la représentation canonique de ce fichier serait le dernier chemin. Avec des chemins locaux ou relatifs, vous ne pouvez pas identifier globalement la ressource sans informations contextuelles. Avec les chemins absolus, vous pouvez identifier la ressource, mais vous ne pouvez pas dire si deux chemins font référence à la même entité. Avec deux chemins ou plus convertis dans leurs formes canoniques, vous pouvez faire tout ce qui précède, et déterminer si deux ressources sont identiques ou non, si cela est important pour votre application (résolvez le problème d'aliasing ).
Notez que la forme canonique d'une ressource n'est pas une qualité de cette forme particulière elle-même; il peut y avoir plusieurs formes canoniques possibles pour un type donné comme les chemins de fichiers (disons, lexicographiquement d'abord les chemins absolus possibles). Un formulaire est simplement sélectionné comme forme canonique pour une raison d'application particulière, ou peut-être arbitrairement afin que tout le monde parle la même langue.
Forcer des objets dans leurs instances canoniques est la même idée de base, mais au lieu de déterminer une «meilleure» représentation d'une ressource, il choisit arbitrairement une instance d'une classe d'instances avec le même «contenu» que la référence canonique, puis convertit toutes les références à des objets équivalents pour utiliser la seule instance canonique.
Cela peut être utilisé comme une technique pour optimiser le temps et l'espace. S'il y a plusieurs instances d'objets équivalents dans une application, alors en les forçant tous à être résolus en tant qu'instance canonique unique d'une valeur particulière, vous pouvez éliminer toutes sauf une de chaque valeur, économisant de l'espace et éventuellement du temps puisque vous pouvez maintenant comparer ces valeurs avec l'identité de référence (==) par opposition à l'équivalence d'objet ( equals()
méthode).
Un exemple classique d'optimisation des performances avec des instances canoniques consiste à réduire des chaînes avec le même contenu. L'appel String.intern()
de deux chaînes avec la même séquence de caractères est garanti pour renvoyer le même objet String canonique pour ce texte. Si vous passez toutes vos chaînes à travers ce canonicalizer, vous savez que les chaînes équivalentes sont en fait des références d'objet identiques, c'est-à-dire des alias
Les types enum dans Java 5.0+ forcent toutes les instances d'une valeur d'énumération particulière à utiliser la même instance canonique dans une machine virtuelle, même si la valeur est sérialisée et désérialisée. C'est pourquoi vous pouvez utiliser if (day == Days.SUNDAY)
en toute impunité en java si Days
est un type enum. Faire cela pour vos propres cours est certainement possible, mais il faut faire attention. Lisez Effective Java par Josh Bloch pour plus de détails et des conseils.
réduit à la forme la plus simple et la plus significative sans perdre la généralité
la source
Un moyen facile de s'en souvenir est la façon dont «canonique» est utilisé dans les cercles théologiques, la vérité canonique est la vraie vérité, donc si deux personnes la trouvent, elles ont trouvé la même vérité. Idem avec l'instance canonique. Si vous pensez en avoir trouvé deux (ie
a.equals(b)
), vous n'en avez vraiment qu'un (iea == b
). L'égalité implique donc l'identité dans le cas d'un objet canonique.Maintenant pour la comparaison. Vous avez maintenant le choix d'utiliser
a==b
oua.equals(b)
, car ils produiront la même réponse dans le cas d'une instance canonique mais a == b est la comparaison de la référence (la JVM peut comparer deux nombres extrêmement rapidement car ce ne sont que deux modèles de 32 bits comparés àa.equals(b)
qui est un appel de méthode et implique plus de frais généraux.la source
Un autre bon exemple pourrait être: vous avez une classe qui prend en charge l'utilisation des coordonnées cartésiennes (x, y, z), sphériques (r, thêta, phi) et cylindriques (r, phi, z). Pour établir l'égalité (méthode égale), vous voudrez probablement convertir toutes les représentations en une représentation «canonique» de votre choix, par exemple des coordonnées sphériques. (Ou peut-être voudriez-vous faire cela en général - c'est-à-dire utiliser une représentation interne.) Je ne suis pas un expert, mais cela m'est venu à l'esprit comme peut-être un bon exemple concret.
la source
la représentation canonique signifie voir le caractère dans un style différent, par exemple si j'écris une lettre A signifie qu'une autre personne peut écrire la lettre A dans un style différent :)
Ceci est conforme au CHAMP DE RECONNAISSANCE DE CARACTERE OPTIQUE
la source
Une forme canonique signifie une représentation naturellement unique de l'élément
la source
Les questions du PO sur la forme canonique et sur la manière dont elle peut améliorer les performances de la
equals
méthode peuvent toutes deux être répondues en étendant l'exemple fourni dans Effective Java.Considérez la classe suivante:
La
equals
méthode de cet exemple a un coût supplémentaire en utilisantString
laequalsIgnoreCase
méthode de. Comme mentionné dans le texteQue veut dire Joshua Bloch quand il parle de forme canonique ? Eh bien, je pense que la réponse concise de Dónal est très appropriée. Nous pouvons stocker le
String
champ sous-jacent dans l'CaseInsensitiveString
exemple de manière standard , peut-être la forme majuscule duString
. Maintenant, vous pouvez référencer cette forme canonique duCaseInsensitiveString
, sa variante majuscule, et effectuer des évaluations bon marché dans vos méthodesequals
ethashcode
.la source
Données canoniques dans le SGBDR, données graphiques;
Pensez à la «normalisation» ou à la «forme normale» d'une donnée dans un SGBDR. Les mêmes données existent dans différentes tables, représentées par un identifiant unique et mappées dans différentes tables.
ou
Pensez à une forme unique de données dans la base de données Graph qui est représentée en plusieurs triplets.
Son principal avantage est de rendre Dml (manipulation de données) plus efficace car vous ne pouvez insérer (insérer / mettre à jour) qu'une seule valeur au lieu de plusieurs.
la source