I think you might be misremembering or misinterpreting what IntelliJ said. Using == to check whether a string is null is perfectly fine. What you can't do is use == to check whether two non-null strings have the same contents. Answer from sepp2k on reddit.com
🌐
TutorialsPoint
tutorialspoint.com › comparing-strings-with-possible-null-values-in-java
Comparing Strings with (possible) null values in java?
In the same way the equals() method of the object class accepts two String values and returns a boolean value, which is true if both are equal (or, null) and false if not. import java.util.Scanner; public class CompringStrings { public static void main(String args[]) { Scanner sc = new Scanner(System.in); System.out.println("Enter your first string value: "); String str1 = sc.next(); System.out.println("Enter your second string value: "); String str2 = sc.next(); if(str1.equals(str2)) { System.out.println("Both Strings are null or equal"); }else { System.out.println("Both Strings are not equal"); } } }
🌐
Reddit
reddit.com › r/learnprogramming › how do i compare a generic type with null in java?
r/learnprogramming on Reddit: How do I compare a generic type with null in java?
March 21, 2023 -

I've already discovered that comparing a generic type requires you to use an int to restore the value of compareTo, but if I'm trying to check if T value == Null, java throws an error stating that the compareTo (null) method is undefined for type T.

the code I have so far is

int cmp;
if(cmp = tree.get(index).compareTo(null) == 0)

to check if the value at the index of tree == null.

Thanks in advance :)

edit: well, I actually just fixed it by deleting cmp XD

Top answer
1 of 2
2
You’re probably doing it wrong; usually you want to use some method like contains to check whether something’s not in a collection, and compareTo(null) and equals(null) are bad mojo to begin with. Syntactically, Java’s complaining because it’s breaking the text down as if(cmp = (tree.….compareTo(null) == 0)) with tree.….compareTo(null) == 0 being assigned to cmp, and if testing the value that was assigned. But == 0 provides a boolean, not an int, so you can’t assign anything==anything to cmp; and then if expects a boolean or unboxed Boolean, not an int, so that’s also invalid. If you want to save compareTo’s result en passant, you need a pair of parens around the first part, if((cmp = tree.get(index).compareTo(null)) == 0) ↑here and here↑. Now the relational result from compareTo (an actual int) is saved to cmp, and that same value is compared against 0, producing a boolean for if to consume. Fundamentally, though, compareTo and equals describe bivalent relationships which break if you try to use null in there. For example, a.compareTo(b) represents a query of whether a ⋚ b, and therefore also whether b ⋛ a, and therefore any value of a should be able to be used in b’s place and vice versa. Similarly, a.equals(b) represents a query of whether a = b, and therefore also whether b = a. So let’s play with those identities. if(tree.get(index).compareTo(null) == 0) That looks just fine; we pass null as the argument to compareTo. But changing to the ostensibly-equivalent condition if(null.compareTo(tree.get(index)) == 0) is fully illegal; null doesn’t name a specific enough type to actually find a Comparable.compareTo implementation, and even if it were specific enough, that method would be given null for its this argument, which is illegal for non-static methods and must result in a NullPointerException being thrown. Similarly, if(tree.get(index).equals(null)) is syntactically valid, but if we flip it using the semantic identity, if(null.equals(tree.get(index))) we again have a problem: null would necessarily have an equals method if it named an object, but null contributes no vtable and thus no means of determining how to actually carry out equals’ execution. (Any type’s equals might be chosen with equal correctness, including the equals of an as-yet-nonexistent type.) And of course, trying to ((Foo)null).equals(…) would trigger a NullPointerException unless you’ve found your way to a static equals method. ( java.util.Objects ’ methods can be used when you really do want to involve null more safely in compareTo, equals, and other basic methods, although compare can still throw.) So what you almost always want is either the collections .contains or .containsKey method, which directly checks whether something’s in there, or if your collection is actually permitted to contain null (really don’t, because you can’t tell whether X{k}=null or k∉X), you want to == null or != null directly.
2 of 2
1
isNull() maybe?
🌐
Medium
medium.com › @muqsithirfan › java-null-comparison-fcfbcb55ac67
Java NULL comparison. While working in Java projects I… | by Muqsith Irfan | Medium
March 25, 2017 - In order to make sure such a typo is caught during compilation, programmers just flip the comparison elements like below ... now there is no chance that the pointer ptr can be assigned to a constant NULL, hence even if some programmers write like ... This is impossible to occur in Java, because in Java “only assignment” inside the 'if' condition will lead to compilation error. ... Above code will never get compiled in Java. Overall the conclusion is, it is not required to put null as a first element in the ‘if’ comparison block.
🌐
Codemia
codemia.io › knowledge-hub › path › compare_two_objects_in_java_with_possible_null_values
Compare two objects in Java with possible null values
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises
🌐
Medium
medium.com › @AlexanderObregon › javas-objects-compare-method-explained-7a9ccda5ea74
Java’s Objects.compare() Method Explained | Medium
December 13, 2024 - However, other approaches can achieve ... that can be directly used to compare two objects. While effective, this approach does not handle null values by default....
Find elsewhere
🌐
Coderanch
coderanch.com › t › 324695 › java › compare-String-null
How to compare String with null ?? (Java in General forum at Coderanch)
Whatever value messId has, it can be converted into a String representation - which is definitely not null, or "null" - and can be safely compared to strMId. Personally, any time I get a String input from a potentially dubious source, I like to do a trim() as well to make sure there aren't any icky spaces which will mess up equals().
🌐
Coderanch
coderanch.com › t › 396208 › java › null-comparison
null comparison (Beginning Java forum at Coderanch)
I have tried the equals method and the operators, but neither compares the values correctly. Is this a special case in Java? How should I compare these? ... Hi Tyler, Compare null values are null do the following instead of using the equals method: if (ipArray[s] == null) //is null if(ipArray[s] != null) // if not null.
Top answer
1 of 2
14

