Java Set 和 List 接口的组合

发布于 2024-12-09 22:29:00 字数 427 浏览 1 评论 0原文

我有一个数据结构,目前我正在使用 ArrayList。我意识到在这个结构中我不希望出现任何重复项。我的第一个想法是使用某种形式的集合,但是顺序也很重要。经过一番谷歌搜索并搜索 Collections 文档后,我发现 LinkedHashSet 几乎可以完成这项工作。不幸的是,保留顺序的主要原因之一是因为我使用 ArrayList 的 get(int index) 方法进行随机访问,并且我看不到任何解决此问题的方法。

更简洁 - 我需要一个保留顺序并允许随机访问的集合。到目前为止,我所见过的类都没有提供此功能。有谁知道提供此服务的课程,还是我必须自己制作?如果是后一种情况,在创建人们意识到的这种结构时是否存在任何陷阱?

(或者,一种快速简单的方法来检查和删除 ArrayList 或类似结构中的重复项就足够了)

编辑:为了清楚起见,重要的是元素添加到列表的顺序,而不是它们如何相互比较

I have a data structure, for which I am currently using an ArrayList. I realised that in this structure I do not want any duplicates to be present. My first thought was to use some form of set, however the order is also important. After a bit of googling and searching the Collections docs I found LinkedHashSet which almost does the job. Unfortunately, one of the primary reasons for preserving order is because I am using the get(int index) method of the ArrayList for random access, and I can't see any way around this.

More concisely - I need a set that preserves order and allows random access. None of the classes I have so far looked at provide this functionality. Does anyone know of a class that offers this, or will I have to make it myself? If it is the latter case are there any pitfalls when creating such a structure that people are aware of?

(Alternatively, a quick and easy way of checking for and removing duplicates form an ArrayList or similar structure would suffice)

EDIT: for clarity, it is the order that elements are added to the list that is important, not how they compare to one another

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

合久必婚 2024-12-16 22:29:00

SetUniqueList 来自 commons-collections:(

List<Foo> uniqueList = SetUniqueList.decorate(new ArrayList<Foo>());

不幸的是,commons-collections 仍然不支持泛型,所以你必须在此处抑制警告)

SetUniqueList from commons-collections:

List<Foo> uniqueList = SetUniqueList.decorate(new ArrayList<Foo>());

(unfortunately, commons-collections still doesn't support generics, so you'll have to suppress a warning here)

强辩 2024-12-16 22:29:00

我只是扩展ArrayList

public class SetList<E> extends ArrayList<E> {

    @Override
    public boolean add(E e) {
        return contains(e) ? false : super.add(e);
    }

    @Override
    public void add(int index, E e) {
        if (!contains(e)) {
            super.add(index, e);
        }
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size(), c);
    }

    @Override
    public boolean addAll(int index, Collection<? extends E> c) {
        Collection<E> copy = new ArrayList<E>(c);
        copy.removeAll(this);
        return super.addAll(index, copy);
    }

}

请注意,add()方法符合合同

确保此集合包含指定的元素(可选操作)。如果此集合因调用而发生更改,则返回 true。 (如果此集合不允许重复且已包含指定元素,则返回 false。)

I'd just extend ArrayList.

public class SetList<E> extends ArrayList<E> {

    @Override
    public boolean add(E e) {
        return contains(e) ? false : super.add(e);
    }

    @Override
    public void add(int index, E e) {
        if (!contains(e)) {
            super.add(index, e);
        }
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size(), c);
    }

    @Override
    public boolean addAll(int index, Collection<? extends E> c) {
        Collection<E> copy = new ArrayList<E>(c);
        copy.removeAll(this);
        return super.addAll(index, copy);
    }

}

Note that the add() method conforms the contract:

Ensures that this collection contains the specified element (optional operation). Returns true if this collection changed as a result of the call. (Returns false if this collection does not permit duplicates and already contains the specified element.)

丶视觉 2024-12-16 22:29:00

如何创建 AbstractList 的子类,将 ArrayList 作为其后备存储,重写大多数方法以将它们委托给后备存储,并重写 add() 以拒绝重复项?

class NoDupesList<E> extends AbstractList<E> {
    private final List<E> backing;

    NoDupesList() {
        backing = new ArrayList<E>();
    }

    public E get(int index) {
        return backing.get(index);
    }

    // ...

    public boolean contains(Object o) {
        return backing.contains(o);
    }

    public boolean add(E e) {
        if (contains(e))
            throw new IllegalArgumentException("duplicates disallowed: " + e):

        return backing.add(e);
    }
 }

What about creating a subclass of AbstractList that keeps an ArrayList as its backing store, overrides most methods to delegate them to the backing store, and overrides add() to reject duplicates?

class NoDupesList<E> extends AbstractList<E> {
    private final List<E> backing;

    NoDupesList() {
        backing = new ArrayList<E>();
    }

    public E get(int index) {
        return backing.get(index);
    }

    // ...

    public boolean contains(Object o) {
        return backing.contains(o);
    }

    public boolean add(E e) {
        if (contains(e))
            throw new IllegalArgumentException("duplicates disallowed: " + e):

        return backing.add(e);
    }
 }
メ斷腸人バ 2024-12-16 22:29:00

您可以一起使用 ArrayList 和 HashMap:

import java.util.*;

class AS<T>{

    private HashMap<T, Integer> m = new HashMap<T, Integer>();
    private ArrayList<T> a = new ArrayList<T>();

    public void add(T object){
        if (!m.containsKey(object)){
            m.put(object, a.size());
            a.add(object);
        }
    }
    public void remove(T object){
        Integer i = m.get(object);
        if (i!=null){
            a.remove(i.intValue());
            m.remove(object);
        }
    }
    public void remove(int index){
        m.remove(a.get(index));
        a.remove(index);
    }
    public T get(int index){
        return a.get(index);
    }

    public String toString(){return a.toString();}
}

You can use an ArrayList and a HashMap together:

import java.util.*;

class AS<T>{

    private HashMap<T, Integer> m = new HashMap<T, Integer>();
    private ArrayList<T> a = new ArrayList<T>();

    public void add(T object){
        if (!m.containsKey(object)){
            m.put(object, a.size());
            a.add(object);
        }
    }
    public void remove(T object){
        Integer i = m.get(object);
        if (i!=null){
            a.remove(i.intValue());
            m.remove(object);
        }
    }
    public void remove(int index){
        m.remove(a.get(index));
        a.remove(index);
    }
    public T get(int index){
        return a.get(index);
    }

    public String toString(){return a.toString();}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文