验证字符串为空或null的最佳方法

39

我确定之前已经以不同的方式提出了类似的问题——因为isEmptyOrNull非常常见,但人们实现方法不同。但是我有一个好奇的疑问,关于最佳可用方法,既要考虑内存又要考虑性能。

1)以下代码无法处理所有空格,例如空XML标记中的空格。

return inputString==null || inputString.length()==0;

2) 虽然下面的代码很安全,但trim函数可能会影响性能和内存。

return inputString==null || inputString.trim().length()==0;

3)将一和二相结合可以节省一些性能和内存(如Chris在评论中建议的)

return inputString==null || inputString.trim().length()==0 || inputString.trim().length()==0;

4) 转换为模式匹配器(仅在字符串长度非零时调用)

private static final Pattern p = Pattern.compile("\\s+");

return inputString==null || inputString.length()==0 || p.matcher(inputString).matches();

5) 使用诸如 - Apache Commons(StringUtils.isBlank/isEmpty) 或 Spring(StringUtils.isEmpty) 或 Guava(Strings.isNullOrEmpty) 或其他选项?


inputString!=null && inputString.isEmpty(); 更精细的写法是 inputString!=null && inputString.trim().isEmpty(); - StackFlowed
isEmpty 在 Java 6 中是“新功能”,而旧版本的实现或想保持 Java 5 兼容性的实现将不得不使用长度检查。 - zapl
2
如果你这样写 return inputString==null || inputString.length()==0 || inputString.trim().length()==0; (将1和2合并),那么trim只会在非零长度的字符串上调用。你也可以加上3。 - Christian Fries
@ChristianFries 是的,我同意-针对trim()和pattern matcher使用相同的方法。但是让我这样问吧,trim()或matcher(),哪一个更昂贵? - prash
1
Guava提供了Strings.isNullOrEmpty()方法,目前我正在大量使用它! - prash
显示剩余2条评论
14个回答

42

5
最近我经常使用Guava的Strings.isNullOrEmpty()函数。 - prash
2
isNullOrEmpty 不会检查输入字符串由多个空格组成的情况。 - Manav Bhanot

25

要检测一个字符串是否为空或null,您可以使用以下方法,而无需在项目中包含任何外部依赖项,并保持您的代码简单/清晰:

if(myString==null || myString.isEmpty()){
    //do something
}

或者如果还需要检测空白字符:

if(myString==null || myString.trim().isEmpty()){
    //do something
}

您可以将这些简单的检查封装成实用方法,以使代码更加简洁,因为它们是非常常见的检查:

public final class StringUtils{

    private StringUtils() { }   

    public static bool isNullOrEmpty(string s){
        if(s==null || s.isEmpty()){
            return true;
        }
        return false;
    }

    public static bool isNullOrWhiteSpace(string s){
        if(s==null || s.trim().isEmpty()){
            return true;
        }
        return false;
    }
}

然后通过以下方式调用这些方法:

if(StringUtils.isNullOrEmpty(myString)){...}

以及

if(StringUtils.isNullOrWhiteSpace(myString)){...}


1
更新了,谢谢。我每次都不可避免地犯这个错误,然后编译它,看到错误,意识到我已经犯了这个错误第九十亿次了 :) - GregH
1
@zapl或Java语句是短路的。如果myString为null,它将中断。 - James Wierzba
@JamesWierzbaзҡ„зӯ”жЎҲжҳҜif (s.isEmpty||s==null)пјҢиҝҷдјҡеңЁз©әеҖјзҡ„жғ…еҶөдёӢзҹӯи·Ҝ并引еҸ‘NPE :) жҲ‘еҲ йҷӨдәҶиҜ„и®әд»ҘйҒҝе…Қж··ж·ҶгҖӮ - zapl
它并不会处理空格 :) - prash
这个问题只提到了null或empty。如果空格也需要被检测,那么可以很容易地改为if(myString==null || myString.trim().isEmpty()){...} - GregH
1
现在String类有一个.isBlank()方法。 - user2303325

15

仅为展示Java 8移除空值的立场。

String s = Optional.ofNullable(myString).orElse("");
if (s.trim().isEmpty()) {
    ...
}

如果您能使用Optional<String>,这将很有意义。


谢谢Joop,我认为这也是一个干净的解决方案 - 它不适用于多空格空字符串,如“ ”。 - prash
@prash:为了好看加了一个修剪,但是Apache Commons无与伦比。 ;) - Joop Eggen
3
我必须说,我认为Optional的使用像一种糟糕的疾病一样感染了Java社区。我以前从未见过一个功能需要如此多的额外输入才能实现如此简单的操作,但在竞争激烈的语言正在寻求更简洁的解决方案的时候,却被如此多的人盲目地采用。这一定会让非Java开发人员嘲笑我们。我甚至没有提到当Optional被实例化并由每秒调用数百万次的方法返回时所需的额外CPU和内存消耗 - 但这都在云端运行,所以CPU和内存几乎是免费的,对吧? - Volksman
@Volksman 我同意以下两点:1. 一些其他编程语言具有更好的(设计)结构;2. Optional是一个后期添加的工件,其API尚未成熟。但是,它比null更好,并且允许一些很好的操作,例如map。 - Joop Eggen
1
@JoopEggen 我从C++时代开始使用多态的“Null”类/对象来存储在模板/通用集合中“表示”空值的项目,但最近我一直在处理大规模系统,这些系统已经存在性能问题(CPU + 内存),每秒处理数千个交易。如果我们改变返回null的工作代码,通过将每个返回值包装在Optional中,我们将在堆上分配成千上万个对象,使一个挣扎的系统为没有任何好处而做更多的工作(在我看来),并且会带来很多痛苦或增加基础设施成本来应对。概念上很棒! - Volksman
@Volksman 100%正确; 此外,小的重构浪潮也是很有成效的(尽管应该在开发期间进行重构以保持代码良好)。性能可能会令人惊讶,但确实不是最佳选择。 - Joop Eggen

8

这个来自Google Guava的方法可以同时检查null和空字符串。

Strings.isNullOrEmpty("Your string.");

使用Maven添加依赖

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>20.0</version>
</dependency>

使用Gradle
dependencies {
  compile 'com.google.guava:guava:20.0'
}

你能说一下你正在使用哪个库中的 Strings 类吗? - Silver Quettier
1
从“Google Guava”中。我已经编辑了答案并添加了库。 - mavis.chen
1
Guava的依赖大小为2.3 MB,仅用于检查字符串是否为空。Guava缺乏模块化。 - Aure77

4

Apache Commons Lang拥有StringUtils.isEmpty(String str)方法,如果参数为空或null,则返回true。


4

目前还没有看到任何完全本地化的解决方案,所以这里提供一个:

return str == null || str.chars().allMatch(Character::isWhitespace);

基本上,您可以使用本地的 Character.isWhitespace() 函数。从那里开始,您可以实现不同级别的优化,这取决于它有多重要(我可以向您保证,在99.99999%的情况下,不需要进一步优化):

return str == null || str.length() == 0 || str.chars().allMatch(Character::isWhitespace);

或者,为了真正的最佳效果(但是非常丑陋):
int len;
if (str == null || (len = str.length()) == 0) return true;
for (int i = 0; i < len; i++) {
  if (!Character.isWhitespace(str.charAt(i))) return false;
}
return true;

我喜欢做的一件事:

Optional<String> notBlank(String s) {
  return s == null || s.chars().allMatch(Character::isWhitepace))
    ? Optional.empty()
    : Optional.of(s);
}

...

notBlank(myStr).orElse("some default")

3

springframework库 检查给定的字符串是否为空。

f(StringUtils.isEmpty(str)) {
    //.... String is blank or null
}

1
从Spring 5.3开始,isEmpty已被弃用。建议使用以下替代方法:hasLength(String)hasText(String)ObjectUtils.isEmpty(Object) - Mihkel Selgal

2
Optional.ofNullable(label)
.map(String::trim)
.map(string -> !label.isEmpty)
.orElse(false)

OR

TextUtils.isNotBlank(label);

最后一种解决方案将同时检查是否为null并修剪字符串。


1
来自Apache HttpCore的TextUtils。 - arulraj.net

1
在大多数情况下,来自apache commons库的StringUtils.isBlank(str)可以解决问题。但是,如果有一种情况,被检查的输入字符串在引号内具有null值,则无法检查此类情况。
以一个示例为例,我有一个输入对象,该对象使用String.valueOf(obj) API转换为字符串。如果obj引用为空,则String.valueOf返回“null”而不是null。
当您尝试使用StringUtils.isBlank("null")时,API会失败,您可能还需要检查这些用例,以确保您的验证正确。

1
使用openJDK 11,您可以使用内部验证来检查字符串是否为null或仅为空格。
import jdk.internal.joptsimple.internal.Strings;
...

String targetString;
if (Strings.isNullOrEmpty(tragetString)) {}

不错,我想他们是从C#那里偷来的。我有一段时间没有用了。 - d00d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接