0

I'm working on Library management project in which there is one column "available". I'm fetching value from it. if a value is "Yes" then only a new book will be issued. here is the code that I have tried.

       try {
        
        String a = checkStatus();
        String b = "Yes";
        System.out.println("a: "+a);
        System.out.println("b: "+b);
        if(a.equalsIgnoreCase(b))
        {
            System.out.println("working in if");
        }
        else
        {
            System.out.println("shoot! Fallout :(");
        }
    } catch (SQLException ex) {
        Logger.getLogger(IssueBook.class.getName()).log(Level.SEVERE, null, ex);
    }

Output:

a: Yes

b: Yes

shoot! Fallout :(

it should have return true instead of false. Where I'm making mistake? Thanks!

shubham kumbhar
  • 47
  • 1
  • 2
  • 10
  • Try to set a debug point after `String b = ...` and take a look at the bytes of both `String`s. Maybe there is some sneaky character in the `String a`. – Turing85 Apr 17 '22 at 10:09
  • [Can't reproduce the described behaviour](https://ideone.com/m2rHvD). Either `checkStatus();`does not return "Yes", or the code you posted is not the actual code you're running. – JustAnotherDeveloper Apr 17 '22 at 10:09

2 Answers2

2

Most likely those strings aren't actually equal. They contain a character that you can't see.

It's that or you aren't running the code you pasted, so it's a problem in your build setup.

For example, the string contains a byte order mark.

The way to figure this out is to go through each string and print char-by-char. Replace your 'shoot!' line with:

System.out.print("Not equal!\nA: ");
printPerChar(a);
System.out.println("B: ");
printPerChar(b);

....

void printPerChar(String in) {
  System.out.print(in.length());
  System.out.print(": ");
  for (char c : in.toCharArray()) {
    System.out.print(c + " (" + ((int) c) + ") ");
  }
  System.out.println();
}

And you'll see e.g. byte order marks, extra spaces, zero-length spaces, unicode characters that look exactly like 'Y', 'e', or 's', etcetera.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Not equal! A: 4: Y (89) e (101) s (115) (32) B: 3: Y (89) e (101) s (115) shoot! Fallout :( – shubham kumbhar Apr 17 '22 at 10:25
  • 1
    See, there you go. your `String a` is `"Yes "` <-- it has a trailing space character. Either `.trim()` the arguments or better yet, find the code that inserted this string in the database and fix the bug there, because surely writing `Yes ` (with that space) is a bug. Aftually, writing 'Yes' in the first place is _wild_. databases have the concept of a BOOLEAN column. Use that, putting 'Yes'/'No' in a VARCHAR column is rather silly. – rzwitserloot Apr 17 '22 at 10:26
1

Code points

The Answer by rzwitserloot is very good. I would suggest using code point integers rather than char. The char type is legacy, and problematic.

String input = "Dog  Cat" ;
int[] codePoints = input.codePoints().toArray() ;
for( int codePoint : codePoints )
{
    System.out.println( "Code point " + codePoint + " is: " + Character.getName( codePoint ) ) ;
}

See this code run live at IdeOne.com. Notice the two different kinds of space characters in the middle.

Code point 68 is: LATIN CAPITAL LETTER D
Code point 111 is: LATIN SMALL LETTER O
Code point 103 is: LATIN SMALL LETTER G
Code point 32 is: SPACE
Code point 160 is: NO-BREAK SPACE
Code point 67 is: LATIN CAPITAL LETTER C
Code point 97 is: LATIN SMALL LETTER A
Code point 116 is: LATIN SMALL LETTER T

You can compare two int arrays of code points.

System.out.println(
    Arrays.equals(
        "Dog  Cat".codePoints().toArray() ,  // 2nd space-character is NO-BREAK SPACE.
        "Dog  Cat".codePoints().toArray()    // 2nd space-character is SPACE. 
    )
);

false

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154