1. How do the Comparable and Comparator interfaces differ, and when should you use one over the other?

The Comparable interface is used to define a natural ordering for a class, which allows objects of that class to be sorted automatically in the default manner. The Comparator interface, on the other hand, is used to define a custom ordering for a class, which allows objects of that class to be sorted in a specific manner. You should use the Comparable interface if you want to use the default sorting behavior for a class, and you should use the Comparator interface if you want to define a custom sorting behavior for a class.

  1. How to implement a custom comparator using a lambda expression?
// Define a custom comparator that sorts strings by their length,
// with the shortest strings appearing first in the sorted list.
Comparator<String> stringLengthComparator = (s1, s2) -> s1.length() - s2.length();

// Use the comparator to sort a list of strings.
List<String> stringList = Arrays.asList("abc", "def", "gh", "ijkl");
stringList.sort(stringLengthComparator);

// The sorted list should be: ["gh", "abc", "def", "ijkl"]