如何在以下示例中使用 lambda 表达式和流?
How to use lambda expressions and streams in the following example?
如何使用 lambda 表达式编写以下过程,以及如何使用流编写它?
Screen myScreen = new Screen();
Pattern myPattern = new Pattern("img.png");
Iterator<Match> it = myScreen.findAll(myPattern);
while (it.hasNext())
it.next().click();
您可以使用 Apache Commons Collections 实用程序来做到这一点。例如:
Iterator<Match> matches = s.findAll("someImage.png");
List<Match> list = IteratorUtils.toList(matches);
list.stream().forEach(Match::highlight);
如果你真的想为此使用带 lambda 的 Stream,你必须先将 Iterator 转换为 Stream,然后你可以使用这个 Stream 迭代你的对象并调用它们的 click
方法方法参考:
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);
或者,如果您想使用显式 lambda 表达式:
stream.forEach(match -> match.click());
或者,在 Java 8 中,Iterator
接口有一个默认方法 forEachRemaining(Consumer)。
那个可以解决你的问题,而不必求助于流。你可以简单地做:
Iterator<Match> it = myScreen.findAll(myPattern);
it.forEachRemaining(Match::click);
好吧,将会 一种像 for 循环或迭代器一样使用流进行迭代的方法 - 通过 Stream.iterate
,但它会出现在 jdk-9。但它的使用并不那么简单——因为它的行为与 for 循环完全一样,因此并不完全符合您的预期。例如:
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]
或者这样:
Iterator<Integer> iter = List.of(1).iterator();
Stream.iterate(iter.next(), i -> iter.hasNext(), i -> iter.next())
.forEach(System.out::println); // prints nothing
对于您需要的情况,有 forEachRemaining
,但没有 "magic",它在内部完全符合您的要求:
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
如何使用 lambda 表达式编写以下过程,以及如何使用流编写它?
Screen myScreen = new Screen();
Pattern myPattern = new Pattern("img.png");
Iterator<Match> it = myScreen.findAll(myPattern);
while (it.hasNext())
it.next().click();
您可以使用 Apache Commons Collections 实用程序来做到这一点。例如:
Iterator<Match> matches = s.findAll("someImage.png");
List<Match> list = IteratorUtils.toList(matches);
list.stream().forEach(Match::highlight);
如果你真的想为此使用带 lambda 的 Stream,你必须先将 Iterator 转换为 Stream,然后你可以使用这个 Stream 迭代你的对象并调用它们的 click
方法方法参考:
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);
或者,如果您想使用显式 lambda 表达式:
stream.forEach(match -> match.click());
或者,在 Java 8 中,Iterator
接口有一个默认方法 forEachRemaining(Consumer)。
那个可以解决你的问题,而不必求助于流。你可以简单地做:
Iterator<Match> it = myScreen.findAll(myPattern);
it.forEachRemaining(Match::click);
好吧,将会 一种像 for 循环或迭代器一样使用流进行迭代的方法 - 通过 Stream.iterate
,但它会出现在 jdk-9。但它的使用并不那么简单——因为它的行为与 for 循环完全一样,因此并不完全符合您的预期。例如:
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]
或者这样:
Iterator<Integer> iter = List.of(1).iterator();
Stream.iterate(iter.next(), i -> iter.hasNext(), i -> iter.next())
.forEach(System.out::println); // prints nothing
对于您需要的情况,有 forEachRemaining
,但没有 "magic",它在内部完全符合您的要求:
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}