Java的入侵列表实现?

Java的入侵列表实现?,java,list,collections,linked-list,Java,List,Collections,Linked List,是否有任何(实现良好的)可用于Java的侵入式双链表类?还是我应该自己做?Boost为C++提供了它: 介入式列表是一个在元素中具有(在本例中)next和prev指针的容器,所以像replace和remove这样的典型列表操作可以直接针对基本类而不是容器类。在某些情况下,侵入式列表是最佳解决方案 我试图给出一个适当的例子。假设我有链表L list1和L list2,它们属于不同类型的类X1和Y2 类Q(它与x1和Y2的接口无关,或者不容易访问x1和Y2的接口)需要执行i)替换,ii)删除元素e的

是否有任何(实现良好的)可用于Java的侵入式双链表类?还是我应该自己做?Boost为C++提供了它:

介入式列表是一个在元素中具有(在本例中)next和prev指针的容器,所以像replace和remove这样的典型列表操作可以直接针对基本类而不是容器类。在某些情况下,侵入式列表是最佳解决方案

我试图给出一个适当的例子。假设我有链表L list1和L list2,它们属于不同类型的类X1和Y2

类Q(它与x1和Y2的接口无关,或者不容易访问x1和Y2的接口)需要执行i)替换,ii)删除元素e的操作,元素e始终存在于list1 xor list2的某个地方,具体取决于运行时状态,但该信息不会直接存储在任何地方

使用intrussive list Q可以将对元素的引用存储到成员元素e,并且它总是指向正确的位置

否则,您必须从几个明显更复杂的解决方案中选择一个或另一个。 -元素e的包装类和用于完成操作i和ii的附加方法。没有

基本上,问题仍然不是性能,而是架构的复杂性。这也可以理解为一种共享对象情况,解决方案IL避免了每个客户端Lx和Q的更新需求

请注意,我不需要与其他标准容器兼容。这只是一个通用的侵入式lsit实现,具有用于未知元素类的迭代、添加、删除和查找操作


谢谢。

你看了报纸了吗?根据javadoc,“一个支持两端元素插入和移除的线性集合。deque是“双端队列”的缩写,通常读作“deck”
它是由和实现的。

Java的语义是由设计侵入的,它们使用引用而不是复制。基本上,您只想找到java拥有的最好的链表实现,或者其他什么,这将是一种入侵

import java.util.LinkedList;

public class Foo {

  public static void main(String[] args) {
    String[] i = new String[1];
    i[0] = "FOO";
    String[] j = new String[1];
    j[0] = "BAZ";

    LinkedList<String[]> list = new LinkedList<String[]>();

    list.add(i);
    list.add(j);

    for (String[] x: list) {
      System.out.println(x[0]);
    }

    i[0] = "ZILCH";

    for (String[] x: list) {
      System.out.println(x[0]);
    }
  }
}

如果您查看SDK代码,您将看到LinkedList实际上是一个私有类条目的列表,其中包含下一个和上一个元素。 因此,如果您将MyClass包括在此列表中,列表中的一个元素将是一个条目,其中包含您的对象以及列表中下一个和上一个元素的链接

所以,我认为这是侵入性的

private static class Entry<E> {
    E element;
    Entry<E> next;
    Entry<E> previous;

    Entry(E element, Entry<E> next, Entry<E> previous) {
        this.element = element;
        this.next = next;
        this.previous = previous;
    }
}
私有静态类条目{
E元素;
进入下一步;
入境前;
条目(E元素、下一条条目、上一条条目){
this.element=元素;
this.next=next;
this.previous=先前;
}
}
是否有(实现良好的)可用于Java的侵入式双链表类?

我相信你找不到

我对“入侵”的理解是,要存储在数据结构中的应用程序对象需要直接包括(“入侵”)应用程序对象中的下一个/上一个指针

这与“指针包装器”方法相反,在“指针包装器”方法中,数据结构节点包含指向应用程序对象的指针,因此不需要修改应用程序对象。侵入式方法包括避免“指针包装器”方法常见的双重解引用(一次用于节点,一次用于节点指向应用程序对象的指针)

我不相信您会找到一个针对Java的侵入式数据结构库。Java缺乏类似C++的模板,也没有多重继承,而且它不容易支持整个对象的按值复制。因此,我认为没有一种方法可以将next/prev实例字段一般地添加到Java对象中

例如,给定应用程序对象:

class Foo {
    int bar;
}
不知何故,您需要能够将下一个/上一个字段和列表管理方法添加到该字段或其派生字段:

class Foo2 {
    int bar;
    Foo2 prev;
    Foo2 next;
}
添加这些字段的一种方法是为这些应用程序类提供一个带有这些字段的基类来扩展这些字段,这就是Boost的方法。然而,这种方法在Java这样的单一继承语言中非常有限

Java接口通常是Java对多重继承的回答,例如,需要应用程序类的getNext()和getPrev()方法的接口。但是,如果出于性能原因需要侵入式数据结构,则通过方法访问下一个/上一个字段可能会对这些目标产生不利影响

Java泛型也不以需要的方式扩展类

还是我自己做?

如果这是一次针对一个经过仔细评估的需求的特定案例,那么一定要自己动手。如果你想推出一款通用的,我不确定它是否值得

一种非常重要的方法是自定义扩展应用程序类,以添加所需的字段:

class Foo3 extends Foo {
    Foo3 prev;
    Foo3 next;
}
并使用cut-n-paste重用添加列表管理方法。但是,我强烈建议不要使用这种方法

肥皂盒

您没有说明为什么需要侵入式数据结构。也许你有正当的理由需要一个,但很难想象它们。Java严重依赖于使用对象指针,因此很难像这样避免它们

我恭敬地建议您考虑:

  • 您是否试图过早地优化
  • 您是否在增加不必要的复杂性,却没有什么好处
  • 如果速度和内存管理至关重要,那么您是否使用了正确的语言

我不知道任何现有的实现(也不,我不认为正常的java集合是侵入性的)。 这可能是因为这样一个列表在Java中的唯一主要优势是,当您手头已经有要删除的元素(并且没有

Itera)时,可以快速调用
remove()
class Foo3 extends Foo {
    Foo3 prev;
    Foo3 next;
}
public interface IntrusiveListElement<E extends<IntrusiveListElement<E>> {
  public void setNext(E next);
  public E getNext();
  public void setPrev(E prev);
  public E getPrev();
}

public class IntrusiveList<E extends IntrusiveListElement<E>> implements List<E> {
  // implement your run-of-the-mill double-linked list here
}
public class MyBusinessElement implements IntrusiveListElement<MyBusinessElement> {
  private MyBusinessElement prev;
  private MyBusinessElement next;

  public void setNext(MyBusinessElement next) {
    this.next = next;
  }

      public MyBusinessElement getNext() {
    return next;
  }

  public void setPrev(MyBusinessElement prev) {
    this.prev = prev;
  }

  public MyBusinessElement getPrev() {
    return prev;
  }
}