Collections.max function for Iterable<Integer> in Java
Asked Answered
M

6

9

The Java Collections.max method takes only a collection of a sortable (Comparable) object. However since the collection is not necessarily sorted, I don't see any reason not to implement the same max function for Iterable types.

Is there a max method for Iterable<T extends Comparable<? super T>> in Java's standard library?

Morsel answered 14/1, 2009 at 17:38 Comment(2)
Where does it says that Collections.max only takes a sorted collection? From the docs it looks like it will take anything that implements Collection.Latrena
@Outlaw Programmer: that's what he said. "...since the collection is not necessarily sorted..."Deach
C
5

Collections.max was introduced in 1.2. Iterable was introduced in 1.5.

It's rare to have an Iterable that is not a Collection. If you do then it's straightforward to implement (be careful to read the spec). If you think it is really important you can submit an RFE in the Java Bug Database (or vote if there is already one there).

Commensurable answered 14/1, 2009 at 18:46 Comment(4)
Implementing an Iterable is implementing two functions, implementing a collection is more than double the work. So if I want to make a quick iterable of a class I created it's much easier.Morsel
Collections.max(new ArrayList<X>(0) { @Override public Iterator<X> iterator() { return iterable.iterator(); }}) ;)Commensurable
@TomHawtin-tackline: You are a bad man. Never violate the contract of an interface. For instance, an implementation of Collections.max could legitimately start by calling Collection#isEmpty() and throwing an error if it returns true.Sclerometer
@chrispy Yes(ish). May have helped if I added some comment in my comment. Calling toArray often has better properties than calling iterator (works with concurrent/synchronised implementations, and may well be faster). / I note the many of the classes within collections don't implemented the interfaces correctly, and the collection interfaces are really ropey (check out the missing throws documentation in the new (at time of writing) Java SE 8 stuff).Commensurable
S
16

While Guava is not Java's standard library, it's close enough...

E com.google.common.collect.Ordering#max(Iterable<E> iterable)

e.g. T max = Ordering.natural().max(myIterable);

As to why the standard library does not implement it, it may be because a Collection must be finite, but an Iterable need not be—and, arguably, one should never accept an Iterable if a non-terminating Iterable would cause your code to loop forever.

Sclerometer answered 6/4, 2011 at 15:4 Comment(0)
C
5

Collections.max was introduced in 1.2. Iterable was introduced in 1.5.

It's rare to have an Iterable that is not a Collection. If you do then it's straightforward to implement (be careful to read the spec). If you think it is really important you can submit an RFE in the Java Bug Database (or vote if there is already one there).

Commensurable answered 14/1, 2009 at 18:46 Comment(4)
Implementing an Iterable is implementing two functions, implementing a collection is more than double the work. So if I want to make a quick iterable of a class I created it's much easier.Morsel
Collections.max(new ArrayList<X>(0) { @Override public Iterator<X> iterator() { return iterable.iterator(); }}) ;)Commensurable
@TomHawtin-tackline: You are a bad man. Never violate the contract of an interface. For instance, an implementation of Collections.max could legitimately start by calling Collection#isEmpty() and throwing an error if it returns true.Sclerometer
@chrispy Yes(ish). May have helped if I added some comment in my comment. Calling toArray often has better properties than calling iterator (works with concurrent/synchronised implementations, and may well be faster). / I note the many of the classes within collections don't implemented the interfaces correctly, and the collection interfaces are really ropey (check out the missing throws documentation in the new (at time of writing) Java SE 8 stuff).Commensurable
L
0

Hmm… no, there isn’t. If you want to use Collections.max() you have to convert your Iterable into a Collection first, probably by adding all of the elements into a List (or Set, depending on the data).

Lore answered 14/1, 2009 at 17:46 Comment(0)
M
0

My observation of Iterable is that, while it could be used in preference to Collection in many places where a stream of data is needed but not the various collection methods like size, it typically isn't within the Java core libraries.

This is just an inference on my part, but it feels like the Java designers are really sticking to Iterable just being a way to use the enhanced for statement for a given stream of data, and use Collection where a bunch of data items are needed, even if Iterable would be sufficient.

A look at the Javadocs for Iterable adds weight to this viewpoint, as this is the only thing called out in the class-level Javadocs:

Implementing this interface allows an object to be the target of the enhanced for statement (sometimes called the "for-each loop" statement).

Mada answered 29/11, 2023 at 7:14 Comment(0)
M
0

With the introduction of streams with Java 8, operations like this that could be done on an Iterable are generally instead done on a Stream.

StreamSupport.stream can convert any Iterable to a Stream, which means that the stream-based approach to finding a max value can be used for an arbitrary Iterable:

Optional<Integer> max = StreamSupport.stream(iterable.spliterator(), false)
        .max(Comparator.naturalOrder());
Mada answered 29/11, 2023 at 7:25 Comment(0)
D
-2

By definition the elements of the collection must be "sortable" (specifically, they must implements Comparable) since in order to compute the maximum, it must be possible to work out whether one element is greater than another (which is exactly what Comparable means).

The max() method in the Collections class has essentially the exact type signature you posted there, so it should suit your purpose.

Dipper answered 14/1, 2009 at 17:50 Comment(1)
I want to compute the max of an Iterable which is not a CollectionMorsel

© 2022 - 2024 — McMap. All rights reserved.