一个用于从Set中获取子列表的衬垫

时间:2012-09-19 08:25:28

标签: java guava apache-commons-collection

是否有一个单行(可能来自Guava或Apache Collections)从集合中获取子列表。在内部它应该做这样的事情:

public <T> List<T> sublist(Set<T> set, int count) {
  Iterator<T> iterator = set.iterator();
  List<T> sublist = new LinkedList<T>();
  int pos = 0;
  while (iterator.hasNext() && pos++ < count) {
    sublist.add(iterator.next());
  }
  return sublist;
}

显然,如果没有足够的元素,它必须尽可能多地返回。

6 个答案:

答案 0 :(得分:18)

使用番石榴:

return FluentIterable.from(set) 
  .limit(count)
  .toImmutableList();

(另外,与大多数其他解决方案相比,这实际上不会迭代整个集合 - 它实际上只会迭代第一个count元素 然后停止。)

答案 1 :(得分:13)

(new LinkedList<Object>(mySet)).sublist(0, Math.min(count, mySet.size()))

但是请注意:代码(甚至是原始代码)有点臭,因为集合的迭代顺序取决于所讨论的实际集合实现(HashSet中的完全未定义以及{的密钥顺序{1}} S)。因此,它实际上是一个悬而未决的问题,哪些元素成为最终的子列表。

答案 2 :(得分:7)

这应该这样做:

return (new LinkedList<T>(set)).subList(0, count);

但请确保count不大于set的大小。

答案 3 :(得分:5)

您可以使用TreeSet并使用subSet方法:

  

返回此set的部分视图,其元素范围从fromElement到toElement。如果fromElement和toElement相等,则返回的集合为空,除非fromExclusive和toEx​​clusive都为真。返回的集由此集支持,因此返回集中的更改将反映在此集中,反之亦然。返回的集支持此集支持的所有可选集操作。

使用INTEGER的示例:

TreeSet<Integer> t = new TreeSet<Integer>();
t.add(1);
t.add(2);
t.add(3);
t.add(4);
t.add(5);

System.out.println("Before SubSet:");

for(Integer s : t){
    System.out.println(s);
}

System.out.println("\nAfter SubSet:");


for(Integer s : t.subSet(2,false,5,true)){
    System.out.println(s);
}

<强>输出:

Before SubSet:
1
2
3
4
5

After SubSet:
3
4
5

或者,如果您不知道元素并希望在两点之间返回元素,则可以使用由Set构造的ArrayList并使用subList方法。

System.out.println("\nAfter SubSet:");

t = new TreeSet(new ArrayList(t).subList(2, 5));

for(Integer s : t){
    System.out.println(s);
}

答案 4 :(得分:2)

这个怎么样?

Set<String> s = new HashSet<String>();
// add at least two items to the set 
Set<String> subSet = new HashSet(new ArrayList<String>(s).subList(1, 2));

这将在1到2之间进行子列表

答案 5 :(得分:0)

不事先创建Set的副本,你可以(使用番石榴):

Lists.newLinkedList(Iterables.getFirst(Iterables.partition(mySet, count), ImmutableList.of()))

这是一个真实的LinkedList,仅包含(最多)第一个count元素,而不是更大列表中的视图。