HashMap以对象值为键

时间:2016-09-09 07:36:13

标签: java object dictionary hash

假设我有2个节点列表(节点是一些可比较的对象,细节无关紧要)。我想找到哪两个节点出现在两个列表上 - 不一定是相同的Node对象,而是compareTo返回0的节点。

例如,nodeA在列表A上,nodeB在列表B上。它们不是同一个节点,但nodeA.compareTo(nodeB)将返回0(相等)。

我想通过迭代列表A并将节点放在HashMap / HashSet中来解决这个问题,然后迭代列表B并检查哪些节点已经插入到HashMap / HashSet中。问题是,这不起作用,因为HashMap不会认为节点是相同的,除非它们是相同的实际节点。

我该如何解决这个问题?请注意,我正在寻找此问题的其他解决方案,但是为了理解if(以及如何)在给定的示例场景中我可以使用HashMap,HashSet或其他类似的数据结构。

4 个答案:

答案 0 :(得分:2)

你可以通过覆盖Node对象中的equals和hashcode方法来使用与compareTo方法相同的标准来解决这个问题(如果我理解这一点)。

答案 1 :(得分:2)

您应该使用TreeSet,因为依赖于排序,而不是哈希

更新(错误!请参阅更新3):但是您仍然必须确保a.compareTo(b)==0 iff a.equals(b),因为{{3}实际上通过排序找到相应的元素,然后使用equals

检查相等性

更新2:要仅使用排序,您可以对第一个列表进行排序(Collections.sort(listA)),然后检查每个Collections.binarySearch(listA, nodeB)的结果nodeB来自listB。当结果为>=0时,nodeB位于listA,w.r.t他们的排序。 implementation of contains,没有平等参与。此方法的复杂性为O(n log(n)),因为每个二进制搜索都是O(log(n))n是列表中较大者的大小 - 排序列表A也是O(n log(n))),与使用TreeSet(O(log n)对于insert / contains)具有相同的复杂性。

更新3:正如评论中指出的那样,TreeSet应该开展工作,因为equals {{未使用TreeMap's 1}},但在其他地方。但是JavaDoc说:

  

注意由一组维护的排序(无论是否显式   比较器提供)必须与equals一致,如果是的话   正确实现Set接口。

The implementation of binarySearch uses only ordering(!)说:

  

如果此set包含指定的元素,则返回true。更多   形式上,当且仅当此集合包含元素e时才返回true   这样(o == null?e == null:o.equals(e))。

因此,将containsKey与不存在的API一起使用仍然不是一个好主意。谁知道在这种情况下另一个 Java实现可能会做什么。所以我建议坚持使用 Update 2 解决方案。

答案 2 :(得分:0)

我的建议是让你自己的HashMap子类用一个符合你标准的函数覆盖containsValue(对象值)函数。

答案 3 :(得分:0)

使用 TreeSet / TreeMap 。它使用 compareTo()方法而不是equals()和hashcode(),这是在HashMap / HashSet中分配节点时使用的。

请查看以下代码:

import java.util.HashSet;
import java.util.TreeSet;

public class TestMaps {

public static void main(String[] args) {
    TreeSet<Node> set1 = new TreeSet<>();
    HashSet<Node> set2 = new HashSet<>();

    Node node1 = new Node(0, "First");
    Node node2 = new Node(0, "Second");

    System.out.println(set1.add(node1)); //Node1 added in TreeSet
    System.out.println(set2.add(node1));//Node1 added in HashSet
    System.out.println(set1.add(node2));//Node2 added in TreeSet
    System.out.println(set2.add(node2));//Node2 added in HashSet
}


}

class Node implements Comparable<Node>{
int i;
String name;

Node(int i, String n){
    this.i = i;
    this.name = n;
}
@Override
public int compareTo(Node o) {

    return this.i - o.i;
}
}

将此结果运行到:

true
true
false
true

希望它有所帮助!!