Оператор add класса set возвращает логическое значение, которое имеет значение true, если элемент (который должен быть добавлен) еще не существует, и false в противном случае. Пишет
if (set.add(entry)) {
//do some more stuff
}
считается хорошим стилем с точки зрения написания чистого кода? Мне интересно, так как вы делаете две вещи одновременно. 1) добавление элемента и 2) проверка существования элемента.
java
coding-style
clean-code
Андреас Браун
источник
источник
java.util.Set
, который возвращает true,add
когда элемент еще не был там, верно?if (!set.add(entry)) {// entry already present, possibly a case you want to handle}
Ответы:
Да, это так.
Обычный момент, когда операция возвращает логическое значение, заключается в том, что вы можете использовать его для принятия решений, то есть внутри
if
конструкции. Единственный способ реализовать этот потенциал - это сохранить возвращаемое значение в переменной, а затем сразу же повторно использовать его в переменнойif
, что просто глупо и, безусловно, ни в коем случае не предпочтительнее записиif(operation()) { ... }
. Так что просто продолжайте и сделайте это, мы не будем судить вас (за это).источник
Set.add
качестве одной операции без указания альтернативы. Если предполагаемая операция заключается в добавлении одного элемента и выяснении, был ли он добавлен, то нет необходимости в более мощной альтернативе, которая все еще усложняет операцию без выгоды. Я надеюсь, что вы знаете, чтоSet.add
это встроенный метод JRE, который можно использовать без предварительного изучения книги на> 700 страницах.Я бы сказал, что он не настолько чист, насколько это возможно, потому что он заставляет сопровождающего либо уже узнать, либо посмотреть, что означает возвращаемое значение. Означает ли это, что значение уже существует, еще не существует, успешно вставлено? Если вы не используете его часто, вы не будете знать, и даже если вы это сделаете, это намного больше умственная нагрузка.
Я бы предпочел следующее:
Да, немного более многословно, но компилятор должен генерировать в значительной степени тот же самый байт-код, и даже люди, которые годами не использовали наборы Java, могут следовать логике, не ища ничего.
источник
add
возвращает true, если элемент не был там, а не если он был. (Формулировка вопроса вводит в заблуждение.)Set.add
, вы неопытны, и вы должны искать эти методы, чтобы изучить их и стать более опытным.notAlreadyPresent
не лучшая формулировка. Я бы использовалadded
и ожидал, что читатель узнает, почему значение не будет добавлено в набор.Если true означает успех, то это хороший, понятный код.
Существует широко распространенное соглашение, что функция или метод возвращает true (или что-то, что оценивается как true) в случае успеха. Пока ваш код следует этому, я думаю, что помещать метод в условное выражение - это нормально.
Код, подобный этому, излишне загроможден, на мой взгляд:
Такое чувство, что ты повторяешься.
Однако вопрос о значении возвращаемого значения неоднозначен. Вы говорите «логическое значение, которое указывает, существовал ли добавленный элемент», что может означать, что true означает, что элемент существовал (а добавление не произошло). Если это так, я бы в идеале изменил поведение метода при возврате, чтобы оно было более привычным. Если это невозможно, я бы добавил дополнительную промежуточную переменную, которая позволит вам четко обозначить возвращаемый результат в вашем коде (как это предлагают другие).
источник
false
означает, что элемент не был добавлен, потому что он уже содержался, иtrue
означает, что элемент еще не содержался. Asadd()
добавляет элемент в набор, если набор еще не содержит его,true
поэтому означает, что элемент был успешно добавлен в набор.add
успешно ничего не нужно делать. Если элемент еще не был в наборе,add
успешно, добавив элемент в набор. Какая интерпретация правильная, произвольно. Менее произвольное определение успеха - это определение языка: метод завершается успешно, если он возвращается нормально.firstLessThanSecond(int l, int r)
, и он возвращает,true
еслиl > r
илиfalse
еслиl <= r
, то этот метод не является успешным, даже если он возвращает нормально.add
- серьезное сокращение контракта. Документация начинается с «Добавляет указанный элемент к этому набору, если он еще не существует», который удовлетворяет, был ли элемент уже в наборе. Вы можете интерпретировать возвращаемое значение так, как хотите, но в конечном итоге это только ваша интерпретация. А во втором примере метод оценивает, является ли условие истинным. Если условие ложно, метод определенно не потерпел неудачу, так как он успешно оценил условие.Я бы сказал, что это очень C-like. Большую часть времени я бы предпочел иметь переменную с описательным именем для результата мутации, а в
if
условии не было бы никакой мутации .Компилятор исключит эту переменную, если она будет немедленно использована повторно. Человеку будет легче читать источник; для меня это важнее.
Если кому-то придется расширить условие, добавив условие
and
/or
к условию if,.add()
в некоторых случаях он может не вызывать из-за оценки короткого замыкания. Если короткое замыкание не предусмотрено специально, это может привести к ошибке.источник
if (set.contains(entry)){set.add(entry); //do more stuff}
, это также устранено компилятором?contains
иadd
. Кроме того, он выполняет двойную работу по поискуentry
в наборе; это может играть роль для очень больших наборов и очень легких петель.if (set.contains(entry)){set.add(entry); //do more stuff}
а вместо этого использовать, например, ответ Карла Билефельда?Кажется, ваш код нарушает разделение командных запросов . Это обсуждается в книге « Чистый код» и в видео « Структура функций» . Так что с точки зрения чистого кода я думаю, что это не считается хорошим стилем.
Для меня цель вашего кода неясна. Выполняется ли if оба при успешном добавлении записи или когда она уже существует? Что
add()
возвращает? пункт? Код ошибки?источник
if (set.contains(entry)){set.add(entry); //do more stuff}
что-то вроде глупости. Что вы думаете об этом?Collection
API.