2017-07-17 71 views
0

我在写在Java中图论的算法,并已在图中的节点定义为:使用自己的字段在Set中标识对象?

public class Node { 
    public String UUID; 
    public Set<Node> children; 
    // and some other fields & methods 

    @Override 
    public int hashCode() { 
     return UUID.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (obj == null) return false; 
     if (!(obj instanceof Node))return false; 
     Node other = (Node)obj; 
     return UUID.equals(other.UUID); 
    } 
} 

在曲线图上的任何特定的节点的UUID领域进行了保证是唯一的(通过输入数据集) ,因此我计划将所有节点存储在HashSet<Node>中,同时读取输入数据集并构建在Node类中也定义为Set<Node> children的邻接列表。

不过,我很快注意到我无法以优雅的方式将Node实例存储在我的HashSet<Node>中,因为Set不能被随机访问。

的parentNode,childNode 的问题是:我想要得到存储在HashSet与特定Node实例的具体UUID(因而有相同的hashCode),因为我必须更新每个节点的邻接表,WHILE我无法真正使用任何Set来做到这一点。

我想我很困惑。如果我切换到Map<String, Node>,使UUID是关键,它只是感觉就像哑巴Node类(UUID应该是基站的一部分逻辑!)

我读过this post,并仍然相信定义UUID java应该提供接口来访问Set中的元素(或者至少它的一些实现),因为这通过二叉树不是不可能的,就像C++ STL set.find()那样。

有关我该如何破解这个的任何建议?

+3

'节点其它=(节点)OBJ;' - >不而不检查'instanceof'安全。 – shmosel

+1

使用地图不是愚蠢的。这是您想要通过特定密钥访问时所做的事情。 – RealSkeptic

+1

顺便说一句,根据你的建议,使用'Map '没有什么愚蠢的。 – Eran

回答

0

我从HashSet<Node>切换为Map<String, Node>,其中UUID用作关键字符串,用于存储图上的所有节点,但仍将UUID字段保留在Node类中以备将来扩展。

看来非常奇怪的是java的如此关注"modeling the mathematical set abstraction",而用C std::set::findstd::unordered_set::find ++可以O(log n)Log(1)(平均)分别获取集合中元素。

嗯,我的结论是:如果你想存储在一定的数据结构中的一些对象,而不让他们为了要求,后来取特定对象进行更新,你仍然should't使用的java.util 。组。使用java.util.Map来代替,即使您必须添加一些冗余字段或密钥。 如果没有迭代整个集合,你无法真正从Set in Java中获取任何东西。

+0

这并不奇怪。 Java中的集合表示一组元素,而不是键。单独查找元素是没有意义的。 – shmosel

0

如果您使用HashSet的,

  • 您可以使用克隆()(返回此HashSet中的浅拷贝)
  • onthis复制调用中的retainAll过滤只有你想要的节点。

:)

+0

制作浅拷贝对我来说太贵了,因为我必须多次重复读取和更新一个元素,而且我认为Map对我来说很有用。奥弗,谢谢你的回答。 –

相关问题