【问题标题】:Which data structure should I use for maintaining this information?我应该使用哪种数据结构来维护这些信息?
【发布时间】:2017-02-07 12:05:16
【问题描述】:

大家好,我有两个实体通过关系相互连接,如下所示:

实体 B 知道实体 A,实体 B 知道实体 A。

我可以使用哪种最有效的数据结构来维护这些信息?

我想有 2 个哈希图,其中键为实体的 A 键,并为每个了解 A 的 B 实体赋值一个列表,另一个具有键实体 B 的键等。但我想知道我是否可以只使用一个数据结构。

我的目标是速度而不是空间性能,所以只要它快,它是否大并不重要。

【问题讨论】:

  • 不可能作曲
  • 查看在休眠中管理了多少对多关系。
  • 我认为这不能以这种一般形式解决。的确,我们可以建议一种或另一种结构,但它们都同样有效,因为我们不知道谁将使用关系信息以及用于什么目的。在某些情况下,将其建模为 Map>, Multimap 或 Entity 本身的私有字段是完全合理的 - 我们不知道。
  • 总是对称的吗?
  • @Sentry 在什么意义上对称?所有对象都已知或至少知道一个对象?

标签: java data-structures


【解决方案1】:

为什么要使用数据结构? 这是两个对象之间的“正常”双向关联。

class A {
    B b;
    ....
    // Perhaps you can do somthinkg like this to maintain consitsncy
    void setB(B b) {
        this.b = b;
        b.a = a;
}
class B {
    A a;
    ....
}

【讨论】:

【解决方案2】:

鉴于您提到重点是速度,这实际上归结为您需要如何访问数据,即您需要对数据结构提出什么问题。

例如,如果您只需要问“X 是否知道 Y”或“Y 是否知道 X”这样的问题,那么您只需要一个哈希映射。或哈希集, 只要您可以为它们中的一对生成一个像样的 hashCode() 实现 (请参阅前面的示例 hashCode 实现,虽然可能不是一个好的实现,而且我已经有很多年没有使用 Java 了)

即有一套

class Item extends Pair {
  Item(A,B)
  // override hashCode() and equals() methods as necessary 
}

hashset<Item> relationships;
relationships.add(new Item(A,B))
relationships.add(new Item(B,C))

if( ! relationship.contains (new Item(B,A)))
   // print "b does not know a"

或地图:

HashMap<Item,Boolean> relationships;
relationships.put(Item(A,B),True)
....

但是,如果您需要查看一个实体,然后找到它所知道的所有内容,那么图结构会更好。

如果您正在构建一个不需要太多灵活性的一次性数据集,您可以将图形实现为单个链表,包含从起点开始的所有边,并有一个哈希(按对象键)指向到每个已知项目列表的第一条边。

例如,未经测试的伪代码,不正确的java

Class Item {
  Entity first
  Entity second
  Item next;
  Item prior;
  Item(x,y) { first = x; second = y; }
  Item Join(nextItem) { 
    next = nextItem; next.prior = this; return next; 
  }
  // override hashCode and equals() but don't use 'next' or prior as part of the hash calculation or equals comparison

  //this is just for example, not sure if this is a good hash
  long hashCode() { return a. hashCode() & b.hashCode(); }
}

class Graph extends HashSet<Item> {

  Bool containsRelationship(Entity x, Entity y) {
     return contains(new Item(x,y))
   }
   Bool isRcognisedEntity(Entity x) {
     return contains(new Item(x,x))
  }
  Item getRelationships(Entity x) {
      Item ret = get(new Item(x,x))
       if ret is not null
         return ret.next // return the first entity x knows, other than itself
       else 
         return null // nothing known
  }

  Item addEntity(Entity e, Entity[] e_knows) {
     Item first = new item (e,e)
     add(first)
     Item lastItem = first
     for k in e_knows
         lastItem = lastItem.join(new item(e,k))
         add(lastItem)
     return first
  }
}

Entity a;
Entity b;
Entity c;
Graph g;
g.addEntity(a, {b,c})
g.addEntity(b, {c})
g.addEntity(c,{ a,b,c})

if g.contains(item(a,b))
   Print "a knows b"

c_knows = g.getRelationships(c)

while c_knows is not null
   Print "c knows " + c_knows.second
   c_knows = c.next

所以你只用一个集合就可以看到这种方式,你可以问“x 知道 y”和“x 知道谁”,代价是下一个/先前属性的一些内存开销(你可能只需要一个)

如果您有两个单独的 A 和 B 类而不是一个通用的 Entity 基类,那么您可以使用 Object 来执行此操作,并根据需要在 Graph 类的例程中转换结果以提供类型安全。

例如

class Item {
  Object first;
  Object second;
 ...
}
class Graph {
 // as above except use Object instead of Entity, and make the methods protected not public
}
class ABGraph extends Graph {

   Iterator getRelationships(A a) {
     return new B_Itemterator(super.getRelationships(a));
   }
   void addRelationships(A a,B[] b_knows) {
     super.getRelationships( a, b_knows)
   }
   // Similar functions for B
}
class A_ItemIterator implements Java.collections...Iterator<A> {
  A_ItemIterator(Item i) { this.i = I }
  bool hasNext() { return i.next !=  null; }
  A next() { item n = i.next; I = n; return n; }
}

// similar iterator class for B_ItemIterator

ABGraph g;
A a;
B b1;
B b2;
g.addRelationships(a, new B[]{b1,b2})

if g.contains (a,b1) // should still work 

Iterator<B> i= g.getRelationships(a)
while(i.hasNext())
  print " thing "+ a + " of type A knows about " + b.next() + "of type B'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多