The canonical form of the field

I am learning effective Java, clause 8 (follow the general contract when redefining peers). The author explained this quite clearly, but still some details are not so much developed.

In this example, he considers the CaseInsensitiveString class, defined as:

public final class CaseInsensitiveString { private final String s; public CaseInsensitiveString(String s) { if (s == null) throw new NullPointerException(); this.s = s; } // Broken - violates symmetry! @Override public boolean equals(Object o) { if (o instanceof CaseInsensitiveString) return s.equalsIgnoreCase(((CaseInsensitiveString) o).s); if (o instanceof String) // One-way interoperability! return s.equalsIgnoreCase((String) o); return false; } // ... // Remainder omitted } 

At the end of the article he says:

For some classes, such as the CaseInsensitiveString above, field comparisons are more complex than simple equality tests. If so, you might want to store the canonical form of the field, so the equals method can do cheap, accurate comparisons of these canonical forms, rather than a more expensive inaccurate comparison, isons. This method is most suitable for immutable classes (clause 15); if the object can change, you must keep the canonical form up to date.

I searched this term and found that it basically means a standard representation of something, such as an absolute path without any symbolic links for the file in the directory. But I cannot understand the use of the "canonical" form for this class, which will help here. Any suggestions?

+5
source share
1 answer

I think that in this particular example, the canonical form can contain a lowercase or uppercase version of String and make comparisons on it.

 private final String s; public CaseInsensitiveString(String s) { //for real code probably use locale version this.s = s.toLowerCase(); } 

This makes comparison comparisons cheaper because we can do exact string comparisons instead of the more expensive equalsIgnoreCase

 // Broken - violates symmetry! @Override public boolean equals(Object o) { if (o instanceof CaseInsensitiveString) return s.equals(((CaseInsensitiveString) o).s); if (o instanceof String) // One-way interoperability! return s.equals((String) o); return false; } 
+5
source

Source: https://habr.com/ru/post/1237084/


All Articles