我有一个基本的类'HistoryItem',如下所示:
public class HistoryItem
private Date startDate;
private Date endDate;
private Info info;
private String details;
@Override
public int hashCode() {
int hash = (startDate == null ? 0 : startDate.hashCode());
hash = hash * 31 + (endDate == null ? 0 : endDate.hashCode());
return hash;
}
}
我目前正在使用HashSet从startDate&上的ArrayList中删除重复项。 endDate字段,它正常工作。
但是我还需要删除不同字段的重复项(信息和详细信息)。
我的问题是这个 有没有办法指定HashSet将使用的不同方法来代替hashCode()? 像这样:
public int hashCode_2() {
int hash = (info == null ? 0 : info.hashCode());
hash = hash * 31 + (details == null ? 0 : details.hashCode());
return hash;
}
Set<HistoryItem> removeDups = new HashSet<HistoryItem>();
removeDups.setHashMethod(hashCode_2);
或者我还有另一种方法吗?
答案 0 :(得分:2)
您可以使用不同的HistoryItem
实现围绕GetHashCode
创建一个包装类,然后围绕原始集合中的每个项目创建一个包装器的HashSet。
答案 1 :(得分:1)
一些事情。首先,如果要覆盖hashCode(),必须覆盖equals()。这个很重要。其次,如果您正在处理不同的字段,那么您应该为每个字段使用不同的HashSet。所以你可以这样迭代地图:
HashSet<String> info;
HashSet<String> details;
for (HistoryItem h:map){
if(info.contains(h.getInfo()){
// this is a dup
}
if (details.contains(h.getDetails()){
// this is a dup
}
info.add(h.getInfo());
details.add(h.getDetails());
}
答案 2 :(得分:1)
我最终使用了GNU Trove。
需要更改代码。
实施TObjectHashingStrategy的新类(包含HashCode
和Equals
方法)。
public class HistoryItemDuplicateInfo
implements TObjectHashingStrategy<HistoryItem> {
@Override
public int computeHashCode(HistoryItem obj) {
...
}
@Override
public boolean equals(HistoryItem arg0, HistoryItem arg1) {
...
}
}
然后使用具有指定策略的THashSet对象删除重复项。
THashSet<HistoryItem> hs = new THashSet<HistoryItem>(new HistoryItemDuplicateInfo());
希望将来可以帮助某人。
答案 3 :(得分:0)
您可以使用带有自定义java.util.TreeSet
的{{1}}删除重复项,并将Comparator
和Info
考虑在内。
答案 4 :(得分:0)
我会建议你;
答案 5 :(得分:0)
HashSet
被硬编码以使用hashCode()
和equals()
。您可以实现自己的HashSet
类,可能是通过无情地复制Java自己的源代码,但这很简单,与任何体面的软件开发规则相矛盾,并且对于Java的源代码许可证可能是非法的(这取决于实际的JDK,例如Sun / Oracle的JDK与OpenJDK)。
但是,您可以使用TreeSet
执行操作。 TreeSet
通常使用元素的compareTo()
方法,不 hashCode()
或equals()
。此外,可以使用自定义TreeSet
实例构建Comparator
实例,然后调用该实例进行比较,使您可以自由拥有自己的规则。 compareTo()
方法(或Comparator.compare()
方法)必须实现订单,这可能比简单的hashCode()
更加棘手 - 而且 - {{1}但是,这通常也不难。 equals()
有时被称为慢于TreeSet
,但实际差异很小,实际上能够以任何方式注意到这种差异需要非常具体的情况。
从概念上讲,HashSet
可能存在Comparator
的哈希值:具有HashSet
和HasherAndEqualizer
方法的接口int hashCode(Object obj)
。 Sun认为不适合包含这样的界面,我不知道为什么。可能他们认为这不会有用。您在另一个答案中引用的“GNU Trove”库提供了这样的界面。
或者,您始终可以使用包装器。您可以存储boolean equals(Object obj1, Object obj2)
个实例,每个实例都链接到实际HistoryItem
并提供HistoryItemWrapper
/ HistoryItem
方法,而不是在您的辅助集中存储hashCode()
个实例需要那套。