it is possible to handle null pointer exception using Comparator.comparing static method. If you want to comparing loanAmount fields in your objects and you want that every not null value is greater than null you can use Comparator.nullFirst method in combination with Comparator.comparing like the below code:

Comparator.comparing(LoanAccount::getLoanAmount,
                     Comparator.nullsFirst(Comparator.naturalOrder()))

NaturalOrder is a method returning a comparator that compares Comparable objects in natural order. You can also combine more comparators in a chain with method Comparator.thenComparing like the code below:

Comparator
        .comparing(LoanAccount::getLoanAmount,
                   Comparator.nullsFirst(Comparator.naturalOrder()))
        .thenComparing(LoanAccount::getCreationDate, 
                       Comparator.nullsFirst(Comparator.naturalOrder()))
        .compare(o1, o2);

Now you can rewrite your comparator with equal behaviour shortly:

public class LoanAccountAmountComparator
        implements Comparator<LoanAccount> {

    @Override
    public int compare(LoanAccount o1, LoanAccount o2) {
        if (o1 == null && o2 == null) return 0;
        if (o1 == null) return -1;
        if (o2 == null) return 1;
        return Comparator
                .comparing(LoanAccount::getLoanAmount,
                           nullsFirst(naturalOrder()))
                .thenComparing(LoanAccount::getCreationDate,
                               nullsFirst(naturalOrder()))
                .compare(o1, o2);
    }
}

Note: the use of class Date is discouraged, it is better if you use instead the java.time package classes for time related code.

2 of 2
7

Here is another twist, roughly similar to dariosicily's proposal.

It differs in the following points:

  • It create the aggregated comparator only once, then store it in a static field. Why? Because functions such as Comparator.nullsFirst() and Comparator.comparing() implies object allocation, which you definitely want to avoid if your comparator is called from tight loops (for example, a sort or tree insertion algorithm).
  • Null checks on the LoadAccount objects themselves have also been delegated to Comparator.nullsFirst(). That means that absolutely no if statement is required!
  • I moved that comparator to a public, static field of a utility class. I have learned from personal experience that comparators on domain model objects very often come in "families". In different places, you want different sorting strategies, for the same objects. Here, for demonstration, I also included one comparator for loadAmount (that is, without fallback on tie), and another one for creationDate. But you can see how this idea can be generalized.
  • In this sample, I have adopted an uncommon indentation strategy. I think this is justified in this case because it helps make it easier to see which fields are sorted by each comparator, and in which order. This is of great importance when you have comparators that involve a significant number of fields.
    public class LoanAccountAmountComparators {

        /**
         * A comparator that sort LoanAccounts, by load's amount, in decreasing order.
         */
        public static final Comparator<LoanAccount> BY_AMOUNT = 
            Comparator.nullsFirst(
                Comparator.comparing(
                    LoanAccount::getLoanAmount, Comparator.nullsFirst(Comparator.reverseOrder())
                );
            );

        /**
         * A comparator that sort LoanAccounts, by creation date, in ascending order.
         */
        public static final Comparator<LoanAccount> BY_DATE = 
            Comparator.nullsFirst(
                Comparator.comparing(
                    LoanAccount::getCreationDate, Comparator.nullsFirst(Comparator.naturalOrder())
                );
            );

        /**
         * A comparator that sort LoanAccounts, by creation amount (in descending order),
         * then by date (in ascending order).
         */
        public static final Comparator<LoanAccount> BY_AMOUNT_AND_DATE = 
            Comparator.nullsFirst(
                Comparator.comparing(
                    LoanAccount::getLoanAmount, Comparator.nullsFirst(Comparator.reverseOrder())
                ).thenComparing(
                    LoanAccount::getCreationDate, Comparator.nullsFirst(Comparator.naturalOrder())
                );
            );
    }

