[解决]
我是一名C ++人,正在为即将到来的工作学习Java。因此,我正在练习使用Java自己实现链接列表。我完成了一个标准的双链表,它运行得很好。但是,然后我尝试创建一个有序链接列表,并意识到无法重载'<'运营商将成为一个严重的问题。
我在这个网站上查看了其他人的问题,但它仍然没有传达给我,所以我想我会发布我的代码并获得更适合我正在做的事情的答案。
勇往直前..
链接列表类:
public class MyList<T> {
/*** ~Public Interface~ ***/
//insert, delete, size, print, etc.
...
/*** Private Data Members ***/
//node begin, end, T data
....
/** Private node class **/
//Represents the nodes in the list
private class node implements Comparable<T>{ //Don't know if this is right
node next;
node prev;
T data;
node(node p, node n, T d){
next = n;
prev = p;
data = d;
}
@Override
public int compareTo(T o) {
return (data <= o ? 1 : 0); //Get an error still here
}
/** Iterator **/
//iterator class
}
有序链接列表类:
public class OrderedList<T> extends MyList<T> implements Comparable<T>{ //Pretty sure this is wrong
public void insert(T d){
if(empty()){
push_front(d);
} else {
MyList<T>.MyListIter it = begin();
int i = 0;
//This won't work obviously
for(; i < size() || it.current().compareTo(it.next()) == -1; ++i, it.next()){
//find node to place the new node before it
it.prev() //Need to go back one since we went forward in the loopcheck.
}
}
}
这里真的不知所措。如何实现类似于运算符重载的东西,以便我可以完成这个有序列表实现?
我也试图掌握Java中的继承,所以如果你在这方面看到错误的话,也可以随意加入。
谢谢大家。
更新:
好的,我做了我认为必须做出的改变,但我仍然遇到了错误。这是新代码:
MyList类中的节点类:
private static class node<T> implements Comparable<T>{
node<T> next;
node<T> prev;
T data;
node(node<T> p, node<T> n, T d){
next = n;
prev = p;
data = d;
}
public int compareTo(T o) {
return ((Comparable<T>) this.data).compareTo(o);
}
}
订购清单:
公共类OrderedList&gt;扩展MyList {
compareTo的用法:
if(((Comparable<T>) it).compareTo(it.next()) == -1) found = true;
编译器强迫我做那些演员,现在错误是:
MyList$MyListIter cannot be cast to java.lang.Comparable
列表迭代器类看起来像:
public class MyListIter{
它在MyList中。
编辑[求助]
当我使用我的迭代器时,而不是使用it.current()来访问实际数据,我正在做it.compareTo(..),但当然我的迭代器不是数据,因此不了解compareTo()的任何信息。
答案 0 :(得分:2)
虽然这是一个很好的练习,但我不会雇用a)首选使用自己的LinkedList来构建一个b)使用LinkedList作为已排序集合的排序集合和更有效的ArrayList对于这种......;)
我建议您阅读LinkedList,ArrayList和TreeSet的源代码,以了解如何在JDK中实现这些内容。我还建议您阅读java.lang.
和java.util.
您希望将节点与其他节点进行比较,并且您需要使您的数据类型具有可比性。您还应该使用Java代码约定。
public class MyList<T extends Comparable<T>> {
static class Node {
Node prev, next;
T data;
Node(Node p, Node n, T d){
next = n;
prev = p;
data = d;
}
}
public void insert(T d){
if(empty()){
push_front(d);
return;
}
for (Node<T> node = first;node.next != null; node = node.next) {
// if less than we need to insert before.
if (d.compareTo(node.data) < 0) {
if (node == first) {
first = new Node(null, first, d);
node.prev = first;
} else {
node = new Node(node.prev, node, d);
node.prev.next = node;
}
return;
}
答案 1 :(得分:1)
正如您所说,您不能在Java中重载运算符。这意味着您的排序列表不能使用&lt; =来比较任何类型的对象。相反,您需要依赖数据对象来获得compareTo()
方法,或者为列表的用户提供一种方法来提供Comparator
对象。如果您希望严格限制您的列表到第一种情况,您可以将其声明为
public class OrderedList<T implements Comparable<T>> extends MyList<T>
这将保证插入列表的对象具有compareTo()
方法。现在,您的Node.compareTo()
函数只是将比较与此方法进行对比:
public int compareTo(T o) {
return this.data.compareTo(o.data);
}
允许自定义Comparator
可能会有点棘手。我建议您在进行默认比较后继续使用。
P.S。您希望能够将列表相互比较吗?如果是这样,那么OrderedList
实施Comparable
是有道理的。但是,在列表类使用其基本操作后,您可能希望将此保留用于稍后的练习。