Java 如何从Hashmap中删除重复密钥

Java 如何从Hashmap中删除重复密钥,java,hashmap,duplicates,Java,Hashmap,Duplicates,我有一张名单。列表中有一个列表。 [[-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<

我有一张名单。列表中有一个列表。 [[-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);
在编写了这些代码块之后,我认为我的重复键不能显示,只能显示唯一的键

那么,如何使用哈希映射使此列表唯一


当我使用树映射时,它不会编译并给出som eerror。

映射确实不会保留重复的键,集合也不会保留重复的元素,但您需要理解,重复是根据键/元素等于方法定义的,基于散列的集合依赖于它们的键/元素具有与其equals方法一致的hashCode方法

现在你说

[-1,0,1]和[0,1,-1]它们是相同的

,但不,就列表对平等的定义而言,它们并不相同。列表元素的顺序非常重要,列表需要以反映这一点的方式实现equals。这就是为什么这两个列表可能会在同一个地图中显示为键,也可能会在同一集中显示为元素

那么,如何使用哈希映射使此列表唯一

显然,顺序对于您的目的来说并不重要,因此列表并不是适合您使用的模型。如果不需要容纳重复元素,那么应该考虑使用集合。标准库提供了几种实现,据我所知,其中HashSet可能最适合您的情况。如果您确实需要容纳重复的元素,那么您正在寻找一个多集。标准库不提供实现,但有几个可从第三方获得

当我使用树形图时,它没有编译,并且出现了一些错误

是的,它会的,除非你给它提供了一个比较器来确定元素的相对顺序。TreeMap将重复项识别为根据其自然顺序或比较器指定顺序进行相等比较的键


总的来说,听起来好像不是列表列表,而是一组集合或一组多集合。我不明白你为什么要把地图带进去。

试试这样的方法:

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]相同时,它也可能不是您所期望的。在这种情况下,您必须将每个列表转换为一个映射,该映射将为您提供原始列表中相同整数的计数。

您似乎可以使用集合在线完成此操作。这会给你[-1,0,1],-1,2];同态于[-1,0,1],-1,2,-1]],但不是您想要的结果。下面是一组三个整数的向量,它们与任何置换比较相等,这与您的示例一致。根据,重写equals需要hashCode,并且必须是hashCode,这样a==b->hashCodea==hashCodeb

编辑:以下代码替换了上述三个整数的向量集,它们在放入一个集合时比较相等,这也与您的示例一致

    /** 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);
    }

[-1,0,1]和[0,1,-1]不一样。[-1,0,1]和[-1,0,1]'是相同的。[0,1,-1]`和[0,1,-1]是相同的。列表是有序的,所以在比较列表时,值顺序非常重要。如果要考虑[-1,1,0]和[0,1,-1 ],首先对它们排序,使它们都成为[-1,0,1],然后添加到HASMAP中。此外,还取决于使用什么作为列表的具体类。我们无法从您给定的代码中知道,因为我们只能看到列表界面:但我假设您使用ArrayList,所以我完全同意@Andreas@YavuzTas即使原始列表不是ArrayList,您也可以在排序之前复制到ArrayList,保持原始列表不变。@Andreas在这些情况下,复制当然是一种解决办法,因此我再次同意[0,1,1]是否与[0,0,1]或[0,1]相同?您也可以对列表元素进行排序,以获得一致的顺序,而不是使用集合或多集合,例如,[1,1,0]和[0,1,-1]将变得相同,即[1,0,1]。既然顺序无关紧要,就不必保留原来的顺序。同意,@Andreas。然而,如果你想走这条路,那么你必须小心地做额外的工作,以确保内部列表被排序。这需要与保留列表形式的优点(如果有的话)进行权衡。它正在发挥作用。现在如果我救了tho se列表中的值如何保存它。函数返回类型public List threeSumint[]nums。我应该用这种格式找到答案。最终的结果是Collection类型。您可以将其转换为如下列表:list resList=new ArrayListfinal\u sol.values;。
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);
    }