In the course of JSR-335, we considered a number of possible methods on Iterable. There are literally hundreds of methods that might "sensibly" appear on Iterable; see RichIterable from GS-Collections or IEnumerable from .NET for some examples. After considering the landscape, we decided, basically, to not do any of them.

The reason is that Iterable is *so general* and *so ubiquitous* that adding new methods at this stage would carry an unreasonable risk of collision. When viewed through the lens of "what is an Iterable", the meaning of a "getFirst()" is obvious enough. (getLast(), not so much; this assumes there is a last, which is a bad assumption, given that there's no size() or isKnownFinite() method.)

The problem is, in the context of some Foo that implements Iterable<Bar>, methods like getFirst() or sorted() or filter() or ... might not obviously mean in the context of Foo what they obviously mean in the context of Iterable. Iterable is too general. And there are zillions of outstanding Iterable classes now, so the risk is high.

So given the choice between adding a zillion new methods, and adding zero (which is basically the choice, drawing the line is very hard and will always be under pressure to move "just one more method to the left"), we chose zero.

On 4/17/2014 7:52 AM, Otávio Gonçalves de Santana wrote:
I would to add for news methods on Iterable, I believe it will helpful for
many Java Developers.


diff -r 3dd165facde7 test/java/util/Iterator/IteratorDefaults.java

--- a/test/java/util/Iterator/IteratorDefaults.java Wed Apr 09 12:26:00
2014 -0700

+++ b/test/java/util/Iterator/IteratorDefaults.java Wed Apr 16 23:25:56
2014 -0300

@@ -399,6 +399,48 @@

          }

      }



+     public void testgetFirst() {

+

+        List<Integer> source = Arrays.asList(1, 2, 3, 4);

+        int first = source.getFirst();

+        assertEquals(first, 1);

+

+        List<String> emptySource = Collections.<String>emptyList();

+        assertNull(emptySource.getFirst());

+    }

+

+    public void testgetFirstWithDefaultElement() {

+

+        List<Integer> source = Arrays.asList(1, 2, 3, 4);

+        Integer defaultElement = 5;

+        assertEquals(source.getFirst(defaultElement), Integer.valueOf(1));

+

+        List<Integer> emptySource = Collections.<Integer>emptyList();

+        assertEquals(emptySource.getFirst(defaultElement), defaultElement);

+

+    }

+

+    public void testgetLast() {

+

+        List<Integer> source = Arrays.asList(1, 2, 3, 4);

+        int last = source.getLast();

+        assertEquals(last, 4);

+

+        List<String> emptySource = Collections.<String>emptyList();

+        assertNull(emptySource.getLast());

+    }

+

+    public void testgetLastWithDefaultElement() {

+

+        List<Integer> source = Arrays.asList(1, 2, 3, 4);

+        Integer defaultElement = 5;

+        assertEquals(source.getLast(defaultElement), Integer.valueOf(4));

+

+        List<Integer> emptySource = Collections.<Integer>emptyList();

+        assertEquals(emptySource.getLast(defaultElement), defaultElement);

+

+    }

+

      static class IteratorWithRemove implements Iterator {



          public boolean removed;




diff -r 3dd165facde7 src/share/classes/java/lang/Iterable.java

--- a/src/share/classes/java/lang/Iterable.java Wed Apr 09 12:26:00 2014
-0700

+++ b/src/share/classes/java/lang/Iterable.java Wed Apr 16 23:16:21 2014
-0300

@@ -100,4 +100,55 @@

      default Spliterator<T> spliterator() {

          return Spliterators.spliteratorUnknownSize(iterator(), 0);

      }

+

+

+   /**

+     * returns the first element, if empty will return {@code null}

+     * @return the first element or {@code null}

+     * @since 1.8

+     */

+    default T getFirst() {

+        return getFirst(null);

+    }

+

+    /**

+     * returns the first element, if empty will return the default

+     * @param defaultValue - the default value to return if the iterable
is empty

+     * @return the first element or default element

+     * @since 1.8

+     */

+    default T getFirst(T defaultValue) {

+        for (T element : this) {

+            return element;

+        }

+        return defaultValue;

+    }

+

+  /**

+     * returns the last element, if empty will return {@code null}

+     * @return the first element or {@code null}

+     * @since 1.8

+     */

+    default T getLast() {

+

+        return getLast(null);

+    }

+

+    /**

+     * returns the last element, if empty will return the default

+     * @param defaultValue - the default value to return if the iterable
is empty

+     * @return the last element or default element

+     * @since 1.8

+     */

+    default T getLast(T defaultValue) {

+

+        T last = null;

+        for (T element : this) {

+            last = element;

+        }

+        if (Objects.isNull(last)) {

+            return defaultValue;

+        }

+        return last;

+    }

  }

Reply via email to