java.lang.Iterable<T>

Описание java.lang.Iterable<T> довольно простое.

Реализация этого интерфейса позволяет объекту быть целью расширенного оператора for (иногда называемого оператором для каждого цикла).

Просто с данным экземпляром Iterable<T> мы можем это сделать.

for (final T i : iterable) { // for-each element, as i, in iterable
    // do anything with i
}

Теперь поговорим о проблеме того, как узнать, отсортирован ли уже экземпляр Iterable<T>.

Очевидно, для этого нам нужны две вещи. Один является экземпляром Iterable для проверки, а другой - экземпляром Comparable для сравнения каждого элемента в Iterable.

static <T> boolean isSorted(
        final Iterable<? extends T> iterable,
        final Comparator<? super T> comparator) {
    // TODO: implement!
}

Iterable<? extends T>

iterable аргумент будет работать как продюсер, создавая каждый элемент в методе, и это часть продюсер расширяет из PECS.

Comparator<? super T>

Мы будем использовать данный аргумент comparator для сравнения каждого элемента, предоставленного экземпляром iterable. Это означает, что comparator будет работать как потребитель против метода. И это часть потребительского супер от PECS. См. Эффективная Java, если вы не знакомы с концепцией PECS в Generics.

С приведенными выше определениями тело метода несколько прямолинейно.

static <T> boolean isSorted(
        final Iterable<? extends T> iterable,
        final Comparator<? super T> comparator) {
    final T previous = null;
    for (final T current : iterable) { // iterable produces
        if (previous != null // comparator consumes
            && comparable.compare(previous, current) > 0) {
            return false;
        }
        previous = current;
    }
    return true;
}

Типы уже реализованыComparable?

Некоторые типы, такие как String или Integer, уже реализуют интерфейс Comparable. Это означает, что нам не нужен конкретный экземпляр Comparator.

static <T extends Comparable<? super T>> boolean isSorted(
        final Iterable<? extends T> iterable,
        final boolean natural) {
    // TODO: implement!
}

Comparable<? super T>

Интерфейс Comparable<T> - это FunctionalInterface, единственный метод которого - int compare(T o).

Это означает, что когда вы создаете свой гипотетический Apple класс, который расширяет Fruit, реализуете Comparable<Apple>, вы получаете int compare(Apple o).

Что затрудняет сравнение с другим типом Fruit, например, Orange.

И вот здесь на помощь приходит ? super T. Параметризуя с помощью ? super [Self], класс можно сравнивать с любыми предшественниками или, в виде приведенной формы, с любыми братьями, сестрами и преемниками.

И вот единственная строка для метода.

static <T extends Comparable<? super T>> boolean isSorted(
        final Iterable<? extends T> iterable,
        final boolean natural) {
    return isSorted(iterable,
                    natural ? naturalOrder() : reverseOrder());
}

И naturalOrder(), и reverseOrder() - служебные методы, определенные в Comparator интерфейсе, каждый из которых также имеет подпись <T extends Comparable<? super T>> Comparator<T> …Order().

Со следующими тестовыми утверждениями,

final Iterable<String> unknown = Arrays.asList("c", "a", "b");
System.out.println(isSorted(unknown, true));
System.out.println(isSorted(unknown, false));
final Iterable<String> natural = Arrays.asList("a", "b", "c");
System.out.println(isSorted(natural, true));
System.out.println(isSorted(natural, false));
final Iterable<String > reverse = Arrays.asList("c", "b", "a");
System.out.println(isSorted(reverse, true));
System.out.println(isSorted(reverse, false));

Я получил,

false
false
true
false
false
true

Если вы хотите узнать больше о Java. Вот несколько полезных статей, на которые можно сослаться:

  1. 10 вещей, которые Java-программист должен выучить в 2019 году
  2. 10 бесплатных курсов по изучению Java с нуля
  3. 10 книг для углубленного изучения Java
  4. 10 инструментов, которые должен знать каждый Java-разработчик
  5. 10 фреймворков, которые Java и веб-разработчики должны изучить в 2019 году

Заключительные примечания

Спасибо, что прочитали эту статью. Это очень полезный совет для программиста на Java. Если вам понравилась эта статья, обратите внимание на следующую нашу публикацию на Medium.

Если вы хотите получать уведомления о каждой новой публикации и не забывайте подписываться на javarevisited в Twitter!