Creo que hay dos usos relacionados de canónico: formas e instancias.
Una forma canónica significa que los valores de un tipo particular de recurso se pueden describir o representar de múltiples formas, y una de esas formas se elige como la forma canónica preferida. (Esa forma está canonizada , como los libros que llegaron a la Biblia, y las otras formas no). Un ejemplo clásico de una forma canónica son las rutas en un sistema de archivos jerárquico, donde se puede hacer referencia a un solo archivo de varias maneras. :
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 definición clásica de la representación canónica de ese archivo sería la última ruta. Con rutas locales o relativas, no puede identificar globalmente el recurso sin información contextual. Con las rutas absolutas puede identificar el recurso, pero no puede saber si dos rutas se refieren a la misma entidad. Con dos o más rutas convertidas a sus formas canónicas, puede hacer todo lo anterior, además de determinar si dos recursos son iguales o no, si eso es importante para su aplicación (resuelva el problema del alias ).
Tenga en cuenta que la forma canónica de un recurso no es una cualidad de esa forma particular en sí; puede haber múltiples formas canónicas posibles para un tipo dado, como rutas de archivo (digamos, lexicográficamente en primer lugar de todas las posibles rutas absolutas). Una forma simplemente se selecciona como forma canónica por una razón de aplicación en particular, o tal vez arbitrariamente para que todos hablen el mismo idioma.
Forzar objetos en sus instancias canónicas es la misma idea básica, pero en lugar de determinar una "mejor" representación de un recurso, elige arbitrariamente una instancia de una clase de instancias con el mismo "contenido" que la referencia canónica, luego convierte todas las referencias a objetos equivalentes para usar la única instancia canónica.
Esto se puede utilizar como una técnica para optimizar tanto el tiempo como el espacio. Si hay varias instancias de objetos equivalentes en una aplicación, al forzarlos a que se resuelvan como la única instancia canónica de un valor particular, puede eliminar todos menos uno de cada valor, ahorrando espacio y posiblemente tiempo, ya que ahora puede comparar aquellos valores con identidad de referencia (==) en contraposición a la equivalencia de objeto ( equals()
método).
Un ejemplo clásico de optimización del rendimiento con instancias canónicas es contraer cadenas con el mismo contenido. String.intern()
Se garantiza que la invocación de dos cadenas con la misma secuencia de caracteres devolverá el mismo objeto String canónico para ese texto. Si pasa todas sus cadenas a través de ese canonicalizador, sabrá que las cadenas equivalentes son en realidad referencias de objetos idénticas, es decir, alias
Los tipos de enumeración en Java 5.0+ obligan a todas las instancias de un valor de enumeración particular a usar la misma instancia canónica dentro de una VM, incluso si el valor está serializado y deserializado. Es por eso que puede usar if (day == Days.SUNDAY)
con impunidad en java si Days
es un tipo enum. Hacer esto para sus propias clases es ciertamente posible, pero hay que tener cuidado. Lea Effective Java de Josh Bloch para obtener detalles y consejos.
reducido a la forma más simple y significativa sin perder la generalidad
fuente
Una manera fácil de recordarlo es la forma en que se usa "canónico" en los círculos teológicos, la verdad canónica es la verdad real, así que si dos personas la encuentran, han encontrado la misma verdad. Lo mismo ocurre con la instancia canónica. Si cree que ha encontrado dos de ellos (es decir
a.equals(b)
), en realidad solo tiene uno (es decira == b
). Entonces la igualdad implica identidad en el caso de objeto canónico.Ahora para la comparación. Ahora tiene la opción de usar
a==b
oa.equals(b)
, ya que producirán la misma respuesta en el caso de una instancia canónica, pero a == b es una comparación de la referencia (la JVM puede comparar dos números extremadamente rápido ya que son solo dos patrones de 32 bits comparados a loa.equals(b)
que es una llamada a un método e implica más gastos generales.fuente
Otro buen ejemplo podría ser: tienes una clase que admite el uso de coordenadas cartesianas (x, y, z), esféricas (r, theta, phi) y cilíndricas (r, phi, z). Con el fin de establecer la igualdad (método de igualdad), probablemente desee convertir todas las representaciones en una representación "canónica" de su elección, por ejemplo, coordenadas esféricas. (O tal vez desee hacer esto en general, es decir, usar una representación interna). No soy un experto, pero esto se me ocurrió tal vez como un buen ejemplo concreto.
fuente
La representación canónica significa ver el personaje en un estilo diferente, por ejemplo, si escribo una letra A significa que otra persona puede escribir la letra A en un estilo diferente :)
Esto es de acuerdo con el CAMPO DE RECONOCIMIENTO DE CARÁCTER ÓPTICO
fuente
Una forma canónica significa una representación naturalmente única del elemento
fuente
Las preguntas del OP sobre la forma canónica y cómo se puede mejorar el rendimiento del
equals
método se pueden responder ampliando el ejemplo proporcionado en Effective Java.Considere la siguiente clase:
public final class CaseInsensitiveString { private final String s; public CaseInsensitiveString(String s) { this.s = Objects.requireNonNull(s); } @Override public boolean equals(Object o) { return o instanceof CaseInsensitiveString && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s); } }
El
equals
método de este ejemplo tiene un costo adicional al usarString
elequalsIgnoreCase
método de. Como se menciona en el texto¿Qué quiere decir Joshua Bloch cuando dice forma canónica ? Bueno, creo que la respuesta concisa de Dónal es muy apropiada. Podemos almacenar el
String
campo subyacente en elCaseInsensitiveString
ejemplo de una manera estándar , quizás la forma mayúscula deString
. Ahora, puede hacer referencia a esta forma canónica deCaseInsensitiveString
, su variante en mayúsculas y realizar evaluaciones económicas en sus métodosequals
yhashcode
.fuente
Datos canónicos en RDBMS, datos gráficos;
Piense como "Normalización" o "Forma normal" de un dato en un RDBMS. Los mismos datos existen en diferentes tablas, representados con un identificador único y mapeados en diferentes tablas.
o
Piense en una forma única de un dato en Graph Database que se represente en muchos triples.
El principal beneficio de esto es hacer que Dml (manipulación de datos) sea más eficiente, ya que puede insertar (insertar / actualizar) solo un valor en lugar de muchos.
fuente