Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why there is no getFirst(iterable) method?

Iterables present two methods for getLast

 public static <T> T getLast(Iterable<T> iterable);  public static <T> T getLast(Iterable<T> iterable, @Nullable T defaultValue); 

but only one for getFirst

 public static <T> T getFirst(Iterable<T> iterable, @Nullable T defaultValue); 

Is there are any design/implementation reason for breaking symmetry?

like image 635
Stan Kurilin Avatar asked Dec 12 '11 11:12

Stan Kurilin


People also ask

Is a collection an iterable?

A Collection is an Iterable . I know that the OP asked about it, but the assignment to Iterable is entirely unnecessary.

What is iterable return type?

Iterable can also be used as a return type to indicate a function will return an iterable value. If the returned value is not an array or instance of Traversable, a TypeError will be thrown. Example #3 Iterable return type example. function bar(): iterable { return [1, 2, 3];


2 Answers

I think the point is that there is no reason for a getFirst(iterable) in that this could be done with iterable.iterator().next(). Guava makes an excellent attempt to keep the API small and so does not add things that could / should be done easily another way.

On the other hand, there is not already a mechanism to test if an iterable is empty and if so return a default value instead of the first value. Hence, getFirst(iterable, default).

Also, there is not a simple way to get the last element, hence getLast(iterable) and getLast(iterable, default)

like image 128
John B Avatar answered Nov 08 '22 02:11

John B


As an additions to @JohnB's answer I'd like to show Guava's devs opinion about getFirst(iterable). Kevin Bourrillion (head Guava's dev) writes there:

iterable.iterator().next() is perfectly clear and readable and unambiguous. I know exactly what it does, whereas with Iterators.getFirst(), I have to run off and look up how that library designer decided to do it.

Also, your notion of consistency is deeply misguided. We use consistency in how we present important functionality, but we never use it to justify adding worthless functionality, and you shouldn't in your own libraries either!

So, you have a choice:

  • using iterable.iterator().next(),
  • using Iterables.getFirst(Iterable<T> iterable, T default),
  • using Iterables.get(Iterable<T>, 0),
  • writing your own method (probably containing iterable.iterator().next() and some docs) and use it as i.e. Iterables2.getFirst(iterable),
  • waiting for Kevin to change his mind ;)

PS: I had similar doubt some time ago and found exact duplicate of this question at that time.

like image 30
Xaerxess Avatar answered Nov 08 '22 01:11

Xaerxess