Как лучше читается проверка на не пустую коллекцию?

251
16 ноября 2017, 02:31

Интересно, как грамотнее писать проверку на то, что коллекция не пустая, следуя принципу чистого кода?

if(!col.isEmpty())

Или

if(col.size() > 0)

Или

if(col.get(0) != null)

Коварный восклицательный знак можно не заметить, однако на enSO где-то читал, что так лучше читается, но мне кажется, что наиболее читаем второй вариант.

Так, как все-таки лучше?

Answer 1

if(col.size() > 0) и if(col.get(0) != null)

вообще не вариант.

if(!col.isEmpty()) больше подходит, но как вы верно заметили оператор "!" часто можно не заметить, потому что наш мозг плохо работает с отрицанием. Из-за этого иногда трудно будет найти ошибку в коде.

Вы говорите о чистом коде. В таких ситуациях я часто, даже почти всегда пользуюсь рефакторингом, а точнее извлекаю это условие в метод (Extract method) и называю метод в зависимости от того какой коллекцией пользуюсь:

Например,

if(!children.isEmpty()) {
    // do something
}

!children.isEmpty() ивлекаю в метод hasChildren().

if (hasChildren()) {
    // do something
}
private boolean hasChildren() {
    return !children.isEmpty();
}

Такой код лучше читается и не путает другого программиста который будет работать с вашим кодам.

Вот еще варианты: !orders.isEmpty() -> hasOrders(). Если заказы пусты, значит ничего не заказывал(а). !playlist.isEmpty() -> hasPlaylist(). Если пользователь вообще ничего не добавлял(а) в плейлист, значит у него (нее) нет плейлиста. и т.д.

Answer 2

Во-первых, вы не указали еще вариант

if (col.isEmpty()) {
   return ... // результат если коллекция пуста
} else {
   ... // результат если не пуста
}

Во-вторых, if(col.size() > 0) довольно некрасивый на мой взгляд, тем более что для строк и кастомных классов он не всегда подходит. К тому же кастомные коллекции могут быстро отдавать ответ isEmpty() и долго size(). Иметь один вариант для всех случаев предпочтительнее.

Answer 3

По уму нужно использовать col.isEmpty().
Плюсы тут не в производительности. Если заглянуть в исходники метода, то, скорее всего, вы сможете увидеть return size == 0;

Все обстоит немного иначе…
Начнем с того, что если писать код правильно и грамотно, то все классы предметной области должны взаимодействовать через их интерфейсы.
Это дает много плюсов, в т.ч. гибкость, ведь по сути, если класс А имеет дело с интерфейсом класса В, то класс А вообще ничего не знает о существовании класса В, вы можете с легкостью даже полностью заменить класс В, главное, чтобы он имплементировал те же интерфейсы.
Именно по этой причине, создавая новый экземпляр класса любой коллекции, мы приводим ее к интерфейсу Map map = new HashMap(). И вот тут самое интересное…

Теперь, вызывая isEmpty(), вы вообще-то обращаетесь к интерфейсу и вообще не привязаны к непосредственной реализации этого метода в классе, либо к каким-либо другим методам. Посему работает все вышесказанное.

READ ALSO
Java Android. Работа в фоновом режиме. Класс Surface

Java Android. Работа в фоновом режиме. Класс Surface

Я искал как сделать запись происходящего на экране AndroidНашел, вот на сайте

247
“Стрим” экрана (демонстрация экрана). Android API: MediaProjection

“Стрим” экрана (демонстрация экрана). Android API: MediaProjection

В официальном Android API написано следующее:

314
Получение поля SET из БД в java

Получение поля SET из БД в java

Как получить поле типа SET из БД mysql в java?

245
Товарищи как поместить Random в цикл for что бы каждый раз когда он вызывался Random становилось новым числом?

Товарищи как поместить Random в цикл for что бы каждый раз когда он вызывался Random становилось новым числом?

В итоге должен был получиться код который перебирает числа пока не найдет такое которое при перестановке цифр будет в 3 раза больше исходного

246