Oliver Mahoney
Oliver Mahoney

Reputation: 706

Java .contains() not behaving as I expected

I have a problem where .contains() is not returning true when looking for a substring.

See the below code snippet and image which shows variable values for the following code. The problem I have is that the expression returns false, when I think it should obviously be true.

if (this.fileName.toLowerCase().contains(extension.toLowerCase())){
  return true;
}

Screen grab of debug showing variable values at runtime

I have encountered this today, after searching the web I can't see anything obvious that is going on here.

I have tried the same using literals, but still does not evaluate to true:

if ("Android App Image.jpg".toLowerCase().contains("jpg".toLowerCase())){
  return true;
}

I have broken it down further so the result is in a boolean:

boolean result = ("Android App Image.jpg".contains("jpg"));

if (result) {
  return true;
}

The result is true, so .contains is not the issue, rather it appears my if() doesn't evaluate the boolean as true and doesn't cause return true to execute.

I now think it's an issue with my while loop (full function below). Does the enumeration run asynchronously?

public boolean isImage(){
    String[] imageExtensions = {"jpg", "png", "bmp", "gif"};

    for (String extension: imageExtensions) {

        if (this.localFileURLString != null && this.localFileURLString.toLowerCase().contains(extension)){
            return true;
        }

        boolean result = ("Android App Image.jpg".toLowerCase().contains("jpg".toLowerCase()));

        if (result) {
            return true;
        }else{
            Log.i("TEACH", "If evaluated false");
        }
    }

    return false;
}

UPDATE 1/2:

I have trimmed down the entire function, with hard coded literals and no longer using fast enumeration, which still returns false when I expect it to return true:

public boolean isImage(){
    String[] imageExtensions = {"jpg", "png", "bmp", "gif"};

    for (int x = 0; x < imageExtensions.length; x++) {

        // String extension = imageExtensions[x];

        boolean result = ("Android App Image.jpg".toLowerCase().contains("jpg".toLowerCase()));

        if (result) {
            return true;
        }else{
            Log.i("TEACH", "If evaluated false");
        }
    }

    return false;
}

The function does not returns true or does the "If evaluated false" Log get executed, it just jumps straight to the last line of the function (return false;) after evaluating the line if (result) {... it's as if the if breaks the loop.

UPDATE 2/2:

Quite simply, even the most simple of if statements inside my function would cause the code to jump to the last line of the function and return false. For example:

if(true == true){
  return true
}

This happened when stepping through in debug mode and also coded logs show the same result when not attached to a bugger.

After returning from the function every carries on as normal. No errors or warnings.

re-installing Android Studio, trying different simulators and physical Android devices didn't resolve the issue.

Renaming the function didn't resolve the issue.

Changing the return type of the function from boolean to Boolean did resolve the issue.

I'm well aware of the differences in these types, but I'm still perplexed as to to why this would this this problem. I can only assume changing the method signature in this way solved is something funky was happening at compile time.

I'll leave the question open for now, as even though changing the return type "fixed" the issue for me, i'm still not satisfied i'll know why... probably never will.

Hopefully somebody much more knowledgable on these sorts of issues can enlighten is all!

Upvotes: 0

Views: 1160

Answers (2)

App Work
App Work

Reputation: 22039

Your search term produces false positive . Cause the file name string can have a substring that matches the extension. To avoid this you can prepend the search terms by a dot.

String[] imageExtensions = {".jpg", ".png", ".bmp", ".gif"};

This will apperantly solve your problem . It can produce false positive if there's any irregular use of DOT in the file name. Hope it helps.

Upvotes: 0

C-Spydo
C-Spydo

Reputation: 799

Why don't you try using:

if (this.fileName.toLowerCase().contains(extension.toLowerCase()==true){
}

Upvotes: 1

Related Questions