什么';在Java中,返回连接字符串并检查null或empty的最佳方法是什么?

什么';在Java中,返回连接字符串并检查null或empty的最佳方法是什么?,java,string,Java,String,我有两个字符串,每个字符串都可以为空(根据StringUtils定义为空或空)。我需要以串联方式显示它们,中间有一个简单的字符,例如破折号、逗号等 例如,一个人的名字由LastName和FirstName组成。PrintName方法应以以下方式打印: 案例a:两者都不是空的 打印LastName+,“FirstName 案例b:FirstName为空 打印LastName 案例c:LastName为空 打印FirstName 案例d:都是空的 打印空字符串 这只是一个简单的练习,但我很好奇Jav

我有两个字符串,每个字符串都可以为空(根据StringUtils定义为空或空)。我需要以串联方式显示它们,中间有一个简单的字符,例如破折号、逗号等

例如,一个人的名字由LastName和FirstName组成。PrintName方法应以以下方式打印:

案例a:两者都不是空的

打印
LastName+,“FirstName

案例b:FirstName为空

打印
LastName

案例c:LastName为空

打印
FirstName

案例d:都是空的

打印
空字符串


这只是一个简单的练习,但我很好奇Java中是否有一种最有效的方法需要最少的变量/内存分配、更少的代码行等等。。。我对效率的定义有点模糊,所以如果你能写下你认为效率更高的原因,那就太好了。

你可以使用
apachecommons-api
类在单行中验证它

GenericValidator.isBlankOrNull(value); 
为此,您需要使用
apachecommons jar
并导入此类

import org.apache.commons.validator.GenericValidator;

您可以使用ApacheCommonsAPI类在单行中对其进行验证

GenericValidator.isBlankOrNull(value); 
为此,您需要使用
apachecommons jar
并导入此类

import org.apache.commons.validator.GenericValidator;

您可以按如下方式设计定价方法:

public class Main {
    private final static Predicate<String> notEmpty = s -> s != null;
    private final static Predicate<String> notBlank = s -> !s.equals("");

    // ...

    private static void printName(final String firstName, final String lastName) {
        final boolean firstNameOk = notEmpty.and(notBlank).test(firstName);
        final boolean lastNameOk = notEmpty.and(notBlank).test(lastName);
        final StringBuilder result = new StringBuilder();

        // Old version:
        //result
        //    .append(lastNameOk ? lastName : "")
        //    .append(lastNameOk && firstNameOk ? ", " : "")
        //    .append(firstNameOk ? firstName : "");
        // End of old Version:

        // New version:
        if (lastNameOk) {
            result.append(lastName);
        }

        if (firstNameOk) {
            if (lastNameOk) {
                result.append(", ");
            }

            result.append(firstName);
        }
        // End of new version:

        System.out.println(result);
    }
}
将打印:

Bond, James
James
Bond

您可以按如下方式设计定价方法:

public class Main {
    private final static Predicate<String> notEmpty = s -> s != null;
    private final static Predicate<String> notBlank = s -> !s.equals("");

    // ...

    private static void printName(final String firstName, final String lastName) {
        final boolean firstNameOk = notEmpty.and(notBlank).test(firstName);
        final boolean lastNameOk = notEmpty.and(notBlank).test(lastName);
        final StringBuilder result = new StringBuilder();

        // Old version:
        //result
        //    .append(lastNameOk ? lastName : "")
        //    .append(lastNameOk && firstNameOk ? ", " : "")
        //    .append(firstNameOk ? firstName : "");
        // End of old Version:

        // New version:
        if (lastNameOk) {
            result.append(lastName);
        }

        if (firstNameOk) {
            if (lastNameOk) {
                result.append(", ");
            }

            result.append(firstName);
        }
        // End of new version:

        System.out.println(result);
    }
}
将打印:

Bond, James
James
Bond
一个简单的“修复”是

一个简单的“修复”是

