繁体   English   中英

删除重复项而不覆盖哈希方法

[英]Removing duplicates without overriding hash method

我有一个List,其中包含一个对象列表,我想从这个列表中删除所有在两个属性中具有相同值的元素。 我曾做过这样的事情:

List<Class1> myList;
....
Set<Class1> mySet = new HashSet<Class1>();
mySet.addAll(myList);

并重写Class1中的哈希方法,因此它返回一个仅取决于我想要考虑的属性的数字。

问题是我需要在应用程序的另一部分进行不同的过滤,所以我不能以这种方式覆盖哈希方法(我需要两种不同的哈希方法)。

在不重写哈希方法的情况下进行此过滤的最有效方法是什么?

谢谢

Class1重写hashCodeequals (只是为了做到这一点)是有问题的。 你最终会对你的班级有一个不自然的平等定义,这可能会成为班级其他当前和未来用途的其他用途。

查看Comparator接口并编写Comparator<Class1>实现,以根据您的标准比较Class1的实例; 例如,基于这两个属性。 然后使用TreeSet(Comparator)构造函数实例化TreeSet<Class >`以进行重复检测。

编辑

将这种方法与@Tom Hawtin的方法进行比较:

  • 这两种方法总体上使用大致相当的空间。 treeset的内部节点大致平衡了hashset的数组和支持自定义equals / hash方法的包装器。

  • 对于树集方法,包装器+哈希集方法在时间上是O(N) (假设是良好的哈希)而不是O(NlogN) 因此,如果输入列表可能很大,那就是要走的路。

  • 树形集方法在需要编写的代码行方面获胜。

让你的Class1实现Comparable 然后在您的示例中使用TreeSet (即使用addAll方法)。

作为Roman所说的替代方法,您可以查看有关使用Predicates进行过滤的SO问题 无论如何,如果你使用谷歌收藏,这可能是一个不错的选择。

我建议为Class1的部分概念引入一个类,你想在这个上下文中考虑重要。 然后使用HashSetHashMap

有时程序员会尝试使用语言的所有优秀功能而使事情过于复杂,而这个问题的答案就是一个例子。 覆盖课堂上的任何内容都是过度的。 你需要的是这个:

class MyClass {
  Object attr1;
  Object attr2;
}

List<Class1> list;
Set<Class1> set=....
Set<MyClass> tempset = new HashSet<MyClass>;

for (Class1 c:list) {
  MyClass myc = new MyClass();
  myc.attr1 = c.attr1;
  myc.attr2 = c.attr2;

  if (!tempset.contains(myc)) {
    tempset.add(myc);
    set.add(c);
  }
}

随意修复轻微的irregulairites。 根据属性的相等性意味着一些问题(如果属性是原始的,则会有明显的变化)。 有时我们需要编写代码,而不仅仅是使用内置库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM