【问题标题】:Java generic argumentsJava 泛型参数
【发布时间】:2011-03-03 19:35:28
【问题描述】:

在这里回顾我的基本 ADT 内容以进行面试修改,并在我学习 Java 的同时尝试用一块石头杀死两只鸟。尝试使用通用链表(我自己创建)为合并排序编写一个简单的算法。事实证明这比我最初想象的要困难得多!谁能帮帮我?我将从基础开始工作,并会随着我的深入而更新这篇文章。

我的通用链表代码如下:

 public class NodeList<T extends Comparable<T> > {
  private T head;
  public NodeList<T> tail;
  public NodeList( T item, NodeList<T> list ) {
    head = item;
    tail = list;
  } 

}

我正在尝试在我制作的另一个类中访问该类,如下所示:

    public class MyList<T extends Comparable<T>> {

  private NodeList<T> nodes;
  private static int size;
  public MyList( ) { 
    nodes = null; 
  }

  public MyList(T[] array ){
    for( T item : array ) {
      nodes = new NodeList<T>(item, nodes); 
    }
    size = array.length;
  }


  public void add( T item ) { 
    nodes = new NodeList<T>( item, nodes ); 
    size++;
  }


  public void addEnd( T item ) {
    NodeList<T> temp = nodes;
    while ( temp == null || temp.tail != null) {
      temp = temp.tail;
    }
    size++;
    temp.tail = new NodeList<T> ( item, null);
  }

我相信,到目前为止,在 add 和 addEnd 方法之前,一切都是正确的,它们应该分别在列表的开头和列表的结尾添加一个泛型。

我的代码继续:

 public static <S extends Comparable<S>>
    MyList<S> sort( MyList<S> list ) {

    if ( size > 1 ) {

      MyList<S> left  = leftHalf( list );
      MyList<S> right = rightHalf( list );
      list = merge( left, right );
    }

    return list;
  }

  private static <S extends Comparable<S>>
    MyList<S> merge( MyList<S> left, MyList<S> right ) {

  }

  private static <S extends Comparable<S>>
    MyList<S> leftHalf( MyList<S> list ) {
    MyList <S> leftSide = new MyList();
    int middle;
    if(size % 2 == 1) {
     middle = size +1;
    } else {
     middle = size; 
    }
    for ( int countToMiddle = 0; countToMiddle < middle ; countToMiddle++ ) {
      leftSide.addEnd(nodes);
    }


    // return elements from 0 .. list.size() / 2
  }

我得到了错误:

MyList 中的addEnd(S) 不能应用于(NodeList)

当我运行时发生

leftSide.addEnd(nodes);

谁能看到这个原因/告诉我到目前为止我的工作是否正确?再次感谢!

【问题讨论】:

  • 想想TComporable之间的关系。
  • 问题的第二个版本,看起来MyList leftSide 应该是MyList&lt;S&gt; leftSide。确保您摆脱警告,包括原始类型(我认为这是在当前的 JDK6 中)。
  • 已编辑以解决该问题,谢谢,不幸的是,MyList 中的 addEnd(S) 无法应用于 (NodeList) 错误!再次感谢:)
  • addEnd(T item) 需要 T 类型的对象,而不是 NodeList 作为参数。
  • 另外:leftSide.addEnd(nodes); -> nodes 来自哪里?

标签: java adt mergesort


【解决方案1】:

如果您希望 NodeList 和 MyList 仅包含 Comparable 项, 您可以将通用参数 T 替换为:

public class NodeList<T extends Comparable> {

或者

public class NodeList<T extends Comparable<T>> {

并将您使用Comparable 的位置替换为T。这样,你就知道 T 至少实现了 Comparable 的方法。

Oracle 的tutorials for generics 应该能够帮助您掌握它们的窍门。


您可能遇到的一个问题是您从静态函数中引用成员变量,例如在 leftHalf 中您有:

   for ( int countToMiddle = 0; countToMiddle < middle ; countToMiddle++ ) {
      leftSide.addEnd(nodes);
    }

nodes 是一个成员变量,即一个非静态变量,所以你不能从静态方法中调用它。例如,您必须从传递的MyList 中获取它:

   for ( int countToMiddle = 0; countToMiddle < middle ; countToMiddle++ ) {
      leftSide.addEnd(list.nodes);
    }

对于尝试使用成员变量的其他静态方法也是如此。


此外,您收到如下错误的原因是:addEnd(S) in MyList&lt;S&gt; cannot be applied to (NodeList&lt;T&gt;) 是因为根据您的类型参数,S 是一个 Comparable。 NodeList 不扩展 Comparable!

你有两个解决方案是

  1. 使 NodeList 扩展 Comparable,以便您可以将其传递给 MyList.addEnd
  2. 为 addEnd 做一个重载(即同名的不同方法),它接受一个 NodeList,并将传递的 NodeList 中的所有项目添加到 MyList

或者想出一个更适合您班级需要的不同解决方案。


虽然我意识到您正在实施一个链接列表只是为了提高您的面试技巧(祝您好运!),但我只想补充一点,Java 中已经有一个通用的LinkedList

【讨论】:

  • 最好将tail的声明修改为private NodeList&lt;T&gt; tail;,并将NodeList构造函数签名修改为public NodeList( T item, NodeList&lt;T&gt; list )(注意第二个参数的变化)。
  • 非常感谢您的回复,我现在编辑了我的帖子以显示我遇到的一个新问题!再次感谢你:)
  • &lt;T extends Comparable&lt;T&gt;&gt; (注意当前问题中的代码与原始代码完全不同。)
  • 我对 list.nodes 进行了更改,但仍然返回了几个相同的错误。有什么想法吗?
  • @Steve Quinn 我现在已经添加到答案中,这是因为您的 addEnd 接受 Comparable,而不是 NodeList
【解决方案2】:

为什么您两次发布几乎相同的问题? 您可以扩展您的问题,添加 cmets 等。

我们已经给了你hint。 :)

【讨论】:

  • 我无法登录我的旧帐户并有一个新问题! :) 感谢您的回复 :)
  • 这个提示太棒了,谢谢!为重复道歉!
  • 没问题,这样的事情可能发生:)
  • 谢谢!:) 帖子现在编辑了一些新的快速/可能容易出错的代码!
【解决方案3】:

发生错误是因为类 NodeList 没有接收通用 T 类和 NodeList 的构造函数。 实际上,这个实现将替换节点在每个循环中引用的引用对象。你也应该解决这个问题。

你应该做的就是把 T 变成一个 Comparable 本身,并改变属性,比如:

public class NodeList<T extends Comparable> {
    private T head;
    private NodeList tail;
    public NodeList( T item, NodeList list ) {
        head = item;
        tail = list;
    }
}

最好能告诉我们代码的具体用途。

【讨论】:

  • &lt;T extends Comparable&lt;T&gt;&gt; (注意当前问题中的代码与原始代码完全不同。)
猜你喜欢
  • 2010-12-18
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多