Java - If statement not catching when variable equals string [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I compare strings in Java?
(This may be a duplicate, I was not aware of .equals. My apologies.)
I was messing around in Java today when I decided to make a 4 character string generator. I have the program generate every possible combination of characters that I defined. This isn't for a project, I just wanted to see if this was possible. My problem lies with the string checking. I'll post the code first.
String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char[] chars = text.toCharArray();
String name = "Mike";
String pass;
outerLoop:
for (int a = 0; a < chars.length; a ++) {
for (int b = 26; b < chars.length; b++) {
for (int c = 26; c < chars.length; c++) {
for (int d = 26; d < chars.length; d++) {
pass = chars[a]+""+chars[b]+""+chars[c]+""+chars[d];
System.out.println(pass);
if (pass == name){
System.out.print("password");
break outerLoop;
}
}
}
}
}
The nested if will check if pass is equal to Mike. If it is, then it prints password and will break the for loop.
Is pass = chars[a]... the correct way to do this? When I tested it without the if, I had it print out pass and it printed all of the combinations correctly. It did print Mike, but it did not catch in the if.
I also changed the nested for loops so they start with the lower case because the program was taking a while to run when I made minor changes.

if (pass == name){
should be
if (pass.equals(name)){
use String.equals() method to check string equality. == operator simply checks if two reference variables refer to the same object. equals() method checks if two strings are meaningfully equal.

Strings should be compared using equals()

This comes up at least once per day. There should be a "close question" option dedicated to it. Nevertheless, here goes again...
The == operator tests if the two operands are the same instance.
The .equals() method compares the values of the two operands, but only if the class has implemented this method (which String does), otherwise it behaves the same as == (which is how the Object class implements it).

Related

Can`t compare ArrayList values in Java

Im doing a Java course and in one exercise I have to create three ArrayLists, ask the user to fill the first two with Integers, and then compare both ArrayLists.
The values that donĀ“t repeat are added to the third ArrayList. I already declared the ArrayLists, used Scanner to allow the user to fill the ArrayLists, and that part works.
The problem comes when I try to compare both ArrayLists. I get all sort of alerts in this line ("the if statement is redundant", "Integer values compared using == or !=","Flip operands of the binary operator", "Invert if").
I suspect that what I wrote after the if statement is not very clean, and that I could get some comments about that (Im not an expert in Java), but I do not understand the alerts that the IDE displays. The code compiles and runs just fine until it hits the nested loops. Please help! Thanks.
//Checking for values that dont repeat
for(int i=0;i<listVector1.size();i++){
for(int j=0;j<listVector2.size();i++){
if(listVector1.get(i)==listVector2.get(j)){//Im getting an alert here
repeats=true; //this boolean was previously declared
} else {
repeats=false;
}
if(repeats==false){
int newValue=listVector1.get(i);
listVector3.add(newValue);
}
}
}
First of all, you have a mistake in the second for loop. I expect you want increment j.
Second is comparing you must explicit cast your values from the array or use function equals.
Third your if statement must be out of your second loop. Because I expect you want to add number in third array only one time as it you find.
for(int i = 0; i < listVector1.size(); i++) {
for(int j = 0; j < listVector2.size(); j++) {
if (listVector1.get(i).equals(listVector2.get(j))) {
repeats = true;
break;
} else {
repeats = false;
}
}
if(!repeats){
int newValue=listVector1.get(i);
listVector3.add(newValue);
}
}
This is the real problem here.
Integer values compared using == or !=
The == operator compares the two object's reference. But what you actually want to do is compare the values stored in the reference.
So, you need to use the equals operator.
Or you could explicitly cast one of the values to int and use == on the values like
if(listVector1.get(i) == ((int)listVector2.get(j))){
repeats=true;
} else {
repeats=false;
}
For more reading, you'd google difference between == and equals operator.

Why is my code executing both 'IF' and 'ELSE' with '==' but not with '.equals'? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 3 years ago.
Java newbie here, I'm experimenting with some simple code using NetBeans. The program simply takes in a few strings into an Array of a predetermined length, while not allowing the previously used ones to be added.
String[] AnArray = new String[3];
for (int i=0; i<AnArray.length; i++) {
System.out.println("Insert a string:");
Scanner s = new Scanner(System.in);
String astring = s.next();
for (String AnArray1 : AnArray) {
if (astring.equals(AnArray1)) { /* THIS IS WHERE I CHANGE astring.equals(AnArray1) TO astring == AnArray1 */
System.out.println ("String already used");
break;
}
else
AnArray[i] = astring;
}
}
for (String AnArray1 : AnArray) {
System.out.println(AnArray1);
}
If the string was already used, it should print out a message "String already used" and not add it, leaving the field empty (null).
If I use .equals, it works correctly (well, as I expect it to).
However, if I use '==' it prints out the message, but still adds the (already used) string to the Array.
Note: All advice is appreciated, but I'd be most grateful for an explanation as to HOW/WHY this IS happening (as opposed to what I should do to improve my code).
EDIT: I don't see how this is a duplicate. If someone can paste the relevant part of the answer to my question, I would be grateful. My question is: since the condition is True in BOTH cases (using == or .equals) why does the .equals() follow the break command while == triggers else AS IF it's ALSO false?
I hope the below summary helps you in your case:
use == to compare primitive e.g. boolean, int, char etc, while
use equals() to compare objects in Java.
== return true if two reference are of same object. Result of
equals() method depends on overridden implementation.
For comparing String use equals() instead of == equality
operator.
In Java, == compares the object's references, not the object's contents. That is, with == you check whether the two references point to the same object in memory (which implies that they also have the same contents). With .equals(), however, you check whether the contents of the objects, i.e. the string characters, are the same. Also see e.g. What is the difference between == and equals() in Java?.
Edit: Here's a working example that tries to stick as close to your original code as possible:
String[] AnArray = new String[3];
for (int i=0; i<AnArray.length; i++) {
System.out.println("Insert a string:");
Scanner s = new Scanner(System.in);
String astring = s.next();
boolean alreadyContains = false;
for (int k=0; k<i; k++) {
AnArray1 = AnArray[k];
if (astring.equals(AnArray1)) {
alreadyContains = true;
break;
}
}
if (alreadyContains) {
System.out.println ("String already used");
} else {
AnArray[i] = astring;
}
}
for (String AnArray1 : AnArray) {
System.out.println(AnArray1);
}

Counting The Number of Valleys [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 3 years ago.
I'm doing a problem on hackerRank and the problem is:
Problem Statement
Here we have to count the number of valleys does XYZ person visits.
A valley is a sequence of consecutive steps below sea level, starting with a step down from sea level and ending with a step up to sea level.
For One step up it U, and one step down it is D. We will be given the number of steps does XYZ person traveled plus the ups and down in the form of string, i.e,
UUDDUDUDDUU
Sample Input
8
UDDDUDUU
Sample Output
1
Explanation
If we represent _ as sea level, a step up as /, and a step down as \, Gary's hike can be drawn as:
_/\ _
\ /
\/\/
He enters and leaves one valley.
The code I wrote doesn't work
static int countingValleys(int n, String s) {
int count = 0;
int level = 0;
String[] arr = s.split("");
for(int i = 0; i<n;i++){
if(arr[i] == "U"){
level++;
} else{
level--;
}
if(level==0 && arr[i]=="U"){
count++;
}
}
return count;
}
But another solution I found does, however no matter how I look at it the logic is the same as mine:
static int countingValleys(int n, String s) {
int v = 0; // # of valleys
int lvl = 0; // current level
for(char c : s.toCharArray()){
if(c == 'U') ++lvl;
if(c == 'D') --lvl;
// if we just came UP to sea level
if(lvl == 0 && c == 'U')
++v;
}
return v;
}
So what's the difference I'm missing here that causes mine to not work?
Thanks.
In java, you need to do this to compare String values:
if("U".equals (arr[i])) {
And not this:
if(arr[i] == "U") {
The former compares the value "U" to the contents of arr[i].
The latter checks whether the strings reference the same content or more precisely the same instance of an object. You could think of this as do they refer to the same block of memory? The answer, in this case, is they do not.
To address the other aspect of your question.
Why this works:
for(char c : s.toCharArray()){
if(c == 'U') ++lvl;
if(c == 'D') --lvl;
when this does not:
String[] arr = s.split("");
for(int i = 0; i<n;i++){
if(arr[i] == "U"){
You state that the logic is the same. Hmmmm, maybe, but the data types are not.
In the first version, the string s is split into an array of character values. These are primitive values (i.e. an array of values of a primitive data type) - just like numbers are (ignoring autoboxing for a moment). Since character values are primitive types, the value in arr[i] is compared by the == operator. Thus arr[i] == 'U' (or "is the primitive character value in arr[i] equal to the literal value 'U') results in true if arr[i] happens to contain the letter 'U'.
In the second version, the string s is split into an array of strings. This is an array of instances (or more precisely, an array of references to instances) of String objects. In this case the == operator compares the reference values (you might think of this as a pointer to the two strings). In this case, the value of arr[i] (i.e. the reference to the string) is compared to the reference to the string literal "U" (or "D"). Thus arr[i] == "U" (or "is the reference value in arr[i] equal to the reference value of where the String instance containing a "U" string" is located) is false because these two strings are in different locations in memory.
As mentioned above, since they are different instances of String objects the == test is false (the fact that they just happen to contain the same value is irrelevant in Java because the == operator doesn't look at the content). Hence the need for the various equals, equalsIgnoreCase and some other methods associated with the String class that define exactly how you wish to "compare" the two string values. At risk of confusing you further, you could consider a "reference" or "pointer" to be a primitive data type, and thus, the behaviour of == is entirely consistent.
If this doesn't make sense, then think about it in terms of other object types. For example, consider a Person class which maybe has name, date of birth and zip/postcode attributes. If two instances of Person happen to have the same name, DOB and zip/postcode, does that mean that they are the same Person? Maybe, but it could also mean that they are two different people that just happen to have the same name, same date of birth and just happen to live in the same suburb. While unlikely, it definitely does happen.
FWIW, the behaviour of == in Java is the same behaviour as == in 'C'. For better or worse, right or wrong, this is the behaviour that the Java designers chose for == in Java.
It is worthy to note that other languages, e.g. Scala, define the == operator for Strings (again rightly or wrongly, for better or worse) to perform a comparison of the values of the strings via the == operator. So, in theory, if you addressed other syntactic issues, your arr[i] == "U" test would work in Scala. It all boils down to understanding the rules that the various operators and methods implement.
Going back to the Person example, assume Person was defined as a case class in Scala. If we created two instances of Person with the same name, DOB and zip/postcode (e.g. p1 and p2), then p1 == p2 would be true (in Scala). To perform a reference comparison (i.e. are p1 and p2 instances of the same object), we would need to use p1.eq(p2) (which would result in false).
Hopefully the Scala reference, does not create additional confusion. If it does, then simply think of it as the function of an operator (or method) is defined by the designers of the language / library that you are using and you need to understand what their rules are.
At the time Java was designed, C was prevalent, so it can be argued that it makes sense the C like behaviour of == replicated in Java was a good choice at that time. As time has moved on, more people think that == should be a value comparison and thus some languages have implemented it that way.

Setting a variable to a value in if statement

static int findPerson(String n, int NP, Friend[] giftGivers){
int index = 0;
for (int i = 0; i < NP; i++){
if (giftGivers[i].name == n){
index = i;
}
}
return index;
}
I have this code in Java for a method to search through an array of Friends to find the index number of the person with the name input by String n. however i have found that the index number does not set to the index number it is should be. Is it because it is in the if statement?
if (giftGivers[i].name == n) is wrong, use if (giftGivers[i].name.equals(n))
BTW, there is no need to use NP. It's C-style, not necessary (actually, pretty dangerous) in Java. Instead of
for (int i = 0; i < NP; i++),
just say for (int i = 0; i < giftGivers.length; i++)
You need to use equals to compare strings not ==.
== will compare the object references rather than the actual string value.
If you don't care about case, then there is also an equals method that ignores case
(giftGivers[i].name == n){
should be
(giftGivers[i].name.equals(n)){
String/Object comparison should use .equals() instead of ==
== will check for reference equality. equals() check for object equality.
.equals() method checks for equality of two string objects, == operator checks if two refrence variables point to the same String object.
In your case you have to use .equals() method
if (giftGivers[i].name.equals(n))
refer to String API.
Note that if you wanna check if two strings are equal case insensitive use equalsIgnoreCase()

Using an IF statement to control the return statement?

public static int seqSearch(int numRecords, String[] stuName,
double[] stuGpa, String nameKey, double gpaKey)
for(int i = 0; i < numRecords; i++)
if(stuName[i] == nameKey && stuGpa[i] == gpaKey)
return i;
return -1;
So, how would I used an if statement to control this? I'm doing sequential search to find if the name is found in the array and if the gpa is in the array, then it should return the position it was found in (i). But, all it does do is return -1 and print out that none were found.
You have two separate problems here:
You should be comparing strings using the equals() method (or one of it's kin) - otherwise you are comparing whether two strings are the same reference (instance) rather than equivalent sequences of characters.
You should avoid comparing doubles using == as equality for doubles is more nuanced. Check out this paper for more information about why.
See this question about why using == for floating point comparison is a bad idea in java.
Aside from that, I would also mention that your implementation makes the assumption that both stuName and stuGpa are arrays of the same length. This could easily not be the case ... and is probably something worth asserting before you begin iterating over the arrays.
Strings must be compared with .equals in Java, not ==.
if(stuName[i].equals (nameKey) && stuGpa[i] == gpaKey)
You probably want
if (stuName[i].equals(nameKey) && stuGpa[i].equals(gpaKey))
if(stuName[i] == nameKey is unlikely to be right, you are comparing object identities not string content. Try if(stuName[i].equals(nameKey)
You are comparing two Strings.
Strings are immutable.
Please use "equalsIgnoreCase()" or "equals()" to compare Strings
See examples here
http://www.java-samples.com/showtutorial.php?tutorialid=224
An essential problem is that
stuName[i] == nameKey
Is only comparing whether the objects are the same String Object in memory.
You actually want to use nameKey.equals(stuName[i]), to compare the actual string values.
And you might want to use .equalsIgnoreCase for case insensitivity.
The following is correct for the if statement. stuName[i] is a string so compare with .equals. stuGpa[i] is a double so use ==.
if(stuName[i].equals(nameKey_ && stuGpa[i] == gpaKey)
Your problem is not the conditional if statement, but the conditional operator ==. == refers to the pointer value of the object where as the .equals method returns something computed by the object.
Like everyone has said before, switch your == to .equals in this next line:
public static int seqSearch(int numRecords, String[] stuName,
double[] stuGpa, String nameKey, double gpaKey)
for(int i = 0; i < numRecords; i++)
if(stuName[i].equals(nameKey) && stuGpa[i] == gpaKey)
return i;
return -1;
To actually answer the question about the control of the if statement...
I believe what you're doing is fine with the the multiple return statements, BUT...
I personally prefer one entry point and only one exit point for my methods. It always feels dirty to me having multiple exit points.
So, I would consider the following code instead:
public static int seqSearch(int numRecords, String[] stuName, double[] stuGpa, String nameKey, double gpaKey)
int value = -1;
for(int i = 0; i < numRecords; i++) { // Don't forget your braces, they aren't required, but wait until you add a newline and forget to add them...
if(some.boolean().equals(comparison.here())) {
value = i;
break;
}
}
return value;
}
Best of Luck.

Categories