0

Looking for a way (OK with using Apache libs as well), to compare two String in Java with possible null/empty values, where the main requirement is when if one is null and another is empty ("") it will return true.

Emphasizing - any null/empty combination allowed, and all the combinations would be considered a true statement.

one   | two  | res
------|------|-----
 ""   | ""   | true
 ""   | null | true
 null | ""   | true
 null | null | true

I've checked many related questions here, and they are not considering my main requirement.

2
  • 3
    Is any null/empty combination allowed, or are you looking e.g. only for the first string to be null and the second empty (or vice-versa) ? Commented Feb 7, 2024 at 7:53
  • 2
    return one == null || one.isEmpty()? two == null || two.isEmpty(): one.equals(two); That’s the literal translation of your conditions. Commented Feb 7, 2024 at 14:30

3 Answers 3

6
public static boolean isEqual(String one, String two) {
    // org.apache.commons.lang.StringUtils
    return StringUtils.defaultIfEmpty(one, "")
            .equals(StringUtils.defaultIfEmpty(two, ""));
}

Output:

 one  | two  | res
------|------|-----
 ""   | ""   | true
 ""   | null | true
 null | null | true

Alternatives:

public static boolean isEqual(String one, String two) {
    if (one == null) one = "";
    if (two == null) two = "";    
    return one.equals(two);
}
public static boolean isEqual(String one, String two) {
    one = Objects.requireNonNullElse(one, "");
    two = Objects.requireNonNullElse(two, "");
    return one.equals(two);
}
Sign up to request clarification or add additional context in comments.

3 Comments

There’s no need to use Objects.equals(…) when null has been substituted already. You can use return (one == null ? "" : one).equals(two == null ? "" : two); Or you use return Objects.requireNonNullElse(one, "").equals(Objects.requireNonNullElse(two, "")); which has a similar logic as the StringUtils approach but doesn’t require an external library.
I know it. But this syntax is not very clear. I prefer my implementation. But for Objects.requireNonNullElse() thank you.
“You can separate the equals call and the conditionals” (as you did in the edit) was also my first thought after reading your comment. Note that the good old if would also work, if(one == null) one = ""; if(two == null) two =""; return one.equals(two); I agree that the combined conditionals and equals call might be hard to read.
0

You can use a wrapper class overriding equals(Object) and hashCode().

public final class StringWrapper {

  private final String value;

  private StringWrapper(String value) {
    this.value = value;
  }

  public static StringWrapper ofValue(String value) {
    return new StringWrapper(value);
  }

  public static StringWrapper ofNull() {
    return ofValue(null);
  }

  public static StringWrapper ofEmpty() {
    return ofValue("");
  }

  @Override
  public int hashCode() {
    if (value == null || value.isEmpty()) {
      return 0;
    }
    return value.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof StringWrapper wrapper)) {
      return false;
    }
    String value1 = Objects.requireNonNullElse(value, "");
    String value2 = Objects.requireNonNullElse(wrapper.value, "");
    return Objects.equals(value1, value2);
  }

  @Override
  public String toString() {
    return "Wrapper - " + value;
  }
}

And tests covering the scenarios:

public class StringWrapperTests {

  @Test
  public void sameStringValues_ShouldReturnTrue() {
    StringWrapper first = StringWrapper.ofValue("a");
    StringWrapper second = StringWrapper.ofValue("a");
    assertEquals(first, second);
    assertEquals(second, first);
  }

  @Test
  public void differentValues_ShouldReturnFalse() {
    StringWrapper first = StringWrapper.ofValue("a");
    StringWrapper second = StringWrapper.ofValue("b");
    assertNotEquals(first, second);
    assertNotEquals(second, first);
  }

  @Test
  public void bothEmpty_ShouldReturnFalse() {
    StringWrapper first = StringWrapper.ofEmpty();
    StringWrapper second = StringWrapper.ofEmpty();
    assertEquals(first, second);
    assertEquals(second, first);
  }

  @Test
  public void firstNullSecondEmpty_ShouldReturnTrue() {
    StringWrapper first = StringWrapper.ofNull();
    StringWrapper second = StringWrapper.ofEmpty();
    assertEquals(first, second);
  }

  @Test
  public void firstEmptySecondNull_ShouldReturnTrue() {
    StringWrapper first = StringWrapper.ofEmpty();
    StringWrapper second = StringWrapper.ofNull();
    assertEquals(first, second);
  }

  @Test
  public void bothNull_ShouldReturnTrue() {
    StringWrapper first = StringWrapper.ofNull();
    StringWrapper second = StringWrapper.ofNull();
    assertEquals(first, second);
    assertEquals(second, first);
  }

  @Test
  public void firstNullSecondValue_ShouldReturnFalse() {
    StringWrapper first = StringWrapper.ofNull();
    StringWrapper second = StringWrapper.ofValue("qwerty");
    assertNotEquals(first, second);
  }

  @Test
  public void firstValueSecondNull_ShouldReturnFalse() {
    StringWrapper first = StringWrapper.ofValue("asd");
    StringWrapper second = StringWrapper.ofNull();
    assertNotEquals(first, second);
  }
}

Comments

-3

try to use the hutool

boolean answer(String str1, String str2) {
    if (StrUtil.isEmpty(str1) && StrUtil.isEmpty(str2)) {
        return true;
    }
    if (StrUtil.equals(str1, str2)) {
        return true;
    }
    return false;
}

1 Comment

You need to indicate where StrUtil comes from by using the full package name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.