Я пытаюсь проверить, не является ли строка Java не null
, а не пустой, а не пробельной.
На мой взгляд, этот код должен был полностью соответствовать задаче.
public static boolean isEmpty(String s) {
if ((s != null) && (s.trim().length() > 0))
return false;
else
return true;
}
В соответствии с документацией String.trim()
должно работать так:
Возвращает копию строки с опущенными пробелами в начале и конце.
Если этот объект
String
представляет собой пустую последовательность символов, или первый и последний символы последовательности символов, представленные этим объектомString
, оба имеют коды больше, чем'\u0020'
(символ пробела), то ссылка на это Возвращается объектString
.
Однако, apache/commons/lang/StringUtils.java
делает это несколько иначе.
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}
В соответствии с документацией Character.isWhitespace()
:
Определяет, является ли указанный символ пробелом в соответствии с Java. Символ является символом пробела Java тогда и только тогда, когда он удовлетворяет одному из следующих критериев:
- Это символ пробела в Юникоде (
SPACE_SEPARATOR
,LINE_SEPARATOR
илиPARAGRAPH_SEPARATOR
), но также не является неразрывным пробелом ('\u00A0'
,'\u2007'
,'\u202F'
).- Это
'\t'
, U + 0009 ГОРИЗОНТАЛЬНАЯ ТАБУЛЯЦИЯ.- Это
'\n'
, U + 000A LINE FEED.- Это
'\u000B'
, U + 000B ВЕРТИКАЛЬНАЯ ТАБУЛЯЦИЯ.- Это
'\f'
, U + 000C FORM FEED.- Это
'\r'
, U + 000D CARRIAGE RETURN.- Это
'\u001C'
, U + 001C FILE SEPARATOR.- Это
'\u001D'
, U + 001D GROUP SEPARATOR.- Это
'\u001E'
, U + 001E RECORD SEPARATOR.- Это
'\u001F'
, U + 001F UNIT SEPARATOR.
Если я не ошибаюсь - возможно, я просто не читаю его правильно - String.trim()
должен отнять любой из символов, которые проверяются Character.isWhitespace()
. Все они выглядят выше '\u0020'
.
В этом случае более простая функция isEmpty
, по-видимому, охватывает все сценарии, охватывающие более длинный isBlank
.
- Есть ли строка, которая приведет к тому, что
isEmpty
иisBlank
будут вести себя по-другому в тестовом примере? - Предполагая, что их нет, есть ли какое-либо другое соображение, из-за которого я должен выбрать
isBlank
и не использоватьisEmpty
?
Для тех, кто заинтересован в фактическом выполнении теста, здесь приведены методы и модульные тесты.
public class StringUtil {
public static boolean isEmpty(String s) {
if ((s != null) && (s.trim().length() > 0))
return false;
else
return true;
}
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}
}
И модульные тесты
@Test
public void test() {
String s = null;
assertTrue(StringUtil.isEmpty(s)) ;
assertTrue(StringUtil.isBlank(s)) ;
s = "";
assertTrue(StringUtil.isEmpty(s)) ;
assertTrue(StringUtil.isBlank(s));
s = " ";
assertTrue(StringUtil.isEmpty(s)) ;
assertTrue(StringUtil.isBlank(s)) ;
s = " ";
assertTrue(StringUtil.isEmpty(s)) ;
assertTrue(StringUtil.isBlank(s)) ;
s = " a ";
assertTrue(StringUtil.isEmpty(s)==false) ;
assertTrue(StringUtil.isBlank(s)==false) ;
}
Обновление: Это была действительно интересная дискуссия, и именно поэтому я люблю Qaru и людей здесь. Кстати, вернувшись к вопросу, мы получили:
- Программа, показывающая, что все символы будут вести себя по-другому. Код находится в https://ideone.com/ELY5Wv. Спасибо @Dukeling.
- Связанная с производительностью причина выбора стандарта
isBlank()
. Спасибо @devconsole. - Полное описание @nhahtdh. Спасибо друг.