Java two equal Strings are not equal - java

I have the following problem: I have a String that I read from a MySQL Database (with the JDBC driver) and have to compare it with another String that I receive over TCP with a BufferedReader. When I use String.equals, false is returned even if the Strings are exactly equal, I even printed both Strings to the console to make sure there aren't any typos or null objects. String.compareTo returns a negative number around -100.
I am really confused here and have no concrete idea how to fix that. Maybe it's related to the database's encoding (UTF-8)?
As requested, here is my code snippet:
public TeleportSign getTeleportSign(String target) {
// I used a HashMap, but I switched to an ArrayList in order to be able
// to compare the Strings directly.
//return signs.get(target);
for(TeleportSign s : signsList) {
// I am printing the Strings here. I even put stars to the left
// and the right of the String to make sure there are no
// spaces or new lines. s.getTarget() returns the String from the DB,
// target is the String sent over TCP.
System.out.println("*" + s.getTarget() + "* " +
String.valueOf(s.getTarget().compareTo(target))
+ " *" + target + "*");
if(s.getTarget().compareTo(target) == 0)
return s;
}
return null;
}
And the console output is:
*TDM1* -84 *TDM1*
Thanks in advance!
Captain

So I rebooted the entire system and retried. Everything works now as expected. I can't explain this to myself because I restarted the JVM multiple times and nothing happened, and a system reboot shouldn't affect a Java program like this.
I am sorry for everyone's time I wasted, but I really appreciate your quick help anyways.
EDIT: I use the trim method from String now. This method cuts off any leading null characters to prevent issues like this one. I hope this will be helpful for someone who has the same problem!

Related

java spacing when writing to a file

just a beginner in java doing a simple reading file processing some data and writing to a file, however whenever I print to a file I get this inconsistent spacing such as shown below. Especially the zeros are throwing me off. Right now I am padding the strings with empty spaces but I am sure there are better suggestions out there to have consistent spacing between strings in a file. Thanks for the help. I have attached a picture of the inconsistent printing, especially the zeros.
In Apache Commons StringUtils library there are convenient methods to set the proper pad - e.g. rightPad seems to be useful in your case - you could make something like
String row = StringUtils.rightPad(firstValue, lengthOfTheLongestValueInColumn1 + definedColumnMargin) + StringUtils.rightPad(secondValue, lengthOfTheLongestValueInColumn2 + definedColumnMargin) // + ... etc
If these lengthOfTheLongestValueInColumn variables would be calculated dynamically then it would work perfectly but you could also just hardcode some reasonable value (if you know that no value will be longer than, let say, 20 it could have value of 20)
I think best option will be to use String format
return String.format("%1$" + length + "s", inputString)
where length is max size of your digit
you can read more here

Why does IntelliJ wants me to change this?

A simple line of code:
String thing = "Something";
thing += " something else" + " and more.";
IntelliJ IDEA offers to change this line into 4 other ways to accomplish the same result:
String.format()
StringBuilder.append()
java.text.MessageFormat.format()
Replace += with =
Why? What is so wrong with +=? Can anyone explain this please? Thanks.
In general case, the result is not the same. + operator allocates intermediate string, which requires additional memory.
String thing = "Something";
thing += " something else" + " and more."; // two allocations: to compute string inside expression ```" something else" + " and more."```` and to execute ```+=```
By using StringBuilder you don't allocate intermediate result, e.g. less memory is needed.
In your case with short lines and without loops no actual performance boost is expected. However with loops you receive O(N^2) complexity. Please check this answer with explained example.
I am assuming you are referring to this:
This is not actually a fix "problem" with your code, as indicated by the pencil icon. Fixes to problems with your code are identified with a lightbulb, such as not using the value of thing:
The pencil just means "here's a shortcut to change your code, so you don't have to change it manually". Changing a a += b to a = a + b usually isn't that much work, but other things, like changing a for-each loop to a regular for loop, is.
This could be useful if you suddenly remembered that you need the index of the array for something.

