在Java中检查非空,非空字符串

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (15)

我试图检查一个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空白字符,当且仅当它满足下列条件之一时:

  • 它是Unicode空格字符(SPACE_SEPARATORLINE_SEPARATORPARAGRAPH_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组分离器。
  • 它是'\u001E'U + 001E RECORD SEPARATOR。
  • 它是'\u001F'U + 001F UNIT SEPARATOR。

如果我没有弄错 - 或者可能是我没有正确阅读 - String.trim() 应该带走正在检查的任何字符Character.isWhiteSpace()。他们都看到上面'\u0020'

在这种情况下,更简单的isEmpty功能似乎覆盖了更长的覆盖的所有场景isBlank

  1. 是否有一个字符串,这将使isEmptyisBlank表现不同的测试案例?
  2. 假设没有,有没有其他的考虑,因为我应该选择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) ;       

}
提问于
用户回答回答于

这两种标准方法的目的是区分这两种情况:

org.apache.common.lang.StringUtils.isBlank(" ")(将返回true)。

org.apache.common.lang.StringUtils.isEmpty(" ")(将返回false)。

你的自定义实现isEmpty()将返回true

org.apache.common.lang.StringUtils.isEmpty() 用于查找字符串是长度为0还是为空。org.apache.common.lang.StringUtils.isBlank()向前迈进了一步。它不仅检查字符串是否为长度0或空值,还检查它是否只是空白字符串。

用户回答回答于

是否有一个字符串,这将使isEmptyisBlank表现不同的测试案例?

请注意,Character.isWhitespace可以识别Unicode字符并返回trueUnicode空白字符。

根据Java确定指定的字符是否为空白。一个字符是一个Java空白字符,当且仅当它满足下列条件之一时:

  • 它是Unicode空格字符(SPACE_SEPARATORLINE_SEPARATORPARAGRAPH_SEPARATOR),但不也是非打破空间('\u00A0''\u2007''\u202F')。
  • [...]

另一方面,trim()方法将修剪所有代码点低于U + 0020和空格字符(U + 0020)的控制字符。

因此,这两种方法在Unicode空白字符的存在下会有不同的表现。例如:"\u2008"或者,当字符串包含不按Character.isWhitespace方法考虑空格的控制字符时。例如:"\002"

如果您要编写正则表达式来执行此操作(这比通过字符串和检查进行循环更慢):

  • isEmpty() 将相当于 .matches("[\\x00-\\x20]*")
  • isBlank() 将相当于 .matches("\\p{javaWhitespace}*")

isEmpty()isBlank()方法都允许null字符串引用,所以它不完全等同于正则表达式解决方案,但放在一边,它是等价的)。

请注意,\p{javaWhitespace}顾名思义,是访问由Character.isWhitespace方法定义的字符类的Java特定语法。

假设没有,有没有其他的考虑,因为我应该选择isBlank而不是使用isEmpty

这取决于。不过,我认为上述部分的解释应该足以让您决定。总结不同之处:

  • isEmpty()如果字符串只包含U + 0020和空格字符(U + 0020)以下的控制字符1,
  • isBlank如果它只包含由Character.isWhitespace方法定义的空白字符(包括Unicode空白字符),则认为该字符串为空。

1还有一个控制字符U+007F DELETE,它不会被trim()方法修剪。

扫码关注云+社区