使用自己的字段识别Set中的对象?

时间:2017-07-17 08:02:53

标签: java algorithm set

我在Java中编写了一个关于图论的算法,并将图上的节点定义为:

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 问题是:我希望在Node中使用特定的HashSet(因此UUID)存储特定的hashCode实例,因为我必须更新邻接列表对于每个节点, WHILE 我实际上无法使用任何Set来执行此操作。

我想我很困惑。如果我切换到Map<String, Node>并将UUID作为关键,那么在Node类中定义UUID会感到愚蠢( UUID在逻辑上成为Node的一部分!)

我已阅读this post并仍然认为java应提供访问Set中的元素的接口(或至少部分实现),因为这不是不可能通过二叉树,就像C++ STL set.find()那样。

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

2 个答案:

答案 0 :(得分:0)

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

java似乎非常奇怪java专注于"modeling the mathematical set abstraction",而C ++中的std::set::findstd::unordered_set::find可以获取O(log n)Log(1)中的集合中的元素(平均)分别。

好吧,我的结论是:如果你想将某些对象存储在某个数据结构中而不需要保持它们的顺序,以后再获取要更新的特定对象,你仍然应该使用java.util.Set。即使您必须添加一些冗余字段或密钥,也请使用java.util.Map如果没有迭代整个集合,你无法真正从Set in Java中获取任何内容。

答案 1 :(得分:0)

如果您使用HashSet,

  • 你可以使用clone()(返回此HashSet的浅表副本)
  • 在此副本上调用retainAll以仅过滤所需的节点。

:)