简体   繁体   English

如何在Java中将数据从双端队列传输到SortedSet

[英]How to transfer data from a Deque to a SortedSet in Java

I get a Deque<Element> deque and I want to transfer all the elements to the other structure: SortedSet<Element> sortedSet . 我得到了Deque<Element> deque ,我想将所有元素都转移到另一个结构: SortedSet<Element> sortedSet

And the sequence of elements in sortedSet is just as same as the sequences in which the elements are popped from deque. 并且sortedSet中的元素顺序与从双端队列弹出元素的顺序相同。

For example: if all the elements are popped from deque in a sequence: E01, E02, ..., E10 . 例如:如果所有元素均按以下顺序从deque弹出: E01, E02, ..., E10 The sequence of elements stored in sortedSet are also E01, E02, ..., E10 . 存储在sortedSet中的元素序列也是E01, E02, ..., E10

I don't know how to override the comparator to let the elements store in such a sequence. 我不知道如何重写比较器以使元素按这样的顺序存储。

Do you know how to do that? 你知道怎么做吗?

OK, this is most bizarre. 好的,这很奇怪。 You expect to have a SortedSet with elements in iteration order... 您希望有一个SortedSet其中的元素按迭代顺序排列...

Here is a bizarre solution to this bizarre problem: 这是解决这个怪异问题的怪异方法:

// final is CRITICAL here
final List<Element> list = new ArrayList<>(deque);
deque.clear();

final Comparator<Element> cmp = new Comparator<>()
{
    @Override
    public int compare(final Element a, final Element b)
    {
        return Integer.compare(list.indexOf(a), list.indexOf(b));
    }
}

return new TreeSet<>(list, cmp);

HOWEVER : this will only work reliably if no two elements in the Deque are .equals() ! 但是 :这只会可靠地工作,如果在没有两个元素Deque.equals() But this is the best you can do given the inherent incompatibility of requirements. 但是鉴于需求固有的不兼容性,这是您可以做的最好的事情。 All in all, I suspect a XY problem.. 总而言之,我怀疑是XY问题。


There is a way to make that reliable but this requires that you use Guava: 一种方法,使这种可靠的,但是这需要你用番石榴:

final Equivalence<Object> eq = Equivalence.identity();

final Function<Element, Equivalence.Wrapper<Object>> f = new Function<>()
{
    @Override
    public Equivalence.Wrapper<Object> apply(final Element input)
    {
        return eq.wrap(input);
    }
}

final List<Element> list = Lists.newArrayList(deque);
deque.clear();

final List<Equivalence.Wrapper<Object>> wrapped = Lists.transform(list, f);

final Comparator<Element> cmp = new Comparator<>()
{
    @Override
    public int compare(final Element a, final Element b)
    {
        return Integer.compare(wrapped.indexOf(f(a)),
            wrapped.indexOf(f(b)));
    }
};

return new TreeSet<>(list, cmp);

As fge already stated, you need a LinkedHashSet , a collection which keeps the insertion order: 如fge所述,您需要一个LinkedHashSet ,它是一个保留插入顺序的集合:

Set<Element> convertToSet(Deque<Element> dq)
{
LinkedHashSet<Element> lhs = new LinkedHashSet<Element>():
while(!dq.isEmpty())
{
lhs.add(dq.peekFirst());
}

return lhs;
}

Jane, I wrote a simple code: 简,我写了一个简单的代码:

public static void main(String[] args) {
        SortedSet<Integer> set = new TreeSet<Integer>(new Comparator<Integer>() {
            @Override
            public int compare(Integer i1, Integer i2) {
                return 1;
            }
        });
        Deque<Integer> deq = new LinkedList<Integer>();
        deq.add(5);
        deq.add(1);
        deq.add(3);
        set.addAll(deq);
        System.out.println(deq); // 5,1,3
    }

The comparator should always return 1 this way the order stays the same, if this was your question. 如果这是您的问题,比较器应始终以这种方式return 1 ,以便顺序保持不变。 Warning: this solution violates the Comparable and Set contract. 警告:此解决方案违反了Comparable and Set合同。 Use it with caution. 请谨慎使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM