Java TreeSet - 不要移除重复项

14

TreeSet会移除掉具有相同比较器值的不同项。我不想让它们被移除。 有没有什么方法可以控制这个行为?或者使用另一个容器类?

补充说明: 好的,看来我不能使用Set。 我需要插入排序功能,出于性能考虑。 List能够实现这个吗?感谢所有人。


6
使用一个不返回0的比较器。 - Peter Lawrey
1
@Peter Lawrey 除了某种意义上相同的对象之外。 - Tom Hawtin - tackline
@Tom Hawtin,同意,当对象是==时,您可以返回0,否则比较System.identityHashCode()或仅为具有相同内容但不是同一对象的对象返回任意1 - Peter Lawrey
@Petery Lawrey System.identityHashCode 不是唯一的。因此,您仍需要一个决胜者(可能使用 WeakReference)。 - Tom Hawtin - tackline
5个回答

11

根据定义,集合中不能有重复项。

因此,您需要使用列表、数组或类似的数据结构。


6
即便是集合,由于对象不同还是会有些令人困惑。例如,对于一个包含不同对象 E 的 Set,如果基于使用的 Comparator 进行转换为 TreeSet,将会删除一些对象。在两种情况下都是集合,但存储的元素集合是不同的。在我看来,这一点在文档中没有很好地说明。
一个简单的解决方案是,如果可以更改 Comparator,请勿返回 0。例如,可以采用以下方式而不是原来的方式:
public int compare(Integer o1, Integer o2) {
    return o1.compareTo(o2);
}

使用:

public int compare(Integer o1, Integer o2) {
    return o1 < o2 ? -1: 1;
}

4
一个 Set 的主要目的是允许重复。 如果你需要重复元素,那么你不需要使用 Set,或者你需要一个不同的 Comparator

3

来自Set的Javadoc的引用:

一个不包含重复元素的集合

可以使用List的任何派生类。


谢谢。但是,有没有支持在插入项目时进行排序的列表派生类? - pengguang001
你可以通过 Collections.sort(...) 和你的原始比较器来对列表进行排序。或者,你可以使用两个集合,一个包含元素,另一个包含它们的出现次数,即一种多重集合。 - Andrey Adamovich
尝试从这里使用PriorityQueue http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html 或者从这里使用MinMaxPriorityQueue http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/MinMaxPriorityQueue.html - stolen_leaves

2
如果您想要一个 SortedList,可以使用列表,并在每次插入后手动调用 Collections.sort()。
或者,您可以包装例如 ArrayList,以确保自动进行排序调用:
    class SortedArrayList extends ArrayList<String> {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public void add(int index, String element) {
        super.add(index, element);
        Collections.sort(this);
    }

    @Override
    public boolean add(String element) {
        boolean returnValue = super.add(element);
        Collections.sort(this);
        return returnValue;
    }

    @Override
    public boolean addAll(Collection<? extends String> c) {
        boolean returnValue = super.addAll(c);
        Collections.sort(this);
        return returnValue;
    }

    @Override
    public boolean addAll(int index, Collection<? extends String> c) {
        boolean returnValue = super.addAll(index, c);
        Collections.sort(this);
        return returnValue;
    }

    @Override
    public String set(int index, String element) {
        String returnValue = super.set(index, element);
        Collections.sort(this);
        return returnValue;
    }
}

我希望我已经包含了所有需要排序的功能。(不需要覆盖删除)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接