it-swarm.com.de

Suchen nach einer nicht leeren, nicht leeren Zeichenfolge in Java

Ich versuche zu prüfen, ob ein Java-String nicht null, nicht leer und kein Leerzeichen ist. 

Meines Erachtens hätte dieser Code für den Job durchaus passen sollen. 

public static boolean isEmpty(String s) {
    if ((s != null) && (s.trim().length() > 0))
        return false;
    else
        return true;
}

Laut Dokumentation sollte String.trim() so funktionieren:

Gibt eine Kopie der Zeichenfolge zurück, wobei führende und nachgestellte Leerzeichen weggelassen werden.

Wenn dieses String-Objekt eine leere Zeichenfolge darstellt oder die ersten und letzten Zeichen der durch dieses String-Objekt dargestellten Zeichenfolge größere Codes als '\u0020' (Leerzeichen) haben, wird ein Verweis auf dieses String-Objekt zurückgegeben. 

Apache/commons/lang/StringUtils.Java macht es jedoch etwas anders. 

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;
}

Gemäß der Dokumentation Character.isWhitespace() :

Bestimmt, ob das angegebene Zeichen Leerraum gemäß Java ist. Ein Zeichen ist nur dann ein Java-Whitespace-Zeichen, wenn es eines der folgenden Kriterien erfüllt:

  • Es handelt sich hierbei um ein Unicode-Leerzeichen (SPACE_SEPARATOR, LINE_SEPARATOR oder PARAGRAPH_SEPARATOR), jedoch nicht um ein Leerzeichen ('\u00A0', '\u2007', '\u202F').
  • Es ist '\t', U + 0009 HORIZONTALE TABULATION.
  • Es ist '\n', U + 000A LINE FEED.
  • Es ist '\u000B', U + 000B VERTICAL TABULATION.
  • Es ist '\f', U + 000C FORM FEED.
  • Es ist '\r', U + 000D CARRIAGE RETURN.
  • Es ist '\u001C', U + 001C FILE SEPARATOR.
  • Es ist '\u001D', U + 001D GROUP SEPARATOR.
  • Es ist '\u001E', U + 001E RECORD SEPARATOR.
  • Es ist '\u001F', U + 001F UNIT SEPARATOR.

Wenn ich mich nicht irre - oder vielleicht gerade nicht richtig lese - sollte die String.trim() alle Zeichen entfernen, die von Character.isWhiteSpace() geprüft werden. Alle sehen oben '\u0020'

In diesem Fall scheint die einfachere Funktion isEmpty alle Szenarien abzudecken, die die längere Variable isBlank abdeckt.

  1. Gibt es eine Zeichenfolge, durch die sich isEmpty und isBlank in einem Testfall unterschiedlich verhalten?
  2. Angenommen, es gibt keine, gibt es eine andere Überlegung, aus der ich isBlank wählen und nicht isEmpty verwenden sollte?

Für diejenigen, die wirklich an einem Test interessiert sind, hier die Methoden und Unit-Tests. 

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;
    }
}

Und Unit-Tests 

@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) ;       

}

Update: Es war eine wirklich interessante Diskussion - und deshalb liebe ich Stack Overflow und die Leute hier. Übrigens, als wir auf die Frage zurückkamen, bekamen wir:

  • Ein Programm, aus dem hervorgeht, dass sich alle Charaktere anders verhalten. Der Code ist unter https://ideone.com/ELY5Wv . Danke @Dukeling. 
  • Ein leistungsbezogener Grund für die Wahl des Standards isBlank(). Danke @devconsole. 
  • Eine ausführliche Erklärung von @nhahtdh. Danke, Kumpel. 
61
partha

Gibt es eine Zeichenfolge, durch die sich isEmpty und isBlank in einem Testfall unterschiedlich verhalten?

Beachten Sie, dass Character.isWhitespace Unicode-Zeichen erkennen und true für Unicode-Whitespace-Zeichen zurückgeben kann.

Bestimmt, ob das angegebene Zeichen Leerraum gemäß Java ist. Ein Zeichen ist nur dann ein Java-Whitespace-Zeichen, wenn es eines der folgenden Kriterien erfüllt:

  • Es handelt sich hierbei um ein Unicode-Leerzeichen (SPACE_SEPARATOR, LINE_SEPARATOR oder PARAGRAPH_SEPARATOR), jedoch nicht um ein Leerzeichen ('\u00A0', '\u2007', '\u202F').

  • [...]

Andererseits würde die trim()-Methode alle Steuerzeichen abschneiden, deren Codepunkte unter U + 0020 und dem Leerzeichen (U + 0020) liegen.

Daher verhalten sich die beiden Methoden bei Vorhandensein eines Unicode-Whitespace-Zeichens unterschiedlich. Zum Beispiel: "\u2008". Oder, wenn die Zeichenfolge Steuerzeichen enthält, die keine Leerzeichen nach der Character.isWhitespace-Methode berücksichtigen. Zum Beispiel: "\002".

