26

Possible Duplicate:
Java: Get first item from a collection

In Java, I often encounter a collection with one single element, which I need to retrieve. Because collections do not guarantee consistent ordering, there is no first() or get(int index) methods, so I need to use rather ugly things, such as:

public Integer sillyExample(Collection<Integer> collection){
    if(collection.size()==1){
        return collection.iterator().next();
    }
    return someCodeToDecideBetweenElements(collection);
}

So, how do you get the only element out? I can't believe there isn't a better way...

Please note, I understand there's no concept of "first", I'm just trying to avoid building an iterator when I know there is only one element in it.

EDIT: Peter Wooster found a very similar question here. I'm leaving this open because I'm not trying to get the "first" element, which would imply a consistent ordering, but the "one and only" element after checking that it indeed is the only element.

Community
  • 1
  • 1
Miquel
  • 15,405
  • 8
  • 54
  • 87
  • 5
    Exactly like this, except I wouldn't dare call `size()`. `Iterator it = collection.iterator(); return it.hasNext()? it.next() : null;` and now you can go to an even more general `Iterable`. – Marko Topolnik Jan 16 '13 at 10:00
  • hm, counter-question. What do you do if it does not have a single item? Wouldnt iterate over all elements all the time be waaaay safer than using this hack? – Najzero Jan 16 '13 at 10:00
  • 2
    it's actually a good thing that `Collection` does not offer `first() `or `get(int)`, since a collection is generally unordered, and there is no "first" element – gefei Jan 16 '13 at 10:01
  • you could construct an ArrayList from it, but that;s ugly too. – Peter Wooster Jan 16 '13 at 10:02
  • 1
    Here's an old post on this topic: http://stackoverflow.com/questions/1671378/java-get-first-item-from-a-collection – Peter Wooster Jan 16 '13 at 10:03
  • @MarkoTopolnik "dare call size()"? Do you see any danger there? I simply check the size because the treatment I need to give the collection is different if I just have to return the one element, or make a choice between the two. I alter the code to reflect it. – Miquel Jan 16 '13 at 10:04
  • 1
    I would do it like in Marko Topolnic's comment above, just with a generic method signature. – jlordo Jan 16 '13 at 10:04
  • @Miquel If calling some method, clearly the right one is `isEmpty`; `size` requests more information from the collection than you need and may entail calculating the size, which the collection didn't know in advance. For example, what if it is a lazy-loaded collection from Hibernate, or anything like that? – Marko Topolnik Jan 16 '13 at 10:06
  • @MarkoTopolnik yes, but I don't want to know if it's empty, I want to know if it has exactly one element – Miquel Jan 16 '13 at 10:07
  • Aha, you want to **assert** it has only one element? Then do `Iterator it = collection.iterator(); Integer ret = it.hasNext()? it.next() : null; if (it.hasNext()) return someCodeToDecideBetweenElements(collection);` – Marko Topolnik Jan 16 '13 at 10:09
  • @Jayamohan yeap, my apologies. Peter Wooster found the original. I've added it to the question, and I going to vote to close it. – Miquel Jan 16 '13 at 10:09
  • @Miquel That other question doesn't require the assertion you have mentioned. If you make that additional request clear in your question, then you don't have a duplicate. – Marko Topolnik Jan 16 '13 at 10:11
  • 1
    Also take into account that "building an iterator" is not really a good paradigm: the iterator is a very lightweight object, designed to be created at will with negligible performance impact. – Marko Topolnik Jan 16 '13 at 10:26

3 Answers3

28

The easiest answer is what you've done!

first = collection.iterator().next();

note that iterator() is a method, was that a typo?

Peter Wooster
  • 6,009
  • 2
  • 27
  • 39
16

Have you ever looked at Google Guava? If you know that the collection has one element only, you can use Iterables.getOnlyElement(collectionWithOneElement); but if you don't know but still only want the first element you can use getFirst(Iterable, T default). It will also return a default value you define if its empty.

gunr2171
  • 16,104
  • 25
  • 61
  • 88
drobson
  • 955
  • 7
  • 13
  • Thanks! I didn't know the method, but I just checked it and it's internally doing `return iterators.getOnlyElement(iterable.iterator());` so it's still building an iterator internally – Miquel Jan 16 '13 at 10:15
  • 2
    ...and what it does with the iterator is entirely predictable, too, just as in my comment under the question. This may be a reassurance to you that this approach is the best. – Marko Topolnik Jan 16 '13 at 10:19
2

Its as simple as it is,

 Iterator<Integer> itr = collection.iterator(); 
 Object firstObj = itr.hasNext()? itr.next() : null;
Amol Fasale
  • 942
  • 1
  • 10
  • 32