Cant compare strings? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
This is extremely odd. I am simply comparing two strings, which are the same, but they aren't comparing properly. text is a string I extract from a user conversation (it is trimmed):
String compareThis = sharedPrefs.getString("key", "default").toLowerCase().trim();
if (text.equals(compareThis)){
Toast.makeText(lol, "Good, strings matched :)", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Should be " +text +" Not " +compareThis, Toast.LENGTH_SHORT).show();
}
Now look, this code looks simple enough, but the conditional is going into the else even though the strings are equal...Now you're thinking thats because the strings aren't equal. No, because I get this toast:
Should be hello Not hello
WHAT?! Those are the same string?! The toast even shows that those are the same...Why is the comparison not working if they are both "hello"?
Thanks,
Ruchir
This is extremely odd. I am simply comparing two strings, which are the same, but they aren't..
are you sure they are the same strings ???
try get bytes and compare them (by bytes) or use codepoints
try {
byte[] bytesStr1 = Str1.getBytes("UTF-8");
byte[] bytesStr2= Str2.getBytes("UTF-8");
if(bytesStr1.length!=bytesStr.length)log("no match = size");
for(int b=0;b<bytesStr1.length;b++) {
if(bytesStr1[b] != bytesStr2[b])
return log("no match at pos: "+ b);
}
} catch (UnsupportedEncodingException e) {
// handle exception here
}
there could be many reasons why the string comparison fails -
for example
space vs. non breaking space <- trim will not help you here
simple example:
String oldString = "\uD800";
String newString = new String(oldString);
String newString = new String(oldString.getBytes("UTF-8"), "UTF-8");
newString.equals(oldString) // ???? false
small appeal:
most of your(by this i mean most people here) problems can be solved by reading and understanding the basics :) - but instead you are all "drowning" from big "water"
Okay, I tried what you said and went byte by byte, but they were all the same. Also, the lengths were the same.. – Ruchir Baronia
so this mean that both strings "in your definition" are equals
instead of compare method you can use :
int pos = String.indexOf(String); //this will return you the firs position where the two strings don't match
method implementation is similar to method which i wrote on the beginning of this post
lecture:
https://docs.oracle.com/javase/tutorial/java/data/comparestrings.html
now when we we code for android I recommend to take special attention - because google is rewriting most of java classes by itself String class from Oracle is not the same as Google String class because they don't run straight on ORACLE JVM !!! - see ART (Android Runtime) - every time when i visit google & browse repos i see code changes in google api & source code of android i see much more things rewrite in pure c (as native) - google wants to break with proprietary oracle java thus is using more of open jdk implementations

Finding palindrome String throws StringIndexOutOfBoundsException, possible cause?