Wenn Sie dazu einen regulären Ausdruck schreiben würden (was langsamer ist als eine Schleife durch die Zeichenfolge und die Prüfung):

  • isEmpty() wäre äquivalent zu .matches("[\\x00-\\x20]*")
  • isBlank() wäre äquivalent zu .matches("\\p{javaWhitespace}*")

(Die isEmpty()- und isBlank()-Methode erlauben beide eine null-String-Referenz, sodass sie nicht genau der Regex-Lösung entspricht, aber abgesehen davon ist sie gleichwertig.).

Beachten Sie, dass \p{javaWhitespace}, wie sein Name impliziert, eine Java-spezifische Syntax für den Zugriff auf die durch die Character.isWhitespace-Methode definierte Zeichenklasse ist.

Angenommen, es gibt keine, gibt es eine andere Überlegung, aus der ich isBlank wählen und nicht isEmpty verwenden sollte?

Es hängt davon ab, ob. Ich denke jedoch, dass die Erklärung in dem obigen Teil ausreichend sein sollte, damit Sie entscheiden können. Um den Unterschied zusammenzufassen:

  • isEmpty() betrachtet die Zeichenfolge als leer, wenn sie nur Steuerzeichen enthält1 unter U + 0020 und Leerzeichen (U + 0020)

  • isBlank betrachtet die Zeichenfolge als leer, wenn sie nur Whitespace-Zeichen enthält, wie von der Character.isWhitespace-Methode definiert, die Unicode-Whitespace-Zeichen enthält.

1 Es gibt auch das Steuerzeichen bei U+007F DELETE, das von der trim()-Methode nicht getrimmt wird.

32
nhahtdh

Der Zweck der beiden standard -Methoden besteht darin, zwischen diesen beiden Fällen zu unterscheiden: 

org.Apache.common.lang.StringUtils.isBlank(" ") (gibt true zurück).

org.Apache.common.lang.StringUtils.isEmpty(" ") (gibt false) zurück.

Ihre benutzerdefinierte Implementierung von isEmpty() gibt true zurück.


UPDATE:

  • org.Apache.common.lang.StringUtils.isEmpty() wird verwendet, um herauszufinden, ob der String die Länge 0 oder null hat.

  • org.Apache.common.lang.StringUtils.isBlank() geht einen Schritt vorwärts. Es wird nicht nur geprüft, ob der String die Länge 0 oder Null hat, sondern auch, ob es sich nur um einen Whitespace-String handelt.

In Ihrem Fall schneiden Sie den String in der Methode IhrerisEmpty ab. Der einzige Unterschied, der jetzt auftreten kann, kann nicht auftreten (der Fall, den Sie ihm geben, " "), weil Sie trimmen it (Entfernen des nachgestellten Leerraums - was in diesem Fall ist, als wäre all Leerzeichen).

25
Maroun

Ich würde isBlank() über isEmpty() wählen, da trim() ein neues String-Objekt erstellt, das später gesammelt werden muss. isBlank() erstellt dagegen keine Objekte.

14
devconsole

Sie können sich die JSR 303 Bean Validtion ansehen, die Annotatinos @NotEmpty und @NotNull enthält. Die Bean-Validierung ist cool, da Sie Validierungsprobleme von der ursprünglichen Absicht der Methode trennen können. 

4
Lukas Eichler

Warum können Sie nicht einfach einen verschachtelten ternären Operator verwenden, um dies zu erreichen. Schauen Sie sich den Beispielcode an 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)); }

und die Ausgabe ist wie folgt 

1 falsch 2 falsch 3 wahr

hier gibt das 1. 2 Szenario den Wert false (d. h. null und leer) und das 3. Szenario den Wert true zurück

1
Ancel Litto
<% 
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}
<%} %>
0
arjunsekar1991

Dieser einfache Code reicht aus:

public static boolean isNullOrEmpty(String str) {
    return str == null || str.trim().equals("");
}

Und die Unit-Tests:

@Test
public void testIsNullOrEmpty() {
    assertEquals(true, AcdsUtils.isNullOrEmpty(""));
    assertEquals(true, AcdsUtils.isNullOrEmpty((String) null));
    assertEquals(false, AcdsUtils.isNullOrEmpty("lol    "));
    assertEquals(false, AcdsUtils.isNullOrEmpty("HallO"));
}
0
Laurent

Mit Java 8 können Sie auch die optionale Funktion mit Filterung verwenden. Um zu überprüfen, ob eine Zeichenfolge leer ist, handelt es sich um reines Java SE ohne zusätzliche Bibliothek .. Der folgende Code veranschaulicht eine isBlank () - Implementierung.

String.trim () Verhalten

!Optional.ofNullable(tocheck).filter(e -> e != null && e.trim().length() > 0).isPresent()

Verhalten von StringUtils.isBlank ()

Optional.ofNullable(toCheck)
    .filter(e -> 
        {
            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;

        })
    .isPresent()
0