13

If I have a Set that I know contains a single element, what's the best way to extract it? The best I can come up with is this, but it doesn't feel very groovy:

set = [1] as Set
e = set.toList()[0]
assert e == 1

If I'm dealing with a list, I've got lots of nice ways to get the element, none of which seem to work with Sets:

def list = [1]
e = list[0]
(e) = list
e = list.head()
ataylor
  • 64,891
  • 24
  • 161
  • 189
  • 2
    The 'groovy feel' is a very subjective thing. If I were writing the code, I will be happy with `set.toList().first()`. :-) – Binil Thomas Mar 04 '11 at 20:09

4 Answers4

20

One other possibility (which will work in Java or Groovy):

set.iterator().next()
Dónal
  • 185,044
  • 174
  • 569
  • 824
16

A few alternatives, none of them very pretty:

set.iterator()[0]
set.find { true }
set.collect { it }[0]

Finally, if it's guaranteed that that set has only one item:

def e
set.each { e = it }

The underlying issue, of course, is that Java Sets provide no defined order (as mentioned in the Javadoc), and hence no ability to get the nth element (discussed in this question and this one). Hence, any solution is always to somehow convert the set to a list.

My guess is that either of the first two options involve the least data-copying, as they needn't construct a complete list of the set, but for a one-element set, that should hardly be a concern.

Community
  • 1
  • 1
ig0774
  • 39,669
  • 3
  • 55
  • 57
  • 2
    There is [Collection.find()](http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Collection.html#find()) method since 1.8.1, which is a bit shorter to use than `set.find{ true }` – Oleg Estekhin Apr 22 '15 at 13:05
1

Since Java 8, here is another solution that will work for both Java and Groovy:

set.stream().findFirst().get()
noelob
  • 460
  • 5
  • 14
1

Even when this question is quite old, I am sharing my just a bit prettier solution.

(set as List).first()
(set as List)[0]

If you need to take null into account (not the case in this question):

(set as List)?.first()
(set as List)?.get(index)

Hope it helps! :)