ShapeId implements ToShapeId, Comparable<ShapeId> { @Override public int compareTo(ShapeId other) { int outcome = toString().compareToIgnoreCase(other.toString()); if (outcome == 0) { return toString().compareTo(other.toString()); } return outcome; } private  ShapeId(String absoluteName, String namespace, String name, String member); private  ShapeId(String namespace, String name, String member); static ShapeId from(String id); static boolean isValidNamespace(CharSequence namespace); static boolean isValidIdentifier(CharSequence identifier); static ShapeId fromParts(String namespace, String name, String member); static ShapeId fromParts(String namespace, String name); static ShapeId fromRelative(String namespace, String relativeName); static ShapeId fromOptionalNamespace(String defaultNamespace, String shapeName); ShapeId withMember(String member); @Override ShapeId toShapeId(); @Override int compareTo(ShapeId other); ShapeId withoutMember(); String getNamespace(); String getName(); Optional<String> getMember(); String asRelativeReference(); ShapeId withNamespace(String namespace); @Override String toString(); @Override boolean equals(Object other); @Override int hashCode();  }
@Test public void compareToTest() { List<ShapeId> given = Arrays.asList( ShapeId.fromParts("ns.foo", "foo"), ShapeId.fromParts("ns.foo", "Foo"), ShapeId.fromParts("ns.foo", "bar"), ShapeId.fromParts("ns.foo", "bar", "member"), ShapeId.fromParts("ns.foo", "bar", "Member"), ShapeId.fromParts("ns.foo", "bar", "AMember"), ShapeId.fromParts("ns.Foo", "foo"), ShapeId.fromParts("ns.baz", "foo") ); given.sort(ShapeId::compareTo); List<ShapeId> expected = Arrays.asList( ShapeId.fromParts("ns.baz", "foo"), ShapeId.fromParts("ns.foo", "bar"), ShapeId.fromParts("ns.foo", "bar", "AMember"), ShapeId.fromParts("ns.foo", "bar", "Member"), ShapeId.fromParts("ns.foo", "bar", "member"), ShapeId.fromParts("ns.Foo", "foo"), ShapeId.fromParts("ns.foo", "Foo"), ShapeId.fromParts("ns.foo", "foo") ); assertEquals(expected, given); }