Java:有一个项目集合,其中每个项目都有一个字段;“上一项”;,订购藏品最有效的方式是什么?

Java:有一个项目集合,其中每个项目都有一个字段;“上一项”;,订购藏品最有效的方式是什么?,java,collections,hierarchical-data,Java,Collections,Hierarchical Data,我在一个未排序的集合中有一个层次项目集合。每个项目都有一个字段previousItem: public class Item{ public Item previousItem; } 处理这些项以使输出成为集合的最有效方法是什么,其中没有任何previousItem的项是集合中的第一项,而每个子序列项的previousItem是集合中的前一项 我的第一个想法是在Item类中实现可比较的接口: public int compareTo(Item that) { final int

我在一个未排序的集合中有一个层次项目集合。每个项目都有一个字段previousItem:

public class Item{
   public Item previousItem;
}
处理这些项以使输出成为集合的最有效方法是什么,其中没有任何previousItem的项是集合中的第一项,而每个子序列项的previousItem是集合中的前一项

我的第一个想法是在Item类中实现可比较的接口:

public int compareTo(Item that) {
    final int BEFORE = -1;
    final int EQUAL = 0;
    final int AFTER = 1;

    if(this.previousItem==null){
        return BEFORE;
    }

    if(that.previousItem==null){
        return AFTER;
    }

    if(this.previousItem.equals(that){
        return AFTER;
    }else if(that.previousItem.equals(this){
        return BEFORE;
    }

    return EQUAL;
}
然后循环浏览项目并将其添加到树集:

SortedSet<Item> itemSortedSet = new TreeSet<Item>();
for (Item item : itemCollection) {
    itemSortedSet.add(item);
}
SortedSet itemSortedSet=new TreeSet();
用于(项目:itemCollection){
itemSortedSet.add(项目);
}

是否有一种更有效的方法(更少的处理时间/所需的迭代次数)来对集合进行排序,使它们按逻辑、层次顺序排列?

您的比较器将无法工作:它不提供传递性,即,如果在a->B->C的情况下比较项目a和C,它将做错误的事情

如果没有项目可以具有相同的上一个项目,则
项目
对象基本上构成一个基本链表。如果您碰巧知道最后一项是哪一项,则可以从该项开始使用单个循环并分解整个结构:

Item last = ...;

while (last != null) {
    result.add(last)
    last = last.previousItem
}
如果无法找出最后一个项目,则可以使用将每个
以前的项目
值映射到使用它的
项目
对象:

IdentityHashMap<Item,Item> m = new IdentityHashMap<Item,Item>(itemset.size());

for (Item i : itemset)
    m.put(i.previousItem, i);

Item i = m.get(null);

while (i != null) {
    result.add(i);

    i = m.get(i);
}
IdentityHashMap m=newidentityhashmap(itemset.size());
用于(项目i:项目集)
m、 put(i.上一项,i);
项目i=m.get(空);
while(i!=null){
结果.添加(i);
i=m.get(i);
}
这将从没有上一个节点的项开始分解未排序的集合

这两种方法都具有大致线性的复杂性,即项目数量,但它们做出的两个假设在您的情况下可能无效:

  • 每个项目最多只能是另一个节点的上一个项目,即项目是列表而不是树

  • 有一个单一的项目“线程”


如果这些假设中的任何一个都无效,您将需要一个更复杂的算法来解决这个问题。

您的比较器将不起作用:它不提供传递性,也就是说,如果您在a->B->C的情况下比较项目a和C,它将做错误的事情

如果没有项目可以具有相同的上一个项目,则
项目
对象基本上构成一个基本链表。如果您碰巧知道最后一项是哪一项,则可以从该项开始使用单个循环并分解整个结构:

Item last = ...;

while (last != null) {
    result.add(last)
    last = last.previousItem
}
如果无法找出最后一个项目,则可以使用将每个
以前的项目
值映射到使用它的
项目
对象:

IdentityHashMap<Item,Item> m = new IdentityHashMap<Item,Item>(itemset.size());

for (Item i : itemset)
    m.put(i.previousItem, i);

Item i = m.get(null);

while (i != null) {
    result.add(i);

    i = m.get(i);
}
IdentityHashMap m=newidentityhashmap(itemset.size());
用于(项目i:项目集)
m、 put(i.上一项,i);
项目i=m.get(空);
while(i!=null){
结果.添加(i);
i=m.get(i);
}
这将从没有上一个节点的项开始分解未排序的集合

这两种方法都具有大致线性的复杂性,即项目数量,但它们做出的两个假设在您的情况下可能无效:

  • 每个项目最多只能是另一个节点的上一个项目,即项目是列表而不是树

  • 有一个单一的项目“线程”


如果这些假设中的任何一个都无效,您将需要一个更复杂的算法来解决这个问题。

据我所见,您的项目已经实现了一个链表(如果不是按名称),因此(对我来说)将其放入集合的自然方式是递归地将其转换为真实列表。转换项目后,可能需要根据您的规范反转列表

public class Item {
   Item previousItem;

   public void putToCollection(ArrayList<Item> list) {
     list.add(this);
     if (previousItem == null) {
       Collections.reverse(list);
     } else {
       previousItem.putToCollection(list);
     }
   }
}
公共类项目{
项目之前的项目;
公共无效putToCollection(ArrayList列表){
列表。添加(此);
如果(previousItem==null){
收款。反向(列表);
}否则{
上一项。putToCollection(列表);
}
}
}

据我所见,您的项目已经实现了一个链表(如果不是按名称),因此(对我来说)将其放入集合的自然方式是递归地将其转换为真实列表。转换项目后,可能需要根据您的规范反转列表

public class Item {
   Item previousItem;

   public void putToCollection(ArrayList<Item> list) {
     list.add(this);
     if (previousItem == null) {
       Collections.reverse(list);
     } else {
       previousItem.putToCollection(list);
     }
   }
}
公共类项目{
项目之前的项目;
公共无效putToCollection(ArrayList列表){
列表。添加(此);
如果(previousItem==null){
收款。反向(列表);
}否则{
上一项。putToCollection(列表);
}
}
}

如果我理解正确,您可以在没有上一个对象的情况下处理Item对象。您可以循环遍历这些项(例如,使用while循环)并将它们添加到ArrayList或LinkedList,因为这些列表实现的add()方法只是在列表的末尾追加一个新项。这样,您就可以在O(n)时间内完成它。

如果我理解正确,您就可以在没有前面对象的情况下处理Item对象。您可以循环遍历这些项(例如,使用while循环)并将它们添加到ArrayList或LinkedList,因为这些列表实现的add()方法只是在列表的末尾追加一个新项。这样,您可以在O(n)时间内完成它。

您可以使用一个
散列集
,您可以在其中首先放置所有项目。然后在循环中检查项目,并从集合中删除每个
previousItem
。最后,您应该在集合中留下一个元素,即最后一个元素,它不是任何其他项目的
previousItem
。然后,您可以简单地从该项目开始并通过链接添加项目。

您可以使用一个
HashSet
,首先将所有项目放入其中。那你走吧