Reputation: 476
While solving this question, I am getting wrong answer on some of the test cases of the problem using the get
method of ArrayList
directly in condition check.
Code failing the test cases:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Stack <Integer> s= new Stack<>();
ArrayList <Integer> m= new ArrayList<>();
for(int i=0;i<n;i++){
int x=sc.nextInt();
if(x==1){
int y=sc.nextInt();
if(m.isEmpty() || y>=m.get(m.size()-1))
m.add(y);
s.push(y);
}
else if(x==2){
// Here I am using `get` to check the last value of ArrayList with the top of stack
if(m.get(m.size()-1)==s.peek()) {
m.remove(m.size()-1);
}
s.pop();
}
else {
System.out.println(m.get(m.size()-1));
}
}
}
}
But when assigned the same syntax to a variable and used that for the condition check it passed.
Code passing all the test cases:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Stack <Integer> s= new Stack<>();
ArrayList <Integer> m= new ArrayList<>();
for(int i=0;i<n;i++){
int x=sc.nextInt();
if(x==1){
int y=sc.nextInt();
if(m.isEmpty() || y>=m.get(m.size()-1))
m.add(y);
s.push(y);
}
else if(x==2){
// When assigning the same to a variable it passed all test cases.
int a = m.get(m.size()-1);
if(a==s.peek()) {
m.remove(m.size()-1);
}
s.pop();
}
else {
System.out.println(m.get(m.size()-1));
}
}
}
}
As I am new to Java, I am confused with the use of the get
method of the ArrayList
. Please explain to me about the inner working of the get
method that why it is failing or am I missing something?
Upvotes: 0
Views: 250
Reputation: 294
I think that the problem is related to automatic boxing/unboxing of Integer type. In the statement
if(a==s.peek())
the comparison is done comparing the an integer value (a) to the unboxed Integer (s.peek()).
In the statement
m.get(m.size()-1)==s.peek()
the comparison is done comparing between two Integer values, that is between two references. Since the two references are different the equality check fails.
To fix the latest statement you can use:
m.get(m.size()-1).intValue()==s.peek().intValue()
Or use the equals method of Integer type.
Upvotes: 1
Reputation: 21435
s
and m
store Integer
objects and you should never compare objects using ==
.
Replace m.get(m.size()-1)==s.peek()
with m.get(m.size()-1).equals(s.peek())
and your code will work.
The reason that your second approach works is that by assigning m.get(m.size()-1)
to an int
variable the Integer
value is unboxed, and then the comparison a==s.peek()
is done on the int
values (the value from s.peek()
is unboxed too).
Upvotes: 1
Reputation: 3131
I didn't look at the task itself (as a question should be self-contained and I'm not going to visit random links) but I believe the problem comes from types you use here.
In the first case, m.get(m.size()-1)==s.peek()
both right side and left side are Integer
s. Because of that, when you use a ==
sign, you are actually comparing object references. Such comparison will work only sometimes (I believe its for Integers in range from -128 to 127). You could use equals
to fix the issue.
On the other hand we have int a = m.get(m.size()-1); if(a==s.peek())
. Here, in the first part you're getting Integer
first but then it is assigned to an int
variable - unboxing happens here. Then, when you have a condition, you compare an int
and an Integer
. In such comparison, the Integer
gets unboxed to an int
and a comparison on simple int
s happen here (see first point in JLS-5.6.2). Because of that it works alright in this situation.
Upvotes: 1