Path implements CacheValue, Comparable<Path> { @Override public int compareTo(@NotNull Path other) { if (this == other) { return 0; } Path t = this; int off = t.getNumberOfPathElements(true) - checkNotNull(other).getNumberOfPathElements(true); int corrected = off; while (corrected > 0) { t = t.parent; corrected--; } while (corrected < 0) { other = other.parent; corrected++; } int cp = comparePath(t, other); if (cp != 0) { return cp; } return Integer.signum(off); } private  Path(@Nullable Path parent,
                 @NotNull String name,
                 int hash);  Path(@NotNull Path parent, @NotNull String name);  Path(@NotNull String name); @NotNull String getName(); @NotNull Iterable<String> elements(); boolean isRoot(); @Nullable Path getParent(); int length(); int getDepth(); @NotNull Path getAncestor(int nth); boolean isAncestorOf(@NotNull Path other); boolean isAbsolute(); @NotNull static Path fromString(@NotNull String path); @NotNull StringBuilder toStringBuilder(@NotNull StringBuilder sb); @Override int getMemory(); @Override int compareTo(@NotNull Path other); @Override String toString(); @Override int hashCode(); @Override boolean equals(Object obj); static final Path ROOT; }
@Test public void compareTo() { Path baz = Path.fromString("/baz"); Path fooBaz = Path.fromString("/foo/baz"); Path relFooBaz = Path.fromString("foo/baz"); List<Path> paths = new ArrayList<>(); paths.add(root); paths.add(baz); paths.add(foo); paths.add(fooBar); paths.add(fooBaz); paths.add(fooBarQuux); paths.add(relFoo); paths.add(relFooBar); paths.add(relFooBaz); for (int i = 0; i < 20; i++) { Collections.shuffle(paths); Collections.sort(paths); assertThat(paths, contains(root, baz, foo, fooBar, fooBarQuux, fooBaz, relFoo, relFooBar, relFooBaz)); } }