One liner for getting a sublist from a Set

12,352

Solution 1

With Guava:

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

(Also, this won't actually iterate over the whole set, in contrast to most of these other solutions -- it'll actually only iterate through the first count elements and then stop.)

Solution 2

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

But please note: the code (even your original code) is a little bit smelly, since iteration order of sets depends on the actual set implementation in question (it's totally undefined in HashSet and the key order for TreeSets). So, it is actually an open question, which elements make it into the final sublist.

Solution 3

This should do it:

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

But ensure, that count isn't larger than the size of set.

Solution 4

You could use a TreeSet and use it's subSet method:

Returns a view of the portion of this set whose elements range from fromElement to toElement. If fromElement and toElement are equal, the returned set is empty unless fromExclusive and toExclusive are both true. The returned set is backed by this set, so changes in the returned set are reflected in this set, and vice-versa. The returned set supports all optional set operations that this set supports.

EXAMPLE USING 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);
}

OUTPUT:

Before SubSet:
1
2
3
4
5

After SubSet:
3
4
5

Alternatively, If you do not know the elements and want to return the elements between two points you can use an ArrayList constructed with the Set and use the subList method.

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

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

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

Solution 5

What about this

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));

This would sublist between 1 and 2

Share:
12,352
yegor256
Author by

yegor256

Lab director at Huawei, co-founder at Zerocracy, blogger at yegor256.com, author of Elegant Objects book; architect of Zold.

Updated on June 27, 2022

Comments

  • yegor256
    yegor256 almost 2 years

    Is there a one-liner (maybe from Guava or Apache Collections) that gets a sublist from a set. Internally it should do something like this:

    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;
    }
    

    Obviously, if there are not enough elements it has to return as many as possible.