【问题标题】:Wrong Answer using `get` method of ArrayList使用 ArrayList 的 `get` 方法的错误答案
【发布时间】:2021-01-08 08:22:43
【问题描述】:

在解决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 方法的内部工作原理,为什么它会失败或我遗漏了什么?

【问题讨论】:

标签: java arraylist get


【解决方案1】:

我认为问题与整数类型的自动装箱/拆箱有关。 在声明中

 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方法。

【讨论】:

    【解决方案2】:

    我没有查看任务本身(因为问题应该是独立的,我不会访问随机链接)但我相信问题来自您在此处使用的类型。

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

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

    【讨论】:

    • 感谢您的解释...我会更新问题...
    【解决方案3】:

    sm 存储 Integer 对象,您应该从不使用 == 比较对象。

    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() 也未装箱)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-12
      • 2022-08-18
      • 2020-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多