Java generic arguments

和自甴很熟 提交于 2019-12-12 04:48:39

问题


Going back over my basic ADT stuff here to revise for an interview, and trying to kill two birds with one stone by learning Java while I am. Attempting to write a simple algorithm for a merge sort with a generic linked list ( which I am creating myself). It's proving to be far more difficult than I had first imagined ! Can anyone help me out please ? I will start out working on the basics and will update this post as I get further in.

My code for the generic linked list is as follows :

 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;
  } 

}

I am trying to access this class in another class I have made, which is as follows :

    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);
  }

I believe, so far, everything to be correct up until the add and addEnd methods, which should add a generic to the start of the list and end of the list respectively.

My code continues with :

 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
  }

And I get the error:

addEnd(S) in MyList cannot be applied to (NodeList)

which occurs when I run

leftSide.addEnd(nodes);

Can anyone see a reason for this/ tell me if I am correct up to this point of my work ? Thanks so much again!


回答1:


If you want NodeList and MyList to only contain Comparable items, you can replace the generic parameter T with something like:

public class NodeList<T extends Comparable> {

Or

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

And replace where you use Comparable with T. This way, you know T at least implements Comparable's methods.

Oracle's tutorials for generics should be able to help you with getting the hang of them.


One problem you may be having is that you refer to member variables from static functions, like in leftHalf you have:

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

nodes is a member variable, i.e. a non-static variable, so you can't call it from static methods. For that example, you'd have to get it from the passed MyList:

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

And the same goes for your other static methods that try to use member variables.


Also, the reason you are getting an error like: addEnd(S) in MyList<S> cannot be applied to (NodeList<T>) is because S is, according to your type parameter, a Comparable. NodeList does not extend Comparable!

The two solutions you have is

  1. Make NodeList extend Comparable so you can pass it to MyList.addEnd
  2. Make an overload (i.e. a different method with the same name) for addEnd that takes a NodeList, and add all the items in the passed NodeList to MyList

Or come up with a different solution that better fits the need of your classes.


While I realize you are implementing a linked list just to sharpen your skills for an interview (I wish you good luck!), I just want to add that there is a generified LinkedList already available in Java.




回答2:


Why do you post almost the same question twice? You could extend your question, add comments etc.

We already gave you that hint. :)




回答3:


The error is happening because the class NodeList doesn't have a constructor that receives a generic T class and a NodeList. Actually, this implementation will replace the reference object that nodes is referring on every loop. You should also fix that.

What you should do is put T to be a Comparable itself, and change the attribute, something like:

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

It would be better if you tell us what exactly the code is for.



来源:https://stackoverflow.com/questions/5185577/java-generic-arguments

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!