Rec
对象有一个名为tag
的成员变量String
。
如果我有List
个Rec
,我怎么能根据tag
成员变量来删除列表?
我只需要确保List
只包含一个Rec
,每个tag
值。
如下所示,但我不确定什么是保持跟踪计数等的最佳算法:
private List<Rec> deDupe(List<Rec> recs) {
for(Rec rec : recs) {
// How to check whether rec.tag exists in another Rec in this List
// and delete any duplicates from the List before returning it to
// the calling method?
}
return recs;
}
答案 0 :(得分:6)
暂时将其存储在HashMap<String,Rec>
。
创建HashMap<String,Rec>
。遍历所有Rec
个对象。对于每一个,如果tag
已作为HashMap
中的密钥存在,则将两者进行比较并确定要保留哪一个。如果没有,那就把它放进去。
完成后,HashMap.values()
方法会为您提供所有唯一的Rec
个对象。
答案 1 :(得分:5)
试试这个:
private List<Rec> deDupe(List<Rec> recs) {
Set<String> tags = new HashSet<String>();
List<Rec> result = new ArrayList<Rec>();
for(Rec rec : recs) {
if(!tags.contains(rec.tags) {
result.add(rec);
tags.add(rec.tag);
}
}
return result;
}
这会针对Rec
个标记检查每个Set
。如果集合已包含标记,则它是重复的,我们会跳过它。否则,我们会将Rec
添加到结果中,然后将标记添加到集合中。
答案 2 :(得分:1)
如果Rec
.equals
基于其tag
值,则会变得更容易。然后你可以这样写:
private List<Rec> deDupe( List<Rec> recs )
{
List<Rec> retList = new ArrayList<Rec>( recs.size() );
for ( Rec rec : recs )
{
if (!retList.contains(rec))
{
retList.add(rec);
}
}
return retList;
}
答案 3 :(得分:0)
我会用谷歌收藏品做到这一点。您可以使用过滤器函数,使用记住以前标记的谓词,并过滤出之前已存在的标记的Rec。 像这样:
private Iterable<Rec> deDupe(List<Rec> recs)
{
Predicate<Rec> filterDuplicatesByTagPredicate = new FilterDuplicatesByTagPredicate();
return Iterables.filter(recs, filterDuplicatesByTagPredicate);
}
private static class FilterDuplicatesByTagPredicate implements Predicate<Rec>
{
private Set<String> existingTags = Sets.newHashSet();
@Override
public boolean apply(Rec input)
{
String tag = input.getTag();
return existingTags.add(tag);
}
}
我稍微改变了返回Iterable而不是List的方法,但是如果这很重要的话你可以改变它。
答案 4 :(得分:0)
如果您不关心随机数据的混乱(即您有一小部分小对象),您可以这样做:
private List<T> deDupe(List<T> thisListHasDupes){
Set<T> tempSet = new HashSet<T>();
for(T t:thisListHasDupes){
tempSet.add(t);
}
List<T> deDupedList = new ArrayList<T>();
deDupedList.addAll(tempSet);
return deDupedList;
}
请记住,Set的实际内容需要一个一致且有效的equals运算符。因此,如果你有一个自定义对象,请确保已经处理好。