我正在尝试检查Java String是否不是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空白字符:
- 它是一个Unicode空格字符(
SPACE_SEPARATOR
,LINE_SEPARATOR
或PARAGRAPH_SEPARATOR
),但也不是一个不间断的空格('\u00A0'
,'\u2007'
,'\u202F'
)。'\t'
,U + 0009 HORIZONTAL TABULATION。- 是
'\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) ;
}
更新:这是一个非常有趣的讨论 - 这就是为什么我喜欢Stack Overflow和这里的人们。顺便说一句,回到这个问题,我们得到了:
isBlank()
的性能相关原因。谢谢@devconsole。 答案 0 :(得分:32)
是否有一个字符串会使
isEmpty
和isBlank
在测试用例中表现不同?
请注意,Character.isWhitespace
可识别Unicode字符,并返回{NULL}空格字符的true
。
根据Java确定指定的字符是否为空格。当且仅当它满足以下条件之一时,字符才是Java空白字符:
它是一个Unicode空格字符(
SPACE_SEPARATOR
,LINE_SEPARATOR
或PARAGRAPH_SEPARATOR
),但也不是一个不间断的空格('\u00A0'
,{{ 1}},'\u2007'
)。
'\u202F'
另一方面,[...]
方法会修剪代码点低于U + 0020的所有控制字符和空格字符(U + 0020)。
因此,在存在Unicode空白字符时,这两种方法的行为会有所不同。例如:trim()
。 或当字符串包含不通过"\u2008"
方法考虑空格的控制字符时。例如:Character.isWhitespace
。
如果你要编写一个正则表达式来执行此操作(这比通过字符串循环并检查更慢):
"\002"
等同于isEmpty()
.matches("[\\x00-\\x20]*")
等同于isBlank()
(.matches("\\p{javaWhitespace}*")
和isEmpty()
方法都允许isBlank()
字符串引用,因此它不完全等同于正则表达式解决方案,但将它放在一边,它是等效的。)< / p>
请注意null
,顾名思义,是用于访问\p{javaWhitespace}
方法定义的字符类的特定于Java的语法。
假设没有,是否还有其他考虑因素,我应该选择
Character.isWhitespace
而不使用isBlank
?
这取决于。但是,我认为上述部分的解释应该足以让您做出决定。总结差异:
isEmpty
如果字符串只包含控制字符 1 在U + 0020和空格字符(U + 0020)
isEmpty()
如果字符串只包含由isBlank
方法定义的空白字符,则会认为该字符串为空,其中包含Unicode空白字符。
1 Character.isWhitespace
处还有一个控制字符,不会被U+007F DELETE
方法修剪。
答案 1 :(得分:25)
两种标准方法的目的是区分这两种情况:
org.apache.common.lang.StringUtils.isBlank(" ")
(将返回 true )。
org.apache.common.lang.StringUtils.isEmpty(" ")
(将返回 false )。
isEmpty()
的自定义实现将返回 true 。
<强>更新强>
org.apache.common.lang.StringUtils.isEmpty()
用于查找String的长度是0还是null。
org.apache.common.lang.StringUtils.isBlank()
向前迈出了一步。它不仅检查String是长度为0还是null,还检查它是否只是一个空白字符串。
在您的情况下,您正在修改 isEmpty
方法中的字符串。现在唯一的区别是不会发生(你给它" "
的情况),因为你是trimming它(删除尾随空格 - 在这种情况下就像删除所有空格。)
答案 2 :(得分:14)
我会选择isBlank()
而不是isEmpty()
,因为trim()
会创建一个新的String对象,以后必须进行垃圾回收。另一方面,isBlank()
不会创建任何对象。
答案 3 :(得分:4)
您可以查看包含Annotatinos @NotEmpty
和@NotNull
的JSR 303 Bean Validtion。 Bean验证很酷,因为您可以从方法的原始意图中分离验证问题。
答案 4 :(得分:1)
为什么不能简单地使用嵌套的三元运算符来实现此目的。请查看示例代码
public static void main(String[] args)
{
String s = null;
String s1="";
String s2="hello";
System.out.println(" 1 "+check(s));
System.out.println(" 2 "+check(s1));
System.out.println(" 3 "+check(s2));
}
public static boolean check(String data)
{
return (data==null?false:(data.isEmpty()?false:true));
}
,输出如下
1 false 2 false 3 true
这里的前两个场景返回false(即null和empty),第三个场景返回true
答案 5 :(得分:0)
<%
System.out.println(request.getParameter("userName")+"*");
if (request.getParameter("userName").trim().length() == 0 | request.getParameter("userName") == null) { %>
<jsp:forward page="HandleIt.jsp" />
<% }
else { %>
Hello ${param.userName}
<%} %>
答案 6 :(得分:0)
这个简单的代码就足够了:
public static boolean isNullOrEmpty(String str) {
return str == null || str.trim().equals("");
}
单元测试:
@Test
public void testIsNullOrEmpty() {
assertEquals(true, AcdsUtils.isNullOrEmpty(""));
assertEquals(true, AcdsUtils.isNullOrEmpty((String) null));
assertEquals(false, AcdsUtils.isNullOrEmpty("lol "));
assertEquals(false, AcdsUtils.isNullOrEmpty("HallO"));
}
答案 7 :(得分:0)
使用Java 8,您还可以使用可选功能进行过滤。要检查字符串是否为空,代码是纯Java SE而没有其他库。 以下代码说明了isBlank()实现。
.toString()
!Optional.ofNullable(tocheck).filter(e -> e != null && e.trim().length() > 0).isPresent()