如何从一个HashMap除去重复密钥

问题描述 投票:0回答:3

我的目录列表。有一个列表中的列表。 [[-1, 0, 1], [-1, 2, -1], [0, 1, -1]],这个列表的名字说结果。结果列表包含重复的元素的列表。 [-1,0,1][0,1,-1]他们是一样的。我想让它不包含重复的列表。所以列表结果变成[[-1,0,1],[-1,2,-1]][[-1,2,-1],[0,1,-1]]

我读到的Hashmap不能存储重复键,但允许重复的值。因此,要删除重复我试图HashMap中。

但写它运行的代码好后没有任何错误。

HashMap<List<Integer>,Integer> final_sol=new HashMap<>();
for(int k1=0;k1<result.size();k1++){
       final_sol.put(result.get(k1),k1);
    }
    System.out.println(final_sol);

输出:

{[-1, 2, -1]=1, [0, 1, -1]=2, [-1, 0, 1]=0}

编写这些代码块后,我想我重复键不能显示显示唯一的密钥。

然后,我怎么能让使用Hash地图这个名单独特之处?Fail to understand

当我用树状图它不编译并有一定的误差。

java hashmap duplicates
3个回答
2
投票

尝试是这样的:

List<List<Integer>> result = Arrays.asList(
      Arrays.asList(-1, 0, 1),
      Arrays.asList(-1, 2, -1),
      Arrays.asList(0, 1, -1)
);
HashMap<Set<Integer>, List<Integer>> final_sol = new HashMap<>();

for (List<Integer> list : result) {
  final_sol.put(new HashSet<>(list), list);
}

System.out.println(final_sol.values());

你想,[-1,0,1][0,1,-1]他们是一样的,但是这并不成立,因为元素事项顺序列表。你需要套平等的这种认识。

但即使如此,它可能不是你所期望的,当[0,0,1][0,1,1]相同。在这种情况下,你必须将每个列表的地图,让你在原始列表同一Integer的计数。


10
投票

这是事实,地图不保留重复键和设置不保留重复的元素,但你要明白,“副本”的键/元素equals()方法来定义的,而基于散列的集合取决于它们的键/元素有hashCode()方法符合其equals()方法一致。

现在你说

[-1,0,1][0,1,-1]他们是一样的。

,但是没有,他们是不一样的,只要Lists'定义的平等进入。列表中的元素的顺序是显著和列表都需要实现在反映的方式equals()。这就是为什么这两个列表可能会出现在同一个Map键,都可以表现为在同一Set元素。

然后,我怎么能让这个名单唯一使用Hash地图?

显然,为了是不是你的目的显著,所以Lists是不是真的让你一起工作的正确的模式。如果您不需要适应重复元素,那么你应该考虑使用套来代替。标准库提供了几种实现方式,其中HashSet很可能是最适合你的情况我了解。如果确实需要,以适应重复元素,那么你正在寻找一个多集。标准库不提供实现,但也有一些第三方提供的。

当我用树状图不编译并给出了一些错误。

嗯,是的,它会,除非你有Comparator只要它由以确定您的元素的相对顺序。 TreeMap识别重复作为根据其自然或比较指定的顺序比较相等的键。

总体而言,这听起来像,而不是列表的列表,想要一套套或一组多集的。我不明白你为什么会希望把地图进去。


0
投票

看样子,你可以做到这一点就行了Set<Set<Integer>>。这就给了你[[-1, 0, 1], [-1, 2]];同态到[[-1, 0, 1], [-1, 2, -1]],但不是你想要的结果。下面是一组三个整数是比较任意排列,这与你的例子一致相等的载体。每documentation,覆盖equals需要equivalence relation,而且必然,hashCode,这样a == b -> hashCode(a) == hashCode(b)

import java.lang.String;
import java.lang.Integer;
import java.util.Set;
import java.util.LinkedHashSet;

class Java {

    public static void main(String args[]) {
        Set<Three> set = new LinkedHashSet<>();
        set.add(new Three(-1, 0, 1));
        set.add(new Three(-1, 2, -1));
        set.add(new Three(0, 1, -1));
        System.out.printf("%s.\n", set);
    }

}

final class Three {
    private int a, b, c;
    public Three(final int a, final int b, final int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    @Override
    public int hashCode() { return a + b + c; }
    @Override
    public boolean equals(Object o) {
        if(this == o) return true;
        if(!(o instanceof Three)) return false;
        Three t = (Three)o;
        /* Brute force 3! = 6. */
        return a == t.a && b == t.b && c == t.c
            || a == t.a && b == t.c && c == t.b
            || a == t.b && b == t.a && c == t.c
            || a == t.b && b == t.c && c == t.a
            || a == t.c && b == t.a && c == t.b
            || a == t.c && b == t.b && c == t.a;
    }
    @Override
    public String toString() {
        return "["+a+","+b+","+c+"]";
    }
}

这将产生,

[[-1,0,1], [-1,2,-1]].

编辑:下面是一组三个整数放在一组,这也与你的例子一致时比较相等向量的上述代码的替代品。

    /** Hashcode is the sum of the unique numbers. */
    @Override
    public int hashCode() {
        int h = a;
        if(a != b) h += b;
        if(c != a && c != b) h += c;
        return h;
    }
    @Override
    public boolean equals(Object o) {
        if(this == o) return true;
        if(!(o instanceof Three)) return false;
        Three t = (Three)o;
        /* t \in this && this \in t. */
        return (a == t.a || a == t.b || a == t.c)
            && (b == t.a || b == t.b || b == t.c)
            && (c == t.a || c == t.b || c == t.c)
            && (t.a == a || t.a == b || t.a == c)
            && (t.b == a || t.b == b || t.b == c)
            && (t.c == a || t.c == b || t.c == c);
    }
© www.soinside.com 2019 - 2024. All rights reserved.