Статьи

Больше терпеть неудачу рано — Java 8

Fail fast или Fail Early — это концепция разработки программного обеспечения, которая пытается предотвратить возникновение сложных проблем путем остановки выполнения, как только что-то не должно произойти. В предыдущем посте и презентации блога я более подробно расскажу о достоинствах этого подхода, в этом посте я просто подробно опишу еще одно использование этой идеи в Java 8.

В Java итераторы, возвращаемые классами Collection, например, ArrayList, HashSet, Vector и т. Д., Быстро перестают работать. Это означает, что если вы попытаетесь добавить () или удалить () из базовой структуры данных во время итерации, вы получите исключение ConcurrentModificationException. Посмотрим:

1
2
3
4
5
6
7
import static java.util.Arrays.asList;
List ints = new ArrayList<>(asList(1,2,3,4,5,6,9,15,67,23,22,3,1,4,2));
     
for (Integer i: ints) {
    // some code
    ints.add(57);  // throws java.util.ConcurrentModificationException
}

В Java 8u20 API Collections.sort () также быстро отказывает. Это означает, что вы не можете вызвать его внутри итерации. Например:

1
2
3
4
5
6
7
8
import static java.util.Arrays.asList;
List ints = new ArrayList<>(asList(1,2,3,4,5,6,9,15,67,23,22,3,1,4,2));
 
     
for (Integer i: ints) {
    // some code
    Collections.sort(ints); // throws java.util.ConcurrentModificationException
}

Это имеет смысл. Перебор структуры данных и их сортировка во время итерации не только противоречит интуиции, но и может привести к непредсказуемым результатам. Теперь вы можете обойтись без этого и не получить исключение, если у вас был перерыв сразу после вызова сортировки.

1
2
3
4
5
6
7
8
9
import static java.util.Arrays.asList;
List ints = new ArrayList<>(asList(1,2,3,4,5,6,9,15,67,23,22,3,1,4,2));
 
     
for (Integer i: ints) {
    // some code
    Collections.sort(ints); // throws java.util.ConcurrentModificationException
    break;
}

Но это вряд ли отличный код. Старайтесь избегать старых итераций skool, и вы можете использовать Lambdas, когда можете. Но, если вы застряли, просто сделайте сортировку вне итерации

1
2
3
4
5
6
7
import static java.util.Arrays.asList;
List ints = new ArrayList<>(asList(1,2,3,4,5,6,9,15,67,23,22,3,1,4,2));
Collections.sort(ints);
     
for (Integer i: ints) {
    // some code
}

или использовать структуру данных, которая сортирует при добавлении.

Это новое поведение API Collections.sort () появилось в Java 8 выпуск 20 . Стоит взглянуть на конкретный раздел, в котором подробно описаны изменения в API:

»

Площадь : core-libs / java.util.collections
Синопсис : Collection.sort defers теперь переносится в List.sort

Ранее Collection.sort копировал элементы списка для сортировки в массив, сортировал этот массив, затем обновлял список на месте, с этими элементами в массиве, и методом по умолчанию.
List.sort отложен до Collection.sort. Это было неоптимальное соглашение.

Начиная с версии 8u20, Collection.sort переходит к List.sort . Это означает, например, что существующий код, который вызывает Collection.sort с экземпляром ArrayList , теперь будет использовать оптимальную сортировку, реализованную ArrayList.

»

Я думаю, что это помогло бы, если бы Oracle немного более подробно объяснил, как это изменение может вызвать проблемы во время выполнения. Учитывая, что все используют платформу Collections, если API, который раньше не генерировал исключение, теперь может работать в той же ситуации (плохой код и все такое), лучше, если примечания к выпуску облегчат разработчикам поиск этой информации. ,

Опубликовано на Java Code Geeks с разрешения Алекса Стейвли, партнера нашей программы JCG . Смотреть оригинальную статью здесь: Подробнее Fail early — Java 8

Мнения, высказанные участниками Java Code Geeks, являются их собственными.