2015-12-15 88 views
4

对于企业原因我不能覆盖hashCode,我必须使用Java 6(但我可以用番石榴)删除重复没有覆盖的hashCode()

请告诉我最好成绩/简单/快捷/最有效的/ [插入不确定的形容词相当于最好的]机制从Java集合中删除重复的bean?

重复由返回相同值的getter子集定义,例如,

pojoA.getVal() == pojoB.getVal() && pojoA.getOtherVal() == pojoB.getOtherVal() 
+0

我对,目前的hashCode没有反映任何关于getter返回值的等号?它是如何实现的? – sphinks

+0

@sphinks是hashcode是事实上的对象 – NimChimpsky

+0

写一个比较器? –

回答

10

裹的利益为自己的类的对象,并覆盖其hashCode/equals要注意属性的特定子集。制作一个包装器的散列集合,然后从集合中收集对象以获得无重复的子集。

下面是一个例子:

class ActualData { 
    public String getAttr1(); 
    public String getAttr2(); 
    public String getAttr3(); 
    public String getAttr4(); 
} 

比方说,你要注意的属性1,2,4,然后你就可以像这样的包装:

class Wrapper { 
    private final ActualData data; 
    public ActualData getData() { 
     return data; 
    } 
    private final int hash; 
    public Wrapper(ActualData data) { 
     this.data = data; 
     this.has = ... // Compute hash based on data's attr1, 2, and 4 
    } 
    @Override 
    public int hashCode() { 
     return hashCode; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (!(obj instanceof Wrapper)) return false; 
     Wrapper other = (Wrapper)obj; 
     return data.getAttr1().equals(other.getAttr1()) 
      && data.getAttr2().equals(other.getAttr2()) 
      && data.getAttr4().equals(other.getAttr4()); 
    } 
} 

现在你可以做一个HashSet<Wrapper>

Set<Wrapper> set = new HashSet<>(); 
for (ActualData item : listWithDuplicates) { 
    if (!set.add(new Wrapper(item))) { 
     System.out.println("Item "+item+" was a duplicate"); 
    } 
} 
3

你可以使用一个new TreeSet<Pojo> (comparator)有比较IM以满足你的条件(假设整数在这里,但根据需要替换 - 对于不可比较的对象,你需要找到一个返回一些整数的黑客)。

if (pojoA.getVal() != pojoB.getVal()) 
    return Integer.compare(pojoA.getVal(), pojoB.getVal()); 
if (pojoA.getOtherVal() != pojoB.getOtherVal()) 
    return Integer.compare(pojoA.getOtherVal(), pojoB.getOtherVal()); 
return 0; 

虽然不像纯HashSet那样高效,但@dasblikenlight的建议可能会更好。