Java Questions 111 -120  «Prev  Next»


Java SE 25: Comparable and Comparator Questions

Study natural ordering, custom comparators, compareTo signatures, equals consistency, and heterogeneous containers through eleven Java SE 25 questions.

Legacy Collection hierarchy showing list, set, and queue interfaces and example implementations
Simplified historical hierarchy. Java SE 25 additionally includes SequencedCollection, SequencedSet, and Deque: List extends SequencedCollection; SortedSet extends SequencedSet; LinkedList implements List and Deque.
  1. Which Java APIs can sort an ArrayList?

    Answer: Call list.sort(comparator) or Collections.sort(list, comparator). For natural ordering, use list.sort(null) or the one-argument Collections.sort overload. Collections is a class in the java.util package; ArrayList supports an instance sort operation.

    The list must support the required element replacement. An unmodifiable List.of result cannot be sorted in place; copy it into an ArrayList first.

  2. Which ordering interface does String implement?

    Answer: String implements Comparable<String>. Its compareTo method supplies a case-sensitive lexicographic ordering by UTF-16 char values. String has other interfaces too; Comparable is the one relevant to natural-order sorting. Locale-sensitive text ordering requires a different comparator, such as Collator.

  3. Which sorting operations use Comparable?

    Answer: Natural-order object sorting uses Comparable: examples are Collections.sort(list), List.sort(null), and Arrays.sort on an object array without a comparator. Comparator overloads can sort objects without relying on their natural order. Primitive array sorting uses primitive values rather than Comparable instances.

  4. What method does Comparable declare?

    Answer: It declares int compareTo(T other). Return a negative, zero, or positive integer according to the ordering; exactly -1 and 1 are not required. The ordering must be transitive and have consistent signs when arguments are reversed.

    Use Integer.compare or other comparison helpers rather than subtraction that may overflow. Comparison with null conventionally throws NullPointerException under the Comparable contract, even though equals(null) returns false.

  5. What comparison method does Comparator provide?

    Answer: Its functional comparison method is int compare(T first, T second). A lambda or method reference can implement it. Comparator also has composition helpers such as reversed and thenComparing, and static factories such as comparing and nullsFirst.

    Comparator declares equals(Object) too, but that Object-method signature does not prevent Comparator from being a functional interface. Implementations must still follow the comparison contract.

  6. How can a class implement Comparable correctly?

    Answer: Use a parameterized Comparable type and compare the state that defines the desired natural order. The following immutable title value uses the same title for record equality and natural ordering, so compareTo returning zero agrees with equals.

    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    import java.util.Objects;
    
    public class DvdOrdering {
        record DVDInfo(String title) implements Comparable<DVDInfo> {
            DVDInfo { Objects.requireNonNull(title); }
            @Override public int compareTo(DVDInfo other) {
                return title.compareTo(other.title);
            }
        }
        public static void main(String[] args) {
            List<DVDInfo> discs = new ArrayList<>(List.of(
                new DVDInfo("Zulu"), new DVDInfo("Alien")));
            discs.sort(null);
            System.out.println(discs.getFirst().title());
            discs.sort(Comparator.reverseOrder());
            System.out.println(discs.getFirst().title());
            System.out.println(new DVDInfo("Alien").compareTo(new DVDInfo("Alien")));
        }
    }
    

    If a real DVD model adds edition, region, or an identifier, revisit both equality and ordering. Comparing only title can make distinct DVDs collapse into one TreeSet entry.

  7. What parameter type is required when overriding equals()?

    Answer: Use Object: public boolean equals(Object other). A method such as equals(DVDInfo) overloads rather than overrides Object.equals and may behave differently depending on the compile-time argument type. Add @Override so the compiler can catch a signature mistake.

  8. What parameter type is required for compareTo()?

    Answer: When implementing Comparable<DVDInfo>, declare public int compareTo(DVDInfo other). The generic interface supplies the parameter type. Avoid raw Comparable and an unnecessary Object cast; the compiler can generate the bridge needed for erased interface dispatch.

  9. Can a class define several natural orderings with Comparable?

    Answer: A class has one Comparable type contract and one natural ordering for it. It cannot implement Comparable with two different type arguments. Overloads with other parameter types are possible, but they do not create multiple natural orderings for generic sorting.

    Use separate Comparator instances for alternative orderings, such as title, release year, and price. That keeps the intended ordering explicit at each call site.

  10. What flexibility does Comparator add?

    Answer: It defines an external ordering without changing the element class, so you can sort third-party types or use several different criteria. Composition supports tie-breakers and null handling. A comparator used by a TreeSet or TreeMap should agree with equals if normal Set or Map equality semantics are required.

  11. Can an array or ArrayList hold different runtime types?

    Answer: Yes, if its declared element type permits them: Object[] and List<Object> can hold a String and an Integer. Primitives assigned to those containers are boxed. This does not disable type checking, and a List<Object> is different from a raw List.

    Arrays also enforce their actual runtime component type. An Object[] reference pointing to a String[] cannot store an Integer; doing so throws ArrayStoreException. A List<Number> can hold Integer and Double, but List<Integer> is not a subtype of List<Number>.

Java SE 25 references: List, Collections, Comparable, Comparator, String.