创建一个唯一的Java对象列表 [英] Make a unique list of objects Java

查看:116
本文介绍了创建一个唯一的Java对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ArrayList,里面填充了属性名称和时间的对象。我想根据名称删除重复项,并保留最新时间的记录。所以我在我的对象中为名称覆盖了等于哈希码,并使用了这样的代码。

I have an ArrayList filled with objects with attributes name and time. I would like to remove duplicates based on the name and keep only records with the latest time. So I have overriden equals and hashcode for name in my object and used code like this.

private List<ChangedRecentlyTO> groupRecords(List<ChangedRecentlyTO> toList) {
    changedRecentlyList.clear(); //static list
    for(ChangedRecentlyTO to : toList) {
        if(!changedRecentlyList.contains(to)) {
            changedRecentlyList.add(to);
        } else {
            if(changedRecentlyList.get(changedRecentlyList.lastIndexOf(to)).getTimeChanged().before(to.getTimeChanged())) {
                changedRecentlyList.remove(to);
                changedRecentlyList.add(to);
            }
        }
    }
    return changedRecentlyList;
}

但我想知道,有更好的解决方案吗?我在考虑使用设置,但我无法弄清楚我应该如何把时间标准放在那里。

But I am wondering, is there a better solution?I was thinking about using Set but I am not able to figure out how should I put there the time criterion.

推荐答案

你需要我两种方法,一种是需要理解套装的工作方式,另一种方式对于那些人来说更容易理解。对Java集合有更深入的理解:

You have to me two ways, one which requires understanding how the set work, and one which is more understandable for people who have littler understanding of Java Collections:

如果你想简化它,你可以简单地阅读Set的Javadoc, http://docs.oracle.com/javase/6/docs/api /java/util/Set.html#add(E )。它清楚地表明,如果一个元素已经在里面,它将不再被添加。

If you want to make it simple, you can simply read in the detail the Javadoc of Set, http://docs.oracle.com/javase/6/docs/api/java/util/Set.html#add(E). It clearly states that if an element is already inside, it won't be added again.


  • 只使用名称实现等号和哈希码

  • 按时间对项目进行排序,然后将它们添加到Set中。

这样,第一次将项目添加到Set时,您将添加具有最新时间的元素。当您添加时其他人,他们将被忽略,因为他们已被包含。

In such a way, the first time you will add the item to Set, you will be adding the elements with the latest times. When you'll add the others, they will be ignored because they are already contained.

如果其他人不完全知道java.util.Set的合同,你可能想要扩展Set以使你的意图更清晰。但是,由于不应该访问Set以在删除后取回元素,因此您需要使用HashMap备份您的集:

If someone else who does not know exactly the contract of java.util.Set behaves, you might want to extend Set to make your intention clearer. However, since a Set is not supposed to be accessed to "get back an element after removal", you will need to back your set with an HashMap:

interface TimeChangeable {
   long getTimeChanged();
}
public class TimeChangeableSet<E extends TimeCheangeable> implements Set<E> {

    private final HashMap<Integer,E> hashMap = new HashMap<Integer,E>();

    @Override
    public boolean add(E e) {
        E existingValue = hashMap.remove(e.hashCode());
        if(existingValue==null){
            hashMap.put(e.hashCode(),e);
            return true;
        }
        else{
            E toAdd = e.getTimeChanged() > existingValue.getTimeChanged() ? e : existingValue;
            boolean newAdded = e.getTimeChanged() > existingValue.getTimeChanged() ? true : false;
            hashMap.put(e.hashCode(),e);
            return newAdded;
        }

    }

    @Override
    public int size() {
        return hashMap.size();
    }

    @Override
    public boolean isEmpty() {
        return hashMap.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return hashMap.containsKey(o.hashCode());
    }

    @Override
    public Iterator<E> iterator() {
        return hashMap.values().iterator();
    }

    @Override
    public Object[] toArray() {
        return hashMap.values().toArray();
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return hashMap.values().toArray(a);
    }

    @Override
    public boolean remove(Object o) {
        return removeAndGet(o)!=null ? true : false;
    }

    public E removeAndGet (Object o) {
        return hashMap.remove(o.hashCode());
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        boolean containsAll = true;
        for(Object object:c){
            E objectInMap = removeAndGet(object);
            if(objectInMap==null || !objectInMap.equals(object))
                containsAll=false;
        }
        return containsAll;
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        boolean  addAll=true;
        for(E e:c){
            if(!add(e)) addAll=false;
        }
        return addAll;

    }

    @Override
    public boolean retainAll(Collection<?> c) {
        boolean setChanged=false;
        for(E e: hashMap.values()){
            if(!c.contains(e)){
                hashMap.remove(e.hashCode());
                setChanged=true;
            }
        }
        return setChanged;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        throw new UnsupportedOperationException("Please do not use type-unsafe methods in 2012");
    }

    @Override
    public void clear() {
        hashMap.clear();
    }




}

这篇关于创建一个唯一的Java对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