简体   繁体   中英

Java String.equals() method doesn't return true or false

I have the following code running on Android that compares two strings and returns the object field, if its variable is equal to id .

The values are never null , and there's one case when I have id = "m1" and var = "m1" . ( getFields() retrieves the fields from a MongoDB database.)

By watching the expression var.equal(id) on debug mode, I see it returns true , but it doesn't go into either one of the if s below (it does enter the loop.) What is going on here?

public Field getField(String id) {
    for (Field field : getFields()) {
        String var = field.getProperties().getVariable();

        // I know I'm not supposed to do like this.
        // This is just for debug purposes.
        if (!var.equals(id)) {
            // Doesn't get into here
            Log.d("Different?", "Yes.");
        }

        if (var.equals(id)) {
            // Doesn't get into here either
            return field;
        }
    }
    return null;
}

tldr; The diagnoses is incorrect and should be reevaluated. It isn't unheard of for a debugger to report misleading information (or even introduce side-effects), but the actual Dalvik run-time/classes have well-defined behavior.

For any given strings (where null is not a string), represented by x and y, it is always the case that x.equals(y) == y.equals(x) and the output is deterministic based only on the two input strings 1 .

While it is better to use if/else, by the deterministic nature of the equals (and usage of such in the provided code), the following semantic equivalency holds:

if (x.equals(y)) { a; }
else { b; }
// -- and --
if (x.equals(y)) { a; }
if (!x.equals(y)) { b; }

That is, exactly one of {a, b} must execute - iff that code runs at all and no exceptions are thrown.


1 The only way this can differ is if the variables are reassigned between the calls; since they are both local variables then there is no potential threading issue. Because strings are immutable it is also guaranteed that there is no way to change the result of the String.equals function, provided the same string objects are supplied.

String.equals compares this string to the specified object. The result is true if and only if the argument .. represents the same sequence of characters as this object.

Your method is better written as:

public Field getField(final String id) throws IllegalArgumentException {
    for (Field field : getFields()) {
        String var = field.getProperties().getVariable();

        if (var.equals(id)) {
            // match found
            return field;
        } else {
            // no match
            Log.d("Different?", "Yes.");
        }
    }
    throw new IllegalArgumentException("No match for " + id + " found!");
}

It appears maybe your id is not really included in getFields() return, and/or it's in a different case than you expect.

You could try:

if (var.equalsIgnoreCase(id))

This will check for upper and lower case values.

And if you are returning null (from your original method) or catching the IllegalArgumentException from my re-write, then this means no match was found, ie. your id is not really included in the return from getFields() .

For debugging you can print all of the returned fields:

for (Field field : getFields()) {
    System.out.println(field.getProperties().getVariable());
    // do your stuff

}

Another debug option:

public Field getField(final String id) throws IllegalArgumentException {

    Field[] fields = getFields();
    System.out.println("How many fields? " + fields.length);

    for (Field field : getFields()) {
        String var = field.getProperties().getVariable();

        System.out.println("Variable var is: " + var);
        System.out.println("Variable id is: " + id);

        if (var.equals(id)) {
            // match found
            return field;
        } else {
            // no match
            Log.d("Different?", "Yes.");
        }
    }
    throw new IllegalArgumentException("No match for " + id + " found!");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM