开发者

Java generic arguments

开发者 https://www.devze.com 2023-02-14 12:09 出处:网络
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 wit

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!


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.


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

We already gave you that hint. :)


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号