当前位置: 首页 > 知识库问答 >
问题:

如何从散列表中移除重复的键

夏知
2023-03-14

我有一份名单。列表中有列表。< code>[[-1,0,1],[-1,2,-1],[0,1,-1]],此列表的名称表示结果。结果列表包含作为列表重复元素。< code>[-1,0,1]和< code>[0,1,-1]是一样的。我想列一个没有重复的清单。所以列表结果变成< code>[[-1,0,1],[-1,2,-1]]或< code>[[-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}

在编写这些代码块之后,我认为我的重复键不能显示,只显示唯一的键。

那么,如何使用哈希映射使列表唯一?不懂

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

共有3个答案

楚宏胜
2023-03-14

似乎您可以使用Set在线执行此操作

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

高展
2023-03-14

试着这样做:

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

胡野
2023-03-14

的确,映射不保留重复键,集合不保留重复元素,但您需要理解“重复”是根据键/元素<code>equals()

现在你说

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

,但不,就<code>List<code>s的相等定义而言,它们并不相同。列表元素的顺序很重要,列表需要以反映这一点的方式实现equals()。这就是为什么这两个列表可能显示为同一映射中的键,也可能显示为相同集合中的元素。

那么,如何使用哈希映射使这个列表唯一呢?

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

当我使用树状图时,它没有编译并给出了一些错误。

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

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

 类似资料:
  • 问题内容: 我想从列表中删除重复项,但我无法正常工作: 问题答案: 如果该代码不起作用,则可能是你未在该类上正确实现。 大概有一些钥匙(我们称之为)可以唯一地标识一个客户。例如 的适当定义equals(Object)如下所示: 为了完整起见,你还应该实现hashCode两个Customer相等的对象将返回相同的哈希值。hashCode上述定义的匹配项为equals: 还值得注意的是,如果列表很大,

  • 问题内容: 我想从列表列表中删除所有重复列表。 所以我有一个这样的清单清单。 我希望有: 我不知道该怎么办。 谢谢 问题答案: 您可以使用一组: 或者,如果您更喜欢列表推导/生成器: 最后,如果顺序很重要,则可以始终对b进行排序:

  • 问题内容: 我将如何使用python检查列表并删除所有重复项?我不需要指定重复项是什么- 我希望代码找出是否存在重复项,如果有则将其删除,每个重复项仅保留一个实例。如果列表中有多个重复项,它也必须起作用。 例如,在下面的代码中,列表lseparatedOrbList有12个项目-一项被重复六次,一项被重复五次,并且只有一个实例。我希望它更改列表,因此只有三项-每一项,并且它们之前出现的顺序相同。我

  • 问题内容: 我在Python中有一个列表列表: 我想从中删除重复的元素。如果这是正常列表,而不是我可以使用的列表set。但不幸的是,该列表不可散列,因此无法建立一组列表。只有元组。因此,我可以将所有列表转换为元组,然后使用set并返回列表。但这不是很快。 如何以最有效的方式做到这一点? 上面的结果应为: 我不在乎保留订单。 注意:这个问题很相似,但不是我所需要的。搜索了SO,但没有找到确切的重复项

  • 实际上,我知道如何减少重复的,或者将分配给,但我有一个不同的问题。如何在Java8中使用stream或者可能是来解决以下智能方式的问题? 假设列表中有一个对象

  • 问题内容: 我有一张像这样的桌子: ID为 ,自创建表以来一直在使用。 我想要做的是删除除一个记录以外的所有记录,其中所有其他列都相同。 问题答案: 当然,您必须在所有三个位置将col1,col2扩展到所有列。 编辑:我只是从保留的脚本中重新进行了测试,然后重新测试,它在MySQL中执行。