Как снять список объектов? - PullRequest
4 голосов
/ 03 ноября 2010

A 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;

}

Ответы [ 5 ]

6 голосов
/ 03 ноября 2010

Сохраните его временно в HashMap<String,Rec>.

Создайте HashMap<String,Rec>.Переберите все ваши Rec объекты.Для каждого из них, если tag уже существует в качестве ключа в HashMap, сравните их и решите, какой из них оставить.Если нет, введите его.

Когда вы закончите, метод HashMap.values() выдаст вам все ваши уникальные Rec объекты.

5 голосов
/ 03 ноября 2010

Попробуйте это:

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 к нашему результату и добавляем тег в набор.

1 голос
/ 03 ноября 2010

Это становится проще, если 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;
 }
0 голосов
/ 18 октября 2013

Если вас не интересует перемешивание данных (т. Е. У вас есть небольшой список небольших объектов), вы можете сделать это:

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 требуется согласованный и действительный оператор равенства. Поэтому, если у вас есть собственный объект, убедитесь, что он позаботился.

0 голосов
/ 03 ноября 2010

Я бы сделал это с коллекциями Google. Вы можете использовать функцию фильтра с предикатом, который запоминает предыдущие теги, и отфильтровывает записи с тегами, которые были там раньше. Примерно так:

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, но, конечно, вы можете изменить его, если это важно.

...