【问题标题】:Integer value comparison整数值比较
【发布时间】:2009-06-04 21:21:47
【问题描述】:

我是一个 Java 编码新手,我刚刚读取了一个整数类的变量,可以在 API 中以三种不同的方式描述。我有以下代码:

if (count.compareTo(0)) { 
            System.out.println(out_table);
            count++;
    }

这是在一个循环内,只输出out_table
我的目标是弄清楚如何查看整数 count > 0 中的值。

我意识到count.compare(0) 是正确的方法?还是count.equals(0)

我知道count == 0 不正确。这是正确的吗?是否有一个值比较运算符,它只是count=0

【问题讨论】:

    标签: java integer int equals autoboxing


    【解决方案1】:

    要确定 Integer 是否大于 0,您可以:

    • 检查compareTo(O)是否返回正数:

      if (count.compareTo(0) > 0)
           ...
      

      但这看起来很傻,不是吗?最好...

    • 使用autoboxing1:

      if (count > 0)
          ....
      

      这相当于:

      if (count.intValue() > 0)
          ...
      

      请务必注意,“==”是这样计算的,Integer 操作数未装箱,而不是 int 操作数已装箱。否则,count == 0 将在 count 初始化为 new Integer(0) 时返回 false(因为“==”测试引用相等)。

    1从技术上讲,第一个示例使用autoboxing(在 Java 1.5 之前,您不能将int 传递给compareTo),第二个示例使用unboxing。组合功能通常简称为“自动装箱”,然后通常将其扩展为将两种类型的转换称为“自动装箱”。对于我对术语的松懈使用,我深表歉意。

    【讨论】:

    • 前一个例子是使用自动装箱;后者自动拆箱。
    • +1:关于==比较,在比较两个 盒装数字时应该非常谨慎(但不是一个盒装和一个原始number),因为正如 mmyers 所提到的,== 测试引用相等性,而不是包装值的相等性。
    【解决方案2】:

    整数是自动拆箱的,所以你可以这样做

    if (count > 0) {
        .... 
    }
    

    【讨论】:

    • 嗯。并不真地。 ...在其他比较中,情况并非总是如此。如果您要比较两个整数并使用“==”怎么办?然后比较这些实例,但有时 JVM 不会缓存它们,因此它会将相同的值报告为不同的值。见stackoverflow.com/questions/10002037/…
    • @ingyhere 整数与 int 比较时自动拆箱。
    • @Alex78191:在这个例子中,在一个装箱和一个原始比较的情况下,它可以工作,最左边的值取消装箱。对于两个 Integer 对象的比较,这并不能保证,至少在 2013 年和所有 JVM 实现中都不能保证。如果我记得的话,这就是重点。无论如何,使用if (count.intValue() > 0) { ... } 作为一种实践几乎没有什么成本,除非它可能有益于限制循环中的自动拆箱。
    【解决方案3】:

    最好避免不必要的自动装箱,原因有两个。

    一方面,它比int < int 慢一点,因为您(有时)会创建一个额外的对象;

    void doSomethingWith(Integer integerObject){ ...
      int i = 1000;
      doSomethingWith(i);//gets compiled into doSomethingWith(Integer.valueOf(i));
    

    更大的问题是隐藏的自动装箱可以隐藏异常:

    void doSomethingWith (Integer count){
      if (count>0)  // gets compiled into count.intValue()>0
    

    使用null 调用此方法将抛出NullPointerException

    java 中的原始对象和包装对象之间的分离总是被描述为速度的杂物。自动装箱几乎隐藏了这一点,但并不完全——它只是为了跟踪类型而变得更干净。所以如果你有一个 Integer 对象,你可以直接调用compare()intValue(),如果你有原语直接检查值。

    【讨论】:

    • +1 用于提及自动拆箱的负面影响。性能差异可能很大,尤其是在循环中自动(取消)装箱时。
    【解决方案4】:

    你也可以使用等号:

     Integer a = 0;
    
     if (a.equals(0)) {
         // a == 0
     }
    

    相当于:

     if (a.intValue() == 0) {
         // a == 0
     }
    

    还有:

     if (a == 0) {
    
     }
    

    (Java编译器会自动添加intValue())

    请注意,自动装箱/自动拆箱会带来很大的开销(尤其是在循环内部)。

    【讨论】:

      【解决方案5】:

      虽然您当然可以在 Integer 实例上使用 compareTo 方法,但在阅读代码时并不清楚,因此您应该避免这样做。

      Java 允许您使用自动装箱(请参阅http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html)直接与 int 进行比较,因此您可以这样做:

      if (count > 0) { }
      

      Integer 实例 count 会自动转换为 int 以进行比较。

      如果您无法理解这一点,请查看上面的链接,或者想象它正在这样做:

      if (count.intValue() > 0) { }
      

      【讨论】:

      • 对信息链接投赞成票。请记住,count 必须为非空值。在运行时自动拆箱空值时产生的异常令人困惑。
      【解决方案6】:

      另外需要注意的是,如果第二个值是另一个 Integer 对象而不是文字“0”,则“==”运算符会比较对象指针并且不会自动拆箱。

      即:

      Integer a = new Integer(0);   
      Integer b = new Integer(0);   
      int c = 0;
      
      boolean isSame_EqOperator = (a==b); //false!
      boolean isSame_EqMethod = (a.equals(b)); //true
      boolean isSame_EqAutoUnbox = ((a==c) && (a.equals(c)); //also true, because of auto-unbox
      
      //Note: for initializing a and b, the Integer constructor 
      // is called explicitly to avoid integer object caching 
      // for the purpose of the example.
      // Calling it explicitly ensures each integer is created 
      // as a separate object as intended.
      // Edited in response to comment by @nolith
      

      【讨论】:

      • 您必须用New Integer(0) 实例化ab,否则isSame_EqOperator 将是true
      • Goodpoint @nolith,尽管这是由于 Java 中的整数缓存,在接受的stackoverflow.com/questions/3131136/integers-caching-in-java 的回答中得到了很好的解释。我将更改我的答案以使用您建议的编辑,并附上描述为什么要显式使用构造函数的注释。
      【解决方案7】:

      好吧,我可能会迟到,但我想分享一些东西:

      给定输入: System.out.println(isGreaterThanZero(-1));

      public static boolean isGreaterThanZero(Integer value) {
          return value == null?false:value.compareTo(0) > 0;
      }
      

      返回 false

      public static boolean isGreaterThanZero(Integer value) {
          return value == null?false:value.intValue() > 0;
      }
      

      返回真 所以我认为在你的情况下'compareTo'会更准确。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-24
        • 2013-07-10
        • 1970-01-01
        相关资源
        最近更新 更多