[英]Doubly Linked List with generic node type
我需要一个可以在不同节点实现上使用的双向链表。 请注意,我不希望包含通用数据的节点,如DoublyLinkedNode<T>
,但像DoublyLinkedList<N extends DoublyLinkedNode<T>>
。
确切地说,在通常情况下,我将列表与标准节点一起使用,但在程序的其他部分中,我需要具有附加字段的节点。 所以我将通用节点实现为
public class DoublyLinkedNode<T> {
DoublyLinkedNode<T> before, after;
T value;
}
和特殊类型为
public class DoublyLinkedSpecialNode<T, S> extends DoublyLinkedNode<T> {
S specialValue;
}
现在在我的DoublyLinkedList实现中,我希望能够在一个实例中处理这两种情况,因为所有代码基本上都会使用两个实现明显相同的指针。
这给出了一些要求:
1)当我使用特殊节点时,我希望能够将其作为DoublyLinkedSpecialNode
类型返回,以便能够访问其他字段。
2)该列表必须使用DoublyLinkedNode类型来访问节点的指针。
3)列表将指向的节点分配给其他节点,例如head = node.after;
,因此特殊节点中指针的类型必须与列表中的类型相同。
扩展列表毫无意义,因为我无法更改方法的返回类型。 因此,我尝试了两个想法,但没有成功:
已经提到的解决方案:从DLN扩展的通用节点类型
列表看起来像这样:
public class DoublyLinkedList<T, N extends DoublyLinkedNode<T>> {
N head, tail;
N tail() {
return tail; // OK
}
void remove(N node) {
if (head == node) {
head = node.after; // Type error
}
...
此解决方案与要求3)冲突,因为在列表中类型是从DLN扩展的N,但是在节点实现N中,指针是基类/接口DLN的类型(理论上,指针类型可以更通用)比N)。
基本DLN而非通用
在这种情况下,列表在基类节点上工作,并且由于多态性而接受子类:
public class DoublyLinkedList<T> {
DoublyLinkedNode<T> head, tail;
DoublyLinkedNode<T> tail() {
return tail;
}
void remove(DoublyLinkedNode<T> node) {
if (head == node) {
head = node.after; // OK
}
...
但是tail()只能返回一般类型的节点,与1)冲突。 我宁愿不使用强制转换,因为我认为这是不好的做法(?),但也因为实现对性能至关重要。 当然有更好的方法吗?
我找到了另一种解决方案,它是好的,不是很高效,但比上一个解决方案更优雅。
这个想法只是使用一种类型的节点,并将不同的内容包装在一个通用的容器中。 DLN代码如下所示:
public class DoublyLinkedNode<C> {
DoublyLinkedNode<C> before, after;
C content;
public static class ValueContent<T> {
T value;
}
public static class ValueSpecialContent<T, S> extends ValueContent<T> {
S specialValue;
}
}
然后列表实现看起来像这样:
public class DoublyLinkedList<C> {
DoublyLinkedNode<C> head, tail;
public DoublyLinkedNode<C> head() {
return head;
}
void remove(DoublyLinkedNode<C> node) {
if (head == node) {
head = node.after;
...
我可以从调用类访问特殊字段,如下所示:
DoublyLinkedList<SpecialContent<SpecialType>> list;
SpecialType s = list.head().content.specialValue;
有一些开销,因为每个节点都必须实例化该容器类,但是我认为它仍然比强制转换更好。 我必须检查性能影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.