First of all: I'm not trying to re-invent the wheel, this is for purpose of study.
I'm quite a newbie in java world so be patient.
My aim is to build a public class to manage linked list with sorted insertion.
What I did so far (that is working) is:
import java.util.Iterator;
import package_Car.SortTypes;
class Node<E>
{
E data;
Node<E> next;
Node(E data, Node<E> node)
{
this.data = data;
this.next = node;
}
public Node<E> getNext()
{
return next;
}
}
public class SortedInsertionLinkedList<E> implements Iterable<Node<E>>
{
Node<E> root;
Sort_Types sort;
final class LinkedListIterator implements Iterator<Node<E>>
{
private Node<E> cursor;
LinkedListIterator(Node<E> root)
{
cursor = new Node<E>(null, null);
cursor = root;
}
public boolean hasNext()
{
return cursor != null;
}
public Node<E> next()
{
Node<E> retVal = cursor;
if (hasNext())
{
cursor = retVal.getNext();
}
return retVal;
}
}
public Iterator<Node<E>> iterator()
{
return new LinkedListIterator(root);
}
public SortedInsertionLinkedList(Sort_Types sort)
{
root = null;
this.sort = sort;
}
public void insert(E item)
{
if (item != null)
{
if (root == null)
{
root = new Node<E>(item, null);
}
else
{
Node<E> currNode = root;
Node<E> prevNode = null;
for (Node<E> currListNode : this)
{
if (sort.compareTo(currListNode.data, item) < 0)
{
prevNode = currListNode;
currNode = currListNode.next;
}
}
Node<E> t = new Node<E>(item, currNode);
if (prevNode == null)
root = t;
else
prevNode.next = t;
}
}
}
public void print()
{
for (Node<E> currNode : this)
{
System.out.print(currNode.data + " ");
System.out.println();
}
System.out.println();
}
public boolean find(E x)
{
for (Node<E> currNode : this)
{
int c = sort.compareTo(currNode.data, x);
if (c == 0)
return true;
if (c > 0)
return false;
}
return false;
}
public void delete(E x)
{
Node<E> prevNode = null;
for (Node<E> currNode : this)
{
int c = sort.compareTo(currNode.data, x);
if (c == 0)
{
if (currNode == root)
{
root = currNode.next;
}
else
{
prevNode.next = currNode.next;
}
return;
}
if (c > 0)
return;
prevNode = currNode;
}
}
}
As you can see I added to my class a private field that define which type of sort have to be used to compare linked list Nodes. This sort type is a enum
public enum Sort_Types
{
SORT_BY_NAME
{
public int compareTo(Object o1, Object o2)
{
Car item1 = (Car) o1;
Car item2 = (Car) o2;
return item1.nome.compareTo(item2.nome);
}
},
SORT_BY_PRICE
{
public int compareTo(Object o1, Object o2)
{
Car item1 = (Car) o1;
Car item2 = (Car) o2;
return Double.compare(item1.prezzo, item2.prezzo);
}
},
SORT_BY_GAIN
{
public int compareTo(Object o1, Object o2)
{
double gain1;
double gain2;
if (o1 instanceof CarSpecificInterface)
{
CarSpecificInterface dummy = (CarSpecificInterface) o1;
gain1 = dummy.gain();
}
else
{
throw new IllegalArgumentException();
}
if (o2 instanceof CarSpecificInterface)
{
CarSpecificInterface dummy = (CarSpecificInterface) o2;
gain2 = dummy.gain();
}
else
{
throw new IllegalArgumentException();
}
return Double.compare(gain2, gain1);
}
},
SORT_BY_URGENCY
{
public int compareTo(Object o1, Object o2)
{
double urgency1;
double urgency2;
if (o1 instanceof CarSpecificInterface)
{
CarSpecificInterface dummy = (CarSpecificInterface) o1;
urgency1 = dummy.urgency();
}
else
{
throw new IllegalArgumentException();
}
if (o2 instanceof CarSpecificInterface)
{
CarSpecificInterface dummy = (CarSpecificInterface) o2;
urgency2 = dummy.urgency();
}
else
{
throw new IllegalArgumentException();
}
return Double.compare(urgency2, urgency1);
}
};
public abstract int compareTo(Object o1, Object o2);
}
Why I did that? Because of class that can be used to instatiate the linked list are 3:
Car
New_Car
that extends Car
Used_Car
that extends Car
New_Car
and Used_Car
classes implements an interface
public interface Car_Specific_Interface
{
public double gain();
public double urgency();
}
So I can use my linked list for type Car that can accept (obviously) SubClasses
Sorted_Linked_List<Car> carsSortedByName;
Sorted_Linked_List<Car> carSortedByGain;
Sorted_Linked_List<Car> carSortedByUrgency;
public DB_Mng()
{
carsSortedByName = new Sorted_Linked_List<>(Sort_Types.SORT_BY_NAME);
carSortedByGain = new Sorted_Linked_List<>(Sort_Types.SORT_BY_GAIN);
carSortedByGain = new Sorted_Linked_List<>(Sort_Types.SORT_BY_URGENCY);
}
So, to sum up: I have a generic linked list with sorted insertion that can accept different classes and can be sorted by specific field or methods.
What I'd like to understand is if there is a way to do that changing classes hierarchy "simply" implementing Comparable
interface.
Step one is to understand java generics. Specifically, java generics are a compile time feature; they are in no way a java implementation of c++ templates.
You can not create a "fully general" sorted-on-insert list because Object does not implement any comparison functionality.
You can create a sorted-on-insert list of elements that implement some known interface or which extend a specific class.