421

I'd like to know if I can get the first element of a list or set. Which method to use?

Martlark
  • 14,208
  • 13
  • 83
  • 99
user496949
  • 83,087
  • 147
  • 309
  • 426

9 Answers9

456

See the javadoc

of List

list.get(0);

or Set

set.iterator().next();

and check the size before using the above methods by invoking isEmpty()

!list_or_set.isEmpty()
Stephan
  • 16,509
  • 7
  • 35
  • 61
stacker
  • 68,052
  • 28
  • 140
  • 210
  • 13
    Use `isEmpty()` instead of `size()>0`. It better shows your intent and is possibly more efficient (e.g. LinkList size() is O(n)). – Steve Kuo Jan 16 '12 at 20:10
  • 13
    @SteveKuo LinkedList has a size variable so size() is O(1). Additionally, isEmpty() is implemented as size() == 0. – efritz May 10 '14 at 22:49
  • 2
    Always use `List.iterator().next()` or `Set.iterator().next()` to avoid O(N) for Linked data structures, you never know what implementation you will be receiving, and of course verify by using `Set.isEmpty()` or `List.isEmpty()` for the same reason, for both cases will always be O(1) instead of a potential O(N) if, again, an implementation of Linked data structure is passed liked `LinkedList` or `LinkedHashSet` – Guido Medina May 11 '15 at 15:51
  • This should be the accepted answer, although not too verbose, but gives the most accurate answer and works perfectly! – Arturas M Sep 09 '16 at 08:55
  • I used the "stream()"-Method, but needed a addional "get()", so I won't have to use the Example: Contract contrVar= contractPerson.getContracts().stream().findFirst().get(); – Birol Efe Mar 01 '23 at 16:34
341
Collection c;

Iterator iter = c.iterator();

Object first = iter.next();

