Home > Java > Extrinsic vs intrinsic equality

Extrinsic vs intrinsic equality

Note: the following article is purely theoretical. I don’t know if it fits a real-life use-case, but the point is just too good to miss :-)

Java’s List sorting has two flavors: one follows the natural ordering of collection objects, the other requires an external comparator.

In the first case, Java assumes objects are naturally ordered. From a code point of view, this means types of objects in the list must implement the Comparable interface. For example, such is the case for String and Date objects. If this is not the case, or if objects cannot be compared to one another (because perhapsthey belong to incompatible type as both String and Date).

The second case happens when the natural order is not relevant and a comparator has to be implemented. For example, strings are sorted according to the character value, meaning case is relevant. When the use-case requires a case-insensitive sort, the following code will do (using Java 8 enhanced syntax):

Collections.sort(strings, (s1, s2) -> s1.compareToIgnoreCase(s2));

The Comparable approach is intrinsic, the Comparator extrinsic; the former case rigid, the latter adaptable to the required context.

What applies to lists, however, cannot be applied to Java sets. Objects added to sets have to define equals() and hashCode() and both properties (one could say that it’s only one since they are so coupled together) are intrinsic. There is no way to define an equality that can change depending on the context in the JDK.

Enters Trove:

The Trove library provide primitive collections with similar APIs to the above. This gap in the JDK is often addressed by using the “wrapper” classes (java.lang.Integer, java.lang.Float, etc.) with Object-based collections. For most applications, however, collections which store primitives directly will require less space and yield significant performance gains.

Let’s be frank, Trove is under-documented. However, it offers what is missing regarding extrinsic equality: it provides a dedicated set implementation, that accepts its own extrinsic equality abstraction.

A sample code would look like that:

HashingStrategy<Date> strategy = new MyCustomStrategy();

Set<Date> dates = new TCustomHashSet<Date>(strategy);

A big bonus for using Trove is performance, though:

  1. It probably is the first argument to use Trove
  2. I never tested that in any context

To go further, just have a look at Trove for yourself.

email
Send to Kindle
Categories: Java Tags:
  1. January 27th, 2014 at 00:31 | #1

    Trove indeed has a couple of great features. Note, you can actually write this now:

    strings.sort((s1, s2) -> s1.compareToIgnoreCase(s2));

    There’s a new default method on java.util.List…

  2. Steve
    January 27th, 2014 at 03:03 | #2

    Sorry, pretty weak article.

  3. Steve
    January 27th, 2014 at 03:04 | #3

    Ok sorry, my fault.

  4. Yannick
    January 30th, 2014 at 12:40 | #4

    Hello,

    Url to trove is broken :)

  5. February 2nd, 2014 at 16:15 | #5

    @Yannick
    Thanks, fixed.

  1. No trackbacks yet.