Java泛型参数

时间:2011-03-03 19:35:29

标签: java adt mergesort

回到我的基本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(节点);

任何人都可以看到这个原因/告诉我,如果我的工作到目前为止是正确的吗?非常感谢!

3 个答案:

答案 0 :(得分:2)

如果您希望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<S> cannot be applied to (NodeList<T>)是因为S根据您的类型参数而定,是可比较的。 NodeList不会扩展可比较的内容!

你有两个解决方案

  1. 使NodeList扩展为Comparable,以便将其传递给MyList.addEnd
  2. 为获取NodeList的addEnd创建一个重载(即具有相同名称的不同方法),并将传递的NodeList中的所有项添加到MyList
  3. 或者提出一种更符合您课程需要的不同解决方案。


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

答案 1 :(得分:1)

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

我们已经给了你hint。 :)

答案 2 :(得分:0)

发生错误是因为类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;
    }
}

如果你告诉我们代码的确切含​​义会更好。