(This is the closest you'll get to having the "first" element of a Set. You should realize that it has absolutely no meaning for most implementations of Set. This may have meaning for LinkedHashSet and TreeSet, but not for HashSet.)

178

In Java >=8 you could also use the Streaming API:

Optional<String> first = set.stream().findFirst();

(Useful if the Set/List may be empty.)

Sonson123
  • 10,879
  • 12
  • 54
  • 72
  • This looks great but without get() I couldn't be able to call resultant element specific methods.`set.stream().findFirst().get()` will allow you to call any methods on the resultant object. eg:`set.stream().findFirst().get().getMessage()` – Diablo Jul 14 '16 at 11:26
  • 4
    @Diablo Be careful though, because `get()` will throw an exception if the optional is empty. There are plenty of other methods on `Optional` that might be more suitable. – Magnilex Feb 28 '17 at 08:06
  • 3
    if you want it to return null, just do `String first = set.stream().findFirst().orElse(null);` – troosan Jan 29 '18 at 14:27
  • 1
    @troosan This is still isn't null-safe because the first element of the set can be `null`, in which case `findFirst()` will throw NPE. The null-safe way is to use something like: `set.stream().map(Optional::ofNullable).findFirst().orElseGet(Optional::empty).orElse(null)`. First, we wrap first element of the stream into Optional, then, after `findFirst()` (which wraps our Optional into another Optional) we unwrap it back or return `Optional.empty()` if Set was empty. Then, finally, we return the first element of Set or null. – Ruslan Stelmachenko Mar 12 '18 at 18:28
  • @djxak indeed you are right, your proposal is of course safer if you are not sure what the set contains (and what Implementation of the Set is used) – troosan Mar 14 '18 at 10:52
  • "If the stream has no encounter order, then any element may be returned" (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) – CrazyGreenHand Aug 26 '20 at 15:00
  • @RuslanStelmachenko Can you elaborate on throwing NPE? – Mikołaj Podbielski Mar 29 '21 at 09:18
  • System.out.println(new HashSet<>().stream().findFirst().orElse(null)); just prints null – Mikołaj Podbielski Mar 29 '21 at 09:24
  • @MikołajPodbielski As I wrote, it will throw NPE only if *the first element of the set is `null`*. Your example uses empty set. It's fine. But try to do `hashSet.add(null)` before you create a stream from it. See [findFirst()](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#findFirst--) docs on the topic when it throws NPE. – Ruslan Stelmachenko Mar 29 '21 at 17:14
67

Let's assume that you have a List<String> strings that you want the first item from.

There are several ways to do that:

Java (pre-8):

String firstElement = null;
if (!strings.isEmpty() && strings.size() > 0) {
    firstElement = strings.get(0);
}

Java 8:

Optional<String> firstElement = strings.stream().findFirst();

Guava

String firstElement = Iterables.getFirst(strings, null);

Apache commons (4+)

String firstElement = (String) IteratorUtils.get(strings, 0);

Apache commons (before 4)

String firstElement = (String) CollectionUtils.get(strings, 0);

Followed by or encapsulated within the appropriate checks or try-catch blocks.

Kotlin:

In Kotlin both Arrays and most of the Collections (eg: List) have a first method call. So your code would look something like this

for a List:

val stringsList: List<String?> = listOf("a", "b", null)
val first: String? = stringsList.first()

for an Array:

val stringArray: Array<String?> = arrayOf("a", "b", null)
val first: String? = stringArray.first()

Followed by or encapsulated within the appropriate checks or try-catch blocks.

Kotlin also includes safer ways to do that for kotlin.collections, for example firstOrNull or getOrElse, or getOrDefault when using JRE8

Ch Vas
  • 993
  • 8
  • 10
  • why there is no null check in java-8 solution? The check is there in Java (pre-8) solution. – pavan Dec 19 '22 at 11:58
  • @pavan this is because according to the documentation, the `findFirst()` "Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty. ". I've also mentioned twice "Followed by or encapsulated within the appropriate checks or try-catch blocks" so it really depends on your case – Ch Vas Dec 22 '22 at 12:01
27

I'm surprised that nobody suggested guava solution yet:

com.google.common.collect.Iterables.get(collection, 0)
// or
com.google.common.collect.Iterables.get(collection, 0, defaultValue)
// or
com.google.common.collect.Iterables.getFirst(collection, defaultValue)

or if you expect single element:

com.google.common.collect.Iterables.getOnlyElement(collection, defaultValue)
// or
com.google.common.collect.Iterables.getOnlyElement(collection)
Radek Postołowicz
  • 4,506
  • 2
  • 30
  • 47
21

and further

Set<String> set = new TreeSet<>();
    set.add("2");
    set.add("1");
    set.add("3");
    String first = set.stream().findFirst().get();

This will help you retrieve the first element of the list or set. Given that the set or list is not empty (get() on empty optional will throw java.util.NoSuchElementException)

orElse() can be used as: (this is just a work around - not recommended)

String first = set.stream().findFirst().orElse("");
set.removeIf(String::isEmpty);

Below is the appropriate approach :

Optional<String> firstString = set.stream().findFirst();
if(firstString.isPresent()){
    String first = firstString.get();
}

Similarly first element of the list can be retrieved.

Hope this helps.

Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89
Nisarg Patil
  • 1,509
  • 1
  • 16
  • 27
  • "If the stream has no encounter order, then any element may be returned"(https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) – CrazyGreenHand Aug 26 '20 at 14:58
10

Set

set.toArray()[0];

List

list.get(0);
Vasil Valchev
  • 5,701
  • 2
  • 34
  • 39
  • 28
    `set.toArray()[0]` will have to pass through whole set contents to create an array to get only the first element, which is not very effective. – dpedro May 13 '16 at 16:12
  • 2
    this will cause a very low performance – ZetaPR Apr 06 '17 at 16:50
  • For a set this method returns an `Object` and not the type of element in the `Set`. – Paul Feb 22 '18 at 18:50
7

This is not an exact answer to this question, but in case the objects should be sorted SortedSet has a first() method:

SortedSet<String> sortedSet = new TreeSet<String>();
sortedSet.add("2");
sortedSet.add("1");
sortedSet.add("3");
String first = sortedSet.first(); //first="1"

The sorted objects must implement the Comparable interface (like String does)

molholm
  • 1,992
  • 3
  • 25
  • 29
  • good to have an access to the `first` method yet here the question concerns list/set regardless the order. – ciekawy Jun 14 '17 at 21:21
  • I know, the question had been answered when i posted this, it is just meant as related information. My thought was that it would be likely that someone looking for an answer to this in some cases would want to work with sorted objects. I edited my answer. – molholm Jun 15 '17 at 07:43
2

You can use the get(index) method to access an element from a List.

Sets, by definition, simply contain elements and have no particular order. Therefore, there is no "first" element you can get, but it is possible to iterate through it using iterator (using the for each loop) or convert it to an array using the toArray() method.

Feni
  • 303
  • 1
  • 4