试试这个:

    String LastName = "First";
    String FirstName = "Last";
    boolean cond1, cond2;
    cond1 = FirstName == null || "".equals(FirstName);
    cond2 = LastName == null || "".equals(LastName);
    String DesiredName = (cond2 ? "" :  LastName) +
      ((!cond2 && !cond1) ? ", " : "") +
      (cond1 ? "" : FirstName);
     System.out.println(DesiredName);
试试这个:

    String LastName = "First";
    String FirstName = "Last";
    boolean cond1, cond2;
    cond1 = FirstName == null || "".equals(FirstName);
    cond2 = LastName == null || "".equals(LastName);
    String DesiredName = (cond2 ? "" :  LastName) +
      ((!cond2 && !cond1) ? ", " : "") +
      (cond1 ? "" : FirstName);
     System.out.println(DesiredName);

使用谷歌的番石榴和它的木匠方法。据我所知,这是最优雅的解决方案

要跳过空字符串+空字符串,请存储firstName、lastName。。。在数组或列表中,然后执行以下操作

return Joiner.on(", ").join(Iterables.filter(listOfStrings, StringPredicates.notEmpty()));

您可以查看Joiner源代码以了解其实现方式。这当然不是最有效的,但在这种情况下,不可忽视的效率增益值得与代码的清晰性和可读性进行权衡。

使用谷歌的番石榴及其Joiner方法。据我所知,这是最优雅的解决方案

return (firstName == null ? "" : firstname + ", " + lastName==null ? "" : lastName).replaceFirst("^, |, $","");

要跳过空字符串+空字符串,请存储firstName、lastName。。。在数组或列表中,然后执行以下操作

return Joiner.on(", ").join(Iterables.filter(listOfStrings, StringPredicates.notEmpty()));
您可以查看Joiner源代码以了解其实现方式。它当然不是最有效的,但在这种情况下,可以忽略的效率增益值得与代码的清晰性和可读性进行权衡

return (firstName == null ? "" : firstname + ", " + lastName==null ? "" : lastName).replaceFirst("^, |, $","");
这将产生firstname+“,”+lastname字符串,如果“,”字符串位于字符串的开头或结尾,它将被删除,因此您可以得到您想要的内容


这将产生firstname+“,”+lastname字符串,如果“,”字符串位于字符串的开头或结尾,它将被删除,因此您可以得到您想要的内容

清洁,无额外条件/库。这当然是特定于您的要求。您可以用于更复杂的需求

public static void main(String[] args) throws Exception {
    String firstName = "Stack";
    String lastName = "Overflow";
    System.out.println(printName(firstName, lastName));
}

private static String printName(String firstName, String lastName) {
    StringBuilder buffer = new StringBuilder();
    String cleanFirstName = avoidNull(firstName, "");
    String cleanLastName = avoidNull(lastName, "");
    if (!cleanLastName.isEmpty()) {
        buffer.append(cleanLastName);
    }
    if (!cleanFirstName.isEmpty()) {
        if (!cleanLastName.isEmpty()) {
            buffer.append(", ");
        }
        buffer.append(cleanFirstName);
    }
    return buffer.toString();
}

private static String avoidNull(String str, String alternate) {
    if (str == null || str.isEmpty()) {
        return alternate;
    }
    return str;
}
如果不需要,可以删除avoidNull()方法中的备用参数

private static String avoidNull(String str) {
    return str == null ? "" : str;
}

清洁,无额外条件/库。这当然是特定于您的要求。您可以用于更复杂的需求

public static void main(String[] args) throws Exception {
    String firstName = "Stack";
    String lastName = "Overflow";
    System.out.println(printName(firstName, lastName));
}

private static String printName(String firstName, String lastName) {
    StringBuilder buffer = new StringBuilder();
    String cleanFirstName = avoidNull(firstName, "");
    String cleanLastName = avoidNull(lastName, "");
    if (!cleanLastName.isEmpty()) {
        buffer.append(cleanLastName);
    }
    if (!cleanFirstName.isEmpty()) {
        if (!cleanLastName.isEmpty()) {
            buffer.append(", ");
        }
        buffer.append(cleanFirstName);
    }
    return buffer.toString();
}