It should be noted that, in this example, all fields involved are indeed some kind of objects. If, however, your comparator would involve fields containing primitive types, then you should use the corresponding Comparator.comparing<primitiveType> function (that is, never let some primitive be boxed to object only so it can be compared to Comparator.naturalOrder().

Top answer
1 of 4
3

You could write the code like this, it is doing the same, but I think it is more readable, you almost don't need any comment, to assume the return value.

private Integer compareDateStrings(BeanToDoTask arg0, BeanToDoTask arg1, String strProperty) {
    String strDate0 = BeanUtils.getProperty(arg0, strProperty);_logger.debug("strDate0 = " + strDate0);
    String strDate1 = BeanUtils.getProperty(arg1, strProperty);_logger.debug("strDate1 = " + strDate1);
    return compareDateStrings(strDate0, strDate1);
}

private Integer compareDateStrings(String strDate0, String strDate1) {
    int cmp = 0;
    if (isEmpty(strDate0)) {
        if (isNotEmpty(strDate1)) {
            cmp = -1;
        } else {
            cmp = 0;
        }
    } else if (isEmpty(strDate1)) {
        cmp = 1;
    } else {
        cmp = strDate0.compareTo(strDate1);
    }
    return cmp;
}

private boolean isEmpty(String str) {
    return str == null || str.isEmpty();
}
private boolean isNotEmpty(String str) {
    return !isEmpty(str);
}
2 of 4
6

I would use boolean variables to make the code more readable:

private int compareDateStrings(BeanToDoTask arg0, BeanToDoTask arg1, String strProperty) {
    /* Don't worry too much about this part. */
    String strDate0 = BeanUtils.getProperty(arg0, strProperty); _logger.debug("strDate0 = " + strDate0);
    String strDate1 = BeanUtils.getProperty(arg1, strProperty); _logger.debug("strDate1 = " + strDate1);

    boolean isStrDate0Empty = (strDate0 == null || strDate0.isEmpty());
    boolean isStrDate1Empty = (strDate1 == null || strDate1.isEmpty());

    if (isStrDate0Empty && isStrDate1Empty)
        return 0;
    // at least one of them is not empty    
    if (isStrDate0Empty)
        return -1;
    if (isStrDate1Empty)
        return 1;
    //none of them is empty
    return strDate0.compareTo(strDate1);
}
🌐
Oracle
docs.oracle.com › cd › E19798-01 › 821-1841 › bnbvi › index.html
NULL Comparison Expressions (The Java EE 6 Tutorial)
A NULL comparison expression tests whether a single-valued path expression or an input parameter has a NULL value. Usually, the NULL comparison expression is used to test whether a single-valued relationship has been set: ... This query selects all teams where the league relationship is not set.
🌐
Errorprone
errorprone.info › bugpattern › EqualsNull
EqualsNull
This check replaces x.equals(null) with x == null, and !x.equals(null) with x != null. If the author intended for x.equals(null) to return true, consider this as fragile code as it breaks the contract of Object.equals(). See Effective Java 3rd Edition §10: Objey the general contract when ...
🌐
Quora
quora.com › If-null-is-compared-with-null-what-is-the-result-true-or-false-null-or-unknown
If null is compared with null, what is the result, true or false, null or unknown? - Quora
SQL (three-valued logic): comparing NULL to NULL with the equality operator yields UNKNOWN (treated as false in WHERE). Example: NULL = NULL → UNKNOWN; use IS NULL to test presence: NULL IS NULL → TRUE. Java, C#, most imperative languages: "null" is a value/reference sentinel, not SQL NULL.
🌐
Coderanch
coderanch.com › t › 387952 › java › avoid-null-pitfalls-comparing-Strings
How do I avoid null pitfalls when comparing Strings? (Beginning Java forum at Coderanch)
February 7, 2001 - Here's what I'm trying to do with half-way decent looking code I'll give the psuedocode: Compare two String values to determine if they are equal. String oldvalue; String newvalue; if oldvalue == newvalue then update = false What is a pretty way to write this in Java. Both oldvalue and newvalue can have null.