是否有一个收集器收集到一个订单保存集?


107

Collectors.toSet()不保留订单。我可以改用Lists,但是我想指出结果集合不允许元素重复,而这正是Set接口的目的。


我认为这样的事情不存在。我知道我也需要一个,我必须自己写。
markspace 2014年

SortedSet工作吗?如果没有,那么定制是必经之路。
AntonH 2014年

@AntonH不,我更喜欢O(1)操作胜过O(log n)。
gvlasov 2014年

1
我发布了该代码,它并不是您所需要的,但它可能会让您入门。
markspace 2014年

Answers:


203

您可以使用toCollection并提供所需集合的具体实例。例如,如果要保留插入顺序:

Set<MyClass> set = myStream.collect(Collectors.toCollection(LinkedHashSet::new));

例如:

public class Test {    
    public static final void main(String[] args) {
        List<String> list = Arrays.asList("b", "c", "a");

        Set<String> linkedSet = 
            list.stream().collect(Collectors.toCollection(LinkedHashSet::new));

        Set<String> collectorToSet = 
            list.stream().collect(Collectors.toSet());

        System.out.println(linkedSet); //[b, c, a]
        System.out.println(collectorToSet); //[a, b, c]
    }
}

很好,这正是我所需要的,但我认为ImmutableSet以我的情况来说,番石榴会更好。关于如何使收集者成为收集者的任何想法ImmutableSet?它的实例是使用ImmutableSet.Builder而不是建造的Collection,因此在这种情况下,我无法弄清楚如何SupplierCollectors.toCollection()
gvlasov 2014年

@Susei我将尝试调查。另一种选择是返回一个不可修改的集合。例如:Set<String> linkedSet = list.stream().collect(Collectors.toCollection(LinkedHashSet::new)); linkedSet = Collections.unmodifiableSet(linkedSet);
Alexis C.

@Susei我找到的最接近的:Set<String> set = list.stream().collect( ImmutableSet.Builder<String>::new, ImmutableSet.Builder<String>::add, (builder1, builder2) -> builder1.addAll(builder2.build())).build();不知道通过将结果集包装起来是否是更好的方法Collections.unmodifiableSet
Alexis C.

这里有一个专门的问题,因为这已经偏离主题(以及为伟大的答案更多的代表,当然):stackoverflow.com/questions/27612165/...
gvlasov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.