private static String avoidNull(String str, String alternate) {
    if (str == null || str.isEmpty()) {
        return alternate;
    }
    return str;
}
如果不需要,可以删除avoidNull()方法中的备用参数

private static String avoidNull(String str) {
    return str == null ? "" : str;
}

只有一个布尔变量,但仍有四个分支:

public void p(String f, String l) {
    boolean e=l==null||l.isEmpty();
    System.out.println(f==null||f.isEmpty()?e?"":l:e?f:f+", "+l);
}

这肯定不是最好的方法,我还建议使用Guava或其他库,如Apache commons。

只有一个布尔变量,但仍有四个分支:

public void p(String f, String l) {
    boolean e=l==null||l.isEmpty();
    System.out.println(f==null||f.isEmpty()?e?"":l:e?f:f+", "+l);
}

这肯定不是最好的方法,我还建议使用Guava或其他库,如ApacheCommons。

我认为您不应该过多关注性能,而应该关注干净的代码

如果您只有两个字符串,您可以创建一个简单的方法,就像这个(我假设您使用的是Java8)

您可以替换
!StringUtils.isBlank(s1)
with
s1=空%%!s1.trim().isEmpty()


如果您想创建更通用的方法,在该方法中您可以决定使用哪个分隔符,并且哪个分隔符能够接受两个以上的字符串,您可以使用

public static String joinWithourEmptyOrNull(String delimiter, String... words) {
    StringJoiner sj = new StringJoiner(delimiter);
    for (String s : words) {
        if (!StringUtils.isBlank(s))
            sj.add(s);
    }
    return sj.toString();
}
您还可以将此代码重写为可读性更强的代码(至少对于熟悉streams和Lambda的人来说,您不必是guru:D)

演示:


结果
firstName,secondName

我认为您不应该过于关注性能,而应该关注干净的代码

如果您只有两个字符串,您可以创建一个简单的方法,就像这个(我假设您使用的是Java8)

您可以替换
!StringUtils.isBlank(s1)
with
s1=空%%!s1.trim().isEmpty()


如果您想创建更通用的方法,在该方法中您可以决定使用哪个分隔符,并且哪个分隔符能够接受两个以上的字符串,您可以使用

public static String joinWithourEmptyOrNull(String delimiter, String... words) {
    StringJoiner sj = new StringJoiner(delimiter);
    for (String s : words) {
        if (!StringUtils.isBlank(s))
            sj.add(s);
    }
    return sj.toString();
}
您还可以将此代码重写为可读性更强的代码(至少对于熟悉streams和Lambda的人来说,您不必是guru:D)

演示:


result
firstName,secondName

如果只有两个字符串,并且它们是空的,而不是空的,我会选择

System.out.println(
    lastName
    + (( firstName.length() > 0 && lastName.length() > 0 ) ? ", " : "")
    + firstName
);
说明:只有当两个字符串均为非空时,中间表达式才会是“,”

在所有其他情况下,中间部分和一个或两个其他部分都是空的。因此,只打印完整的一面

如果要按照StringUtils的定义,代码是:

System.out.println(
    StringUtils.stripToEmpty(lastName)
    + (( StringUtils.isNotBlank(firstName) && StringUtils.isNotBlank(lastName) ) ? ", " : "")
    + StringUtils.stripToEmpty(firstName)
);

如果只有两个字符串,它们是空的,不是空的,我会选择

System.out.println(
    lastName
    + (( firstName.length() > 0 && lastName.length() > 0 ) ? ", " : "")
    + firstName
);
说明:只有当两个字符串均为非空时,中间表达式才会是“,”

在所有其他情况下,中间部分和一个或两个其他部分都是空的。因此,只打印完整的一面

如果要按照StringUtils的定义,代码是:

System.out.println(
    StringUtils.stripToEmpty(lastName)
    + (( StringUtils.isNotBlank(firstName) && StringUtils.isNotBlank(lastName) ) ? ", " : "")
    + StringUtils.stripToEmpty(firstName)
);

看我读了那个链接上的答案,Joiner会检查空格吗?是的