Я считаю, что есть два связанных использования слова canonical: формы и экземпляры.
А каноническая форма , означает , что значения определенного типа ресурса могут быть описаны или представлены несколько способами, и один из этих способов выбираются в качестве благоприятствования канонической формы. (Эта форма канонизирована , как книги, вошедшие в библию, а другие формы - нет.) Классическим примером канонической формы являются пути в иерархической файловой системе, где на один файл можно ссылаться несколькими способами. :
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
Классическим определением канонического представления этого файла будет последний путь. С локальными или относительными путями вы не можете глобально идентифицировать ресурс без контекстной информации. С помощью абсолютных путей вы можете идентифицировать ресурс, но не можете определить, относятся ли два пути к одному и тому же объекту. С двумя или более путями, преобразованными в их канонические формы, вы можете сделать все вышеперечисленное, а также определить, являются ли два ресурса одинаковыми или нет, если это важно для вашего приложения (решить проблему сглаживания ).
Обратите внимание, что каноническая форма ресурса не является качеством самой этой конкретной формы; для данного типа может быть несколько возможных канонических форм, таких как пути к файлам (скажем, лексикографически прежде всего возможные абсолютные пути). Одна форма просто выбрана в качестве канонической по определенной причине приложения или, возможно, произвольно, чтобы все говорили на одном языке.
Принуждение объектов к их каноническим экземплярам - та же основная идея, но вместо определения одного «лучшего» представления ресурса он произвольно выбирает один экземпляр класса экземпляров с тем же «содержанием», что и каноническая ссылка, а затем преобразует все ссылки эквивалентным объектам, чтобы использовать один канонический экземпляр.
Это можно использовать как метод оптимизации времени и пространства. Если в приложении есть несколько экземпляров эквивалентных объектов, то, принудительно разрешив их все как один канонический экземпляр определенного значения, вы можете удалить все, кроме одного, каждого значения, сэкономив место и, возможно, время, поскольку теперь вы можете сравнивать эти значения со ссылочной идентичностью (==) в отличие от эквивалентности объекта ( equals()
метод).
Классический пример оптимизации производительности с помощью канонических экземпляров - сворачивание строк с одинаковым содержимым. Вызов String.intern()
двух строк с одинаковой последовательностью символов гарантирует возврат одного и того же канонического объекта String для этого текста. Если вы пропустите все свои строки через этот каноникализатор, вы знаете, что эквивалентные строки на самом деле являются идентичными ссылками на объекты, то есть псевдонимами
Типы перечисления в Java 5.0+ заставляют все экземпляры определенного значения перечисления использовать один и тот же канонический экземпляр в виртуальной машине, даже если значение сериализовано и десериализовано. Вот почему вы можете if (day == Days.SUNDAY)
безнаказанно использовать в java, если Days
это тип перечисления. Сделать это для ваших собственных классов, конечно, можно, но будьте осторожны. Прочтите « Эффективная Java » Джоша Блоха для получения подробной информации и советов.
сводится к простейшему и наиболее значительному виду без потери общности
источник
Легкий способ запомнить, что это то, как «каноническая» используется в теологических кругах, каноническая истина - это настоящая истина, поэтому, если два человека находят ее, они нашли одну и ту же истину. То же и с каноническим экземпляром. Если вы думаете, что нашли два из них (т. Е.
a.equals(b)
), На самом деле у вас только один (тa == b
. Е. ). Таким образом, равенство подразумевает идентичность в случае канонического объекта.Теперь для сравнения. Теперь у вас есть выбор использовать
a==b
илиa.equals(b)
, поскольку они дадут тот же ответ в случае канонического экземпляра, но a == b - это сравнение ссылки (JVM может очень быстро сравнивать два числа, поскольку это всего лишь два сравниваемых 32-битных шаблона кa.equals(b)
которому относится вызов метода и требует дополнительных затрат.источник
Другим хорошим примером может быть: у вас есть класс, который поддерживает использование декартовых (x, y, z), сферических (r, theta, phi) и цилиндрических координат (r, phi, z). В целях установления равенства (метод равенства) вы, вероятно, захотите преобразовать все представления в одно «каноническое» представление по вашему выбору, например, в сферические координаты. (Или, может быть, вы захотите сделать это вообще, то есть использовать одно внутреннее представление.) Я не эксперт, но мне это пришло в голову как, возможно, хороший конкретный пример.
источник
каноническое представление означает просмотр персонажа в другом стиле, например, если я напишу букву А, значит другой человек может написать букву А в другом стиле :)
Это согласно ПОЛЯ ОПТИЧЕСКОГО РАСПОЗНАВАНИЯ ХАРАКТЕРА.
источник
Каноническая форма означает естественно уникальное представление элемента.
источник
На вопросы OP о канонической форме и о том, как она может улучшить производительность
equals
метода, можно ответить, расширив пример, представленный в Эффективной Java.Рассмотрим следующий класс:
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); } }
equals
Метод в этом примере добавил стоимость, используяString
«ыequalsIgnoreCase
метод. Как упоминалось в текстеЧто имеет в виду Джошуа Блох, когда говорит о канонической форме ? Что ж, я думаю, что краткий ответ Донала очень уместен. Мы можем сохранить базовое
String
поле вCaseInsensitiveString
примере стандартным способом, возможно, в прописной формеString
. Теперь вы можете ссылаться на эту каноническую форму изCaseInsensitiveString
, его заглавного варианта, а также выполнять дешевые оценки в вашихequals
иhashcode
методах.источник
Канонические данные в СУБД, графические данные;
Представьте себе «нормализацию» или «нормальную форму» данных в СУБД. Одни и те же данные существуют в разных таблицах, представлены уникальным идентификатором и отображены в разных таблицах.
или же
Подумайте об одной форме данных в базе данных Graph, которая представлена множеством троек.
Основным преимуществом этого метода является повышение эффективности Dml (манипуляции данными), поскольку вы можете вставлять (вставлять / обновлять) только одно значение вместо многих.
источник