使用 ArrayList 的 get 方法的错误答案

Wrong Answer using `get` method of ArrayList

在解决this问题时,我直接在条件检查中使用ArrayListget方法在问题的一些测试用例上得到错误答案。

未通过测试用例的代码:

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));
            }
        }
    }
}

但是当将相同的语法分配给变量并将其用于条件检查时,它通过了。

通过所有测试用例的代码:

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));
            }              
        }
    }
}

由于我是 Java 的新手,我对 ArrayListget 方法的使用感到困惑。请向我解释 get 方法的内部工作原理,为什么它会失败,或者我错过了什么?

我没有看任务本身(因为问题应该是独立的,我不会访问随机链接)但我相信问题出在你在这里使用的类型上。

第一种情况,m.get(m.size()-1)==s.peek()右边和左边都是Integer。因此,当您使用 == 符号时,您实际上是在比较对象引用。这种比较仅在某些时候有效(我相信它适用于 -128 到 127 范围内的整数)。您可以使用 equals 来解决这个问题。

另一方面,我们有 int a = m.get(m.size()-1); if(a==s.peek())。在这里,在第一部分中,您首先得到 Integer,但随后它被分配给一个 int 变量——拆箱发生在此处。然后,当你有一个条件时,你比较一个 int 和一个 Integer。在这样的比较中,Integer 被拆箱为 int 并且这里发生了对简单 int 的比较(参见 JLS-5.6.2 中的第一点)。因此,它在这种情况下工作正常。

sm 存储 Integer 个对象,你应该 永远不要 使用 ==.[=22= 比较对象]

m.get(m.size()-1)==s.peek() 替换为 m.get(m.size()-1).equals(s.peek()),您的代码将起作用。

您的第二种方法起作用的原因是,通过将 m.get(m.size()-1) 分配给 int 变量,Integer 值被取消装箱,然后完成比较 a==s.peek()int 值上(s.peek() 中的值也未装箱)。

我认为问题与 Integer 类型的自动 boxing/unboxing 有关。 在声明中

 if(a==s.peek())

比较是将整数值 (a) 与未装箱的整数 (s.peek()) 进行比较。

在声明中

 m.get(m.size()-1)==s.peek()

比较是在两个整数值之间进行比较,即在两个引用之间进行比较。由于两个引用不同,相等性检查失败。

要修复最新的声明,您可以使用:

 m.get(m.size()-1).intValue()==s.peek().intValue()
 

或者使用Integer类型的equals方法