Я пытаюсь проверить, не является ли строка 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. Спасибо друг.