制作一个独特的Java对象列表

Pet*_*sik 11 java collections list unique

我有一个ArrayList,其中包含具有属性名称和时间的对象.我想根据名称删除重复项,并保留最新时间的记录.所以我在我的对象中使用覆盖equalshashcode名称,并使用这样的代码.

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;
}
Run Code Online (Sandbox Code Playgroud)

但我想知道,有没有更好的解决方案?我正在考虑使用Set,但我无法弄清楚我应该如何制定时间标准.

ior*_*vic 5

仅当新对象比现有对象更新时,才扩展HashMap和覆盖put方法.

或者,您可以创建自己的专用容器,该容器将由a支持HashMap,就像一些Stack支持的实现一样LinkedList


这是一个模拟代码:

import java.util.HashMap;
import java.util.Map;

public class TimeMap<K, V> {

    private Map<K, V> timeMap;

    public TimeMap() {
        this.timeMap = new HashMap<K, V>();
    }

    public void put(K key, V value) {
        if (isNewer(key, value)) {
            this.timeMap.put(key, value);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)


Edm*_*984 5

你对我来说有两种方式,一种需要了解集合是如何工作的,另一种对于对 Java 集合不太了解的人来说更容易理解:

如果你想让它简单,你可以简单地详细阅读 Set 的 Javadoc,http: //docs.oracle.com/javase/6/docs/api/java/util/Set.html#add( E ) . 它明确指出,如果一个元素已经在里面,则不会再添加它。

  • 您仅使用名称来实现您的 equals 和 hashcode
  • 您按时间对项目进行排序,然后将它们添加到集合中。

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


如果其他人不完全了解 java.util.Set 的契约行为,您可能需要扩展 Set 以使您的意图更清晰。但是,由于不应访问 Set 以“在删除后取回元素”,因此您需要使用 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();
    }




}
Run Code Online (Sandbox Code Playgroud)