Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

line = reader.readline() result does not behave same as a literal "F"

I was trying to develop a command line interface test first using a technique described in Jeff Langr's book Agile Java, but I can not figure out why:

line = reader.readline(); result does not behave same as a literal "F" in my code.

This works...rover moves forward to 1:

private void goForward() {
        rover.move("F");
    }

This does not work...rover remains at 0:

private void goForward() throws IOException {
    StringBuffer input = new StringBuffer();
    input.append(line("F"));
    byte[] buffer = input.toString().getBytes();
    InputStream inputStream = new ByteArrayInputStream(buffer);
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    BufferedReader reader = new BufferedReader(inputStreamReader);  
    String line = reader.readLine();
    rover.move(line);
}

private String line(String str) {
    return String.format("%s%n", str);
}

I have done everything I can think of:

I added several

System.out.println(line);

to look at the values for line before and after and everything looks okay.

But looks can be deceiving so I added an

if(line.equals("F"))

thinking this would prove they are actually different but it evaluates to True

And spent several hours with my debugger, Javadocs and searching the Internet. I have learned a lot along the way but nothing that explains what is happening.

Any assistance would be greatly appreciated. I am sure I am missing some fine nuance that plague novices like myself. Thanks.

like image 454
bravogolfgolf Avatar asked Dec 04 '25 12:12

bravogolfgolf


1 Answers

Ok, after reading your comment, I have a better answer... (First one was completely wrong, sorry):

Strings should NEVER be compared via ==, because that will only be true if it's the same OBJECT (and not the same STRING). Use equals().

It only works with constant "F", because the compiler takes all constant "F"s and uses the same String for them. But as soon as you have a dynamic String, coming from the "outside" during Runtime, it will be a totally different object, for which == will be FALSE, while equals will be TRUE.

String x = "F";
// Might be true, because the compiler will use ONE object 
// for both instances of "F". It's still bad and should not be done.
boolean isF = x == "F";

String y = new Scanner(System.in).nextLine();
// Will NEVER be true, even if you entered "F", because
//  y will always be a NEW String object...
isF = y == "F"; 
// Will be true, if you entered "F"
isF = "F".equals(y);
like image 56
Florian Schaetz Avatar answered Dec 06 '25 00:12

Florian Schaetz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!