PDA

Visualizza la versione completa : [JAVA] Generics


namek
04-02-2005, 14:25
Salve a tutti. Sto cercando di fare qualche classe per capire come usare una delle novità di Java 1.5, il polimorfismo parametrico.
Ho pensato di fare uno stack, siccome questa struttura dati è logica, mi serve l'aiuto di una lista e quindi di nodi, ho scritto questo codice:


public class Node <A>
{
public A chiave;

public Node next;

public Node()
{
next = null;
}

public Node(A el)
{
chiave = el;
next = null;
}

public Node(A el, SLLNode ptr)
{
chiave = el;
next = ptr;
}
}

public class List <A>
{
protected Node head;

public List()
{
head = null;
}

public void add(A el)
{
head = new Node(el,head);
}

public A deleteHead()
{
A el = head.chiave;
head = head.next;
return el;
}
}

public class Stack <A>
{
protected List lista;

public Stack()
{
lista = new SLList();
}

public void push(A el)
{
lista.add(el);
}

public A pop()
{
return lista.deleteHead();
}
}

Non so assolutamente se le interfacce dei metodi e le dichiarazioni delle variabili sono corrette, il compilatore dice che ci sono 2 errori:
incompatible types nella prima riga del deleteHead() nella List e ancora incompatible types nell'unica riga del metodo pop() di Stack.

Un'altra cosa se possibile:
non mi è chiaro in che caso si usano metodo la cui interfaccia è per esempio


public void push(A elem) //A inteso come tipo placeholder

oppure questo


public <A> A metodo()


Cioè non capisco i metodi parametrizzati come si differenziano dai non parametrizzati, non dovrebbero essere tutti del tipo della seconda riga? Ho provato sullo stack ma dà altri errori.

Ringrazio chiunque possa risolvermi un pò di questi dubbi :ciauz:

netarrow
04-02-2005, 21:04
credo che l'errore sia dovuto dal fatto che quando, in List, dichiari

protected Node head.

A node non passi il tipo, dovresti fare così:



...
public class List <A>
{
protected Node<A> head;

public List()
{
head = null;
}
...


e quando allochi con new devi fare la stessa cosa:



...
public void add(A el)
{
head = new Node<A>(el,head);
}
...


Quindi quando dichiarerai un oggetto list alla classe dovrai passare un tipo, per esempio:



...
List<String> l = new List<String>();
...


Anch'io non sono pratico delle novità di Java 5, se c'è qualcosa di sbagliato ci sono utenti già disinvolti con queste cose che magari faranno un salto nel thread.

:ciauz:

namek
04-02-2005, 21:43
Ho smanettato un pò e sono arrivato a togliere, non so se per pura casualità, l'errore di incompatible types, ora compare questo messaggio strano:
Note: C:\..\..\.\.\.\\SLList.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Process completed.

Questo è il codice allo stato attuale:


public class Node <A>
{
public A chiave;

public Node next;

public Node(A el)
{
chiave = el;
next = null;
}

public Node(A el, Node ptr)
{
chiave = el;
next = ptr;
}
}

public class List <A>
{
protected Node<A> head;

public List()
{
head = null;
}

public void add(A el)
{
head = new Node<A>(el,head);
}

public A deleteHead()
{
Node<A> el = head;
head = head.next;
return el.chiave;
}
}

public class Stack <A>
{
protected List<A> lista;

public Stack()
{
lista = new List<A>();
}

public void push(A el)
{
lista.add(el);
}

public A pop()
{
return lista.deleteHead();
}
}


Comunque sia è il metodo deleteHead() della List il codice critico, è anche l'unico col return, quindi mi sa che ho poco chiaro come si usa un metodo parametrico. :bhò:

:ciauz:

netarrow
05-02-2005, 14:52
Quel messaggio sembra dica che SLList utilizzi operazioni non sicure e di utilizare l'opzione del compilatore -Xlint per avere più info.

Cmq un esempio di Coda col P.P.M in Java 5 è questo :




import java.util.*;

class Coda<A> {
private ArrayList<A> e = new ArrayList<A>();

public void push(A item) {
e.add(item);
}

public A pop() {
int end = e.size() - 1;
A item = e.get(end);
e.remove(end);
return item;
}
}

public class EsempioCoda {

public static void main(String args[]) {

Coda<String> c = new Coda<String>();
c.push("Test1");
c.push("Test2");
c.push("Test3");
c.push("Test4");
c.push("Test5");

System.out.println(c.pop());
System.out.println(c.pop());
System.out.println(c.pop());
System.out.println(c.pop());
System.out.println(c.pop());
}
}


:ciauz:

namek
05-02-2005, 18:32
Ciao, il codice che hai messo sulla coda mi torna, è chiaro e l'ho provato, funziona bene.
Comunque finalmente ho risolto il problema anche al mio codice, si trattava del secondo costruttore della classe Node.java:


public SLLNode(A el, SLLNode<A> ptr)
{
chiave = el;
next = ptr;
}


Avevo messo solo:


public SLLNode(A el, SLLNode ptr)
{
chiave = el;
next = ptr;
}

Quindi potenzialmente potevo dirgli di puntare a un Node, che poteva avere un puntatore next non di tipo <A>, almeno per come l'ho capita io, ora invece c'è il vincolo del parametro di tipo, come è giusto che sia.
:ciauz:

Loading