Paul Taylor
Paul Taylor

Reputation: 13110

Creating subset of a Set in Java

I have a LinkedHashSet, i.e an ordered set. I'm trying to find a function to just return a subset of the set, i.e the first 20 elements of the set. I know I can do it by creating a new set and then populating using an iteration of the first set but I was hoping for something more succinct.

Also took a look at Google's Guava libraries, but couldn't see what I wanted.

Upvotes: 35

Views: 67021

Answers (6)

Lii
Lii

Reputation: 12122

A solution using streams and collectors:

Set<Integer> subSet = set.stream()
    // .skip(10) // Use this to get elements later in the stream
    .limit(20)
    .collect(toCollection(LinkedHashSet::new));
    // You could also collect to something else 
    // with another collector like this: 
    // .collect(toList());

This assumes the following import:

import static java.util.stream.Collectors.toCollection;

Upvotes: 24

thiagoh
thiagoh

Reputation: 7388

In Java 8 you can do

mySet.stream()
   .skip(start) // the offset
   .limit(count) // how many items you want
   .collect(Collectors.toSet());

Upvotes: 28

user1079877
user1079877

Reputation: 9368

Simple helper method (You can use it for Set or any other collection):

public static <T> List<T> listOf(final Collection<T> set, final int limit) {
    final List<T> list = new ArrayList<>(limit);

    final Iterator<T> i = set.iterator();
    for (int j = 0; j < limit && i.hasNext(); j++) {
        list.add(i.next());
    }

    return list;
}

Upvotes: 2

Reimeus
Reimeus

Reputation: 159784

You could do this:

Set<Integer> set = new LinkedHashSet<>();
for (int i = 0; i < 50; i++) {
   set.add(i);
}

List<Integer> list = new ArrayList<>(set);
Set<Integer> subSet = new LinkedHashSet<>(list.subList(0, 20));

Upvotes: 18

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340763

In Guava:

Set<Integer> subset = ImmutableSet.copyOf(Iterables.limit(set, 20));

Note that Iterables.limit() is evaluated lazily, so only one extra collection is created.

Upvotes: 40

Alex
Alex

Reputation: 25613

You can either use at first a SortedSet as the subSet method exists on it.

You can also add the content of your set to a List and use the subList method on it. But it depends on the amount of data stored in your Set as you would not want to duplicate an enormous volume of data.

Otherwise you should stay with the iteration over the Set as it will be more efficient.

Upvotes: 5

Related Questions