Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To check whether all elements of a `Stream` are identical

I am in the process of changing some of my old code to take advantage of the functional aspects of Java 8. In particular, I am moving from using Guava predicates to java.util.function.Predicate. One of the predicates is to check whether a Stream is homogeneous, i.e. consists of all identical elements.

In my old code (using Guava's Predicate), I had this:

static <T> Predicate<Iterable<T>> isHomogeneous() {
    return new Predicate<Iterable<T>>() {
        public boolean apply(Iterable<T> iterable) {
            return Sets.newHashSet(iterable).size() == 1;
        }
    };
}

This is the new version, using java.util.function.Predicate:

public static Predicate<Stream<?>> isHomogeneous =
    stream -> stream.collect(Collectors.toSet()).size() == 1;

The IDE (IntellijIDEA v.12) doesn't show any red squiggly line to indicate an error, but when I try to compile, I get this:

java: no suitable method found for
collect(java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.Set<java.lang.Object>>)
  method java.util.stream.Stream.<R>collect(java.util.function.Supplier<R>,java.util.function.BiConsumer<R,? super capture#2 of ?>,java.util.function.BiConsumer<R,R>) is not applicable
    (cannot infer type-variable(s) R
      (actual and formal argument lists differ in length))
  method java.util.stream.Stream.<R,A>collect(java.util.stream.Collector<? super capture#2 of ?,A,R>) is not applicable
    (cannot infer type-variable(s) R,A,capture#3 of ?,T
      (argument mismatch; java.util.stream.Collector<capture#2 of ?,capture#4 of ?,java.util.Set<capture#2 of ?>> cannot be converted to java.util.stream.Collector<? super capture#2 of ?,capture#4 of ?,java.util.Set<capture#2 of ?>>))

Note: I think having a predicate on a stream is probably not a good idea. In fact, in my codebase, I only need it on a List<>. But I am still curious about what is wrong with the simple one-line isHomogeneous predicate.

like image 950
Chthonic Project Avatar asked Sep 15 '14 19:09

Chthonic Project


1 Answers

Another option is to use Stream.distinct and make sure you only get 1 element in the resulting stream.

stream.distinct().limit(2).count() == 1
like image 55
aioobe Avatar answered Nov 04 '22 20:11

aioobe