Provided a String, my objective is to check if I can make that String a palindrome string even after re-arranging the characters.
For eg: aaabbbb can be made palindrome by changing to : bbaaabb
So what I did try is to compare all the permutations of the string with its reverse, if it exists, print a YES! . And here is the code so far:
private static void permutation(String prefix, String str)
{
temp.setLength(0); //temp is a StringBuilder
int n = str.length();
if((n==0) && (str.charAt(0)==str.charAt(n-1)))
{
temp.append(prefix);
temp.reverse();
if(prefix.equals(temp.toString()))
{
System.out.println("YES");
System.exit(0);
}
}
else
{
for(int i=0;i<n;i++)
permutation(prefix+str.charAt(i),str.substring(0,i)+str.substring(i+1,n));
}
}
Now the problem is, at runtime I get a java.lang.StringIndexOutOfBoundsException at this line: permutation(prefix+str.charAt(i),str.substring(0,i)+str.substring(i+1,n));
What might be possibly causing this?
This line will give you the exception too:
if((n==0) && (str.charAt(0)==str.charAt(n-1)))
If n==0 then the string is empty, and charAt(0) will fail. Not sure what you're testing here.
I'm not going to debug this for you, but I will suggest a process for how to debug this kind of thing yourself.
Identify the problem. All of the detail about the palindromes is irrelevant. The problem is a java.lang.StringIndexOutOfBoundsException when calling one of the methods on the String.
Narrow in on exactly what's failing. There are several method calls in the line that is failing. If it's not obvious which method call is the problem, either single-step through it with a debugger or break that line into several lines, e.g. by creating intermediate variables to hold intermediate state.
Reproduce the problem in a simplified example. Create a new class with a main() method or write a unit test and write code that shows the problem. Remove everything that isn't absolutely essential to show the problem.
Fix your example. Once you've isolated the problem and read the documentation, it will probably be obvious how to fix it. If it's not, and you're still stuck, post the simple example on Stack Overflow and explain what you are expecting and what you're getting.
Fix your code. Apply the same fix to your original code.
String index out of bound exception -This exception is thrown by the methods of the String class, in order to indicate that an index is either negative, or greater than the size of the string itself.
In above code you are calling permutation() method recursively .
Let's say we passed String str="xy" and prefix as "" to permutation() method first time.
As its length is more than 0 it will come to the else block.
In else block we are looping str with its length.
Here length i.e n is 2.
In first loop, i=0. So prefix + str.charAt(i) will give "" + "x" = "x" and str.substring(0,i)+str.substring(i+1,n)
will give str.substring(0,0)+str.substring(0+1,2)=""+"y"="y".
Now again we are passing these values to permutation() method; i.e. permutation("x","y").
So the time when you passed these value in method, at that time instantly string str became "y" and string prefix became "x"
but still you are in loop, and in second loop i=1 and prefix+str.charAt(1) i.e. "x"+"y".charAt(1) will throw exception.
Here you can see string str="y", length is 1 and we are trying to get char at position 1. This is why you got this exception.

Error on customers computer

I have a java client server program that works fine on a half a dozen computere but is causing a NegativeArraySizeException on site.
This is the code
location = message.indexOf("last");
location += 5;
end = message.indexOf('&', location);
int size = end - location; THIS IS THE ERROR LINE
char[] lastC = new char[size];
message.getChars(location, location+size, lastC, 0);
String firstS = new String(firstC);
String lastS = new String(lastC);
message is an xml message I am reading.
location is an integer that points the the location of a character in the message, the first name in this case.
size is the length of the persons name.
As far as I can tell size is being set as a negative number and I don't know why.
Does anyone know how to fix this or a better was of finding the length of the name ?
This is part of the server side.
As far as I can tell size is being set as a negative number and I don't know why.
If the first call to indexOf cannot locate "last" in the message, then location will be set to -1 and then incremented by 5 to give 4.
If the second call to indexOf cannot find a '&' then end will be set to -1, and size will be negative.
Obviously, the input XML is not in the form you expect.
All in all, that code is pretty dodgy. As a minimum you should check the results of both calls to indexOf and take appropriate error reporting / recovery steps if they are -1.
But the real fix is to not attempt to "parse" XML using crufty string bashing. Use an XML parser, preferably with validation against the relevant schema or DTD. If the XML parser rejects the input, report the error back at who / whatever gave you the broken XML.
Does the message contain last at all? If not, location would be negative, and you should stop processing right there. This error might go unnoticed because you add 5 to location after that, which makes it equal to at least 4 even if last is not in the string (thanks SJuan76).
Even if the message contains last, is it guaranteed that it is followed by at least one extra character? If not, adding 5 to location would point outside the string for sure.
Moreover, end may also be negative if there is no & in the string after location. You should handle that somehow (i.e. by setting end to the length of the message in that case).
Also, if message is a string, you can simply extract a substring of it using the substring method, no need for the getChars magic.
A better solution would probably be something like this (I'm assuming that message is something like an URL and you are looking for the part between last> and the next &, based on your comment for one of the other answers):
location = message.indexOf("last>");
if (location >= 0) {
String lastS;
location += 5;
end = message.indexOf('&', location);
if (end == -1) {
// Handle the case when there is no "&" after "last>" in the message
} else {
lastS = message.substring(location, end);
}
} else {
// Handle the case when there is no "last>" in the message
}
The trouble is that end is less than location. The issue is what message are you expecting and which one you are receiving; the rest of the logic works for certain messages. Check from where you get your message String.

Categories

Resources