How do I use lambda expressions and streams in the following example?

How do I write the following procedure using lambda expressions and how do I write it using streams?

Screen myScreen = new Screen();
Pattern myPattern = new Pattern("img.png");

Iterator<Match> it = myScreen.findAll(myPattern);
  while (it.hasNext())
    it.next().click();

      

+3


source to share


4 answers


Alternatively, in Java 8, the interface Iterator

has a default forEachRemaining (Consumer) method .

This will solve your problem without resorting to threads. You can simply do:



Iterator<Match> it = myScreen.findAll(myPattern);
it.forEachRemaining(Match::click);

      

+4


source


You can use Apache Commons Collections to do this. For example:



Iterator<Match> matches = s.findAll("someImage.png");
List<Match> list = IteratorUtils.toList(matches);
list.stream().forEach(Match::highlight);

      

+2


source


If you really want to use Stream with lambdas for this, you need to convert the Iterator to Stream first, and then you can use this Stream to iterate over your objects and call their method click

using the method reference:

Iterator<Match> it = myScreen.findAll(myPattern);

// convert Iterator to Stream
Iterable<Match> iterable = () -> it;
Stream<Match> stream = StreamSupport.stream(iterable.spliterator(), false);

// invoke click on each object
stream.forEach(Match::click);

      

Or, if you want to use an explicit lambda expression:

stream.forEach(match -> match.click());

      

+2


source


Well there will be an iterator with streams like a for loop or an iterator - through Stream.iterate

, but it will be present in jdk-9. But this is not so trivial to use because it acts exactly like a for loop and therefore not exactly what you expect. For example:

 Iterator<Integer> iter = List.of(1, 2, 3, 4).iterator();

 Stream<Integer> stream = Stream.iterate(iter.next(),
                   i -> iter.hasNext(), 
                   i -> iter.next()); 
     stream.forEach(System.out::println); // prints [1,2,3]

      

Or that:

 Iterator<Integer> iter = List.of(1).iterator();

    Stream.iterate(iter.next(), i -> iter.hasNext(), i -> iter.next())
            .forEach(System.out::println); // prints nothing

      

For the case in which you need forEachRemaining

it but it's not "magic", internally it does exactly what you do:

default void forEachRemaining(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    while (hasNext())
        action.accept(next());
}

      

+2


source







All Articles