【问题标题】:How to compare objects with different types?如何比较不同类型的对象?
【发布时间】:2014-10-04 19:03:30
【问题描述】:

在下面的程序中,DList1 是一个列表抽象。

我想在 DList1 类的 main() 函数中运行一些单元测试用例。

具体来说,

Line 105l.head.item != 9main() 方法中,出现编译错误:Incompatible operand types Object and int

在编译时,值9 是基本类型intl.head.itemclass Object 类型。

在运行时,l.head.item 的类型为 class Integer。不确定9的值类型。

/* DList1.java */

/**
 *  A DList1 is a mutable doubly-linked list.  (No sentinel, not
 *  circularly linked.)
 */

public class DList1 {

  /**
   *  head references the first node.
   *  tail references the last node.
   *
   *  DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
   */

  protected DListNode1 head;
  protected DListNode1 tail;
  protected long size;

  /* DList1 invariants:
   *  1)  head.prev == null.
   *  2)  tail.next == null.
   *  3)  For any DListNode1 x in a DList, if x.next == y and x.next != null,
   *      then y.prev == x.
   *  4)  For any DListNode1 x in a DList, if x.prev == y and x.prev != null,
   *      then y.next == x.
   *  5)  The tail can be accessed from the head by a sequence of "next"
   *      references.
   *  6)  size is the number of DListNode1s that can be accessed from the
   *      head by a sequence of "next" references.
   */

  /**
   *  DList1() constructor for an empty DList1.
   */
  public DList1() {
    this.head = null;
    this.tail = null;
    this.size = 0;
  }


  /**
   *  insertFront() inserts an item at the front of a DList1.
   */
  public void insertFront(Object item) {
      if(this.head == null){
          this.head = new DListNode1(item);
          this.tail = this.head;
      }else{
          DListNode1 newNode = new DListNode1(item);
          newNode.next = this.head;
          this.head.prev = newNode;
          this.head = newNode;
      }
      this.size++;
  }

  /**
   *  removeFront() removes the first item (and node) from a DList1.  If the
   *  list is empty, do nothing.
   */
  public void removeFront() {
      if(this.size == 0){
          return;
      }else if(size ==1){
          this.head = null;
          this.tail = null;
      }else{
          this.head.next.prev = null;
          this.head = this.head.next;
      }
  }

  /**
   *  toString() returns a String representation of this DList.
   *
   *  DO NOT CHANGE THIS METHOD.
   *
   *  @return a String representation of this DList.
   */
  public String toString() {
    String result = "[  ";
    DListNode1 current = head;
    while (current != null) {
      result = result + current.item + "  ";
      current = current.next;
    }
    return result + "]";
  }

  public static void main(String[] args) {
    // DO NOT CHANGE THE FOLLOWING CODE.

    DList1 l = new DList1();
    System.out.println("### TESTING insertFront ###\nEmpty list is " + l);

    l.insertFront(9);
    System.out.println("\nInserting 9 at front.\nList with 9 is " + l);
    if (l.head == null) {
      System.out.println("head is null.");
    } else {
        if (l.head.item != 9) { //Line 105
            System.out.println("head.item is wrong.");
        }
        if (l.head.prev != null) {
            System.out.println("head.prev is wrong.");
        }
    }
    if (l.tail == null) {
      System.out.println("tail is null.");
    } else {
      /*if (l.tail.item != 9) {
        System.out.println("tail.item is wrong.");
      }
      if (l.tail.next != null) {
        System.out.println("tail.next is wrong.");
      }*/
    }
    if (l.size != 1) {
      System.out.println("size is wrong.");
    }

    l.insertFront(8);
    System.out.println("\nInserting 8 at front.\nList with 8 and 9 is " + l);
    if (l.head == null) {
      System.out.println("head is null.");
    } else {
      /*if (l.head.item != 8) {
        System.out.println("head.item is wrong.");
      }*/
      if (l.head.prev != null) {
        System.out.println("head.prev is wrong.");
      }
      if (l.head.next != l.tail) {
        System.out.println("head.next is wrong.");
      }
    }
    if (l.tail == null) {
      System.out.println("tail is null.");
    } else {
      if (l.tail.next != null) {
        System.out.println("tail.next is wrong.");
      }
      if (l.tail.prev != l.head) {
        System.out.println("tail.prev is wrong.");
      }
    }
    if (l.size != 2) {
      System.out.println("size is wrong.");
    }

  }

}

/* DListNode1.java */

/**
 *  A DListNode1 is a node in a DList1 (doubly-linked list).
 */

class DListNode1 {

  /**
   *  item references the item stored in the current node.
   *  prev references the previous node in the DList.
   *  next references the next node in the DList.
   *
   *  DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
   */

  Object item;
  DListNode1 prev;
  DListNode1 next;

  /**
   *  DListNode1() constructor.
   */
  DListNode1() {
    this.item = null;
    this.prev = null;
    this.next = null;
  }

  DListNode1(Object item) {
    this.item = item;
    this.prev = null;
    this.next = null;
  }
}

我的问题:

如何使类型在编译时和运行时都兼容,并让值在Line 105 中进行比较? 9 的值的运行时类型是什么?

【问题讨论】:

  • 转换为整数,然后 !l.item.head.equals(9)
  • @sscnapoli1926 更新中的小错字head.item。我的第二部分查询呢?
  • 如果你指的是“!”这不是错字,而是否定运算符!无论如何,如果您需要在运行时决定项目的类型,唯一的方法就是用泛型替换 Object 字段。如果“item”可以是你的类的一个实例,你必须提供一个 equals() 覆盖,游戏就完成了
  • item.head 是一个错字
  • @sscnapoli1926 - 泛型不允许您“在运行时决定项目的类型”。相反,它们允许您对不同的参数类型(即,在代码中的不同位置)使用相同的类,而无需进行显式转换。 (转换由编译器隐式执行。)

标签: java


【解决方案1】:
  1. 您可以在比较之前使用类型转换:(int)l.head.item != 9(它适用于 Java 7 及更高版本,在旧版本中您可以使用 (Integer)l.head.item)。
  2. 如果您的列表应该是同质的,那么使用泛型是个好主意。

【讨论】:

  • 什么是运行时类型的值9
【解决方案2】:

如您所述,编译器无法将原始 intObject 进行比较。解决此问题的一种方法是使用 Integer 包装类:

if (Integer.valueOf(9).equals(l.head.item)) { //Line 105

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    • 2021-04-20
    • 2011-05-04
    • 1970-01-01
    • 2019-05-29
    相关资源
    最近更新 更多