考虑到我有以下课程:
public class Problem2 extends Problem<Integer> {
@Override
public void run() {
result = toList(new FibSupplier(i -> (i <= 4_000_000)))
.stream()
.filter(i -> (i % 2 == 0))
.mapToInt(i -> i)
.sum();
}
@Override
public String getName() {
return "Problem 2";
}
private static <E> List<E> toList(final Iterator<E> iterator) {
List<E> list = new ArrayList<>();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
private class FibSupplier implements Iterator<Integer> {
private final IntPredicate hasNextPredicate;
private int beforePrevious = 0;
private int previous = 1;
public FibSupplier(final IntPredicate hasNextPredicate) {
this.hasNextPredicate = hasNextPredicate;
}
@Override
public boolean hasNext() {
return hasNextPredicate.test(previous);
}
@Override
public Integer next() {
int result = beforePrevious + previous;
beforePrevious = previous;
previous = result;
return result;
}
}
}
如果你看一下FibSupplier
你可以看到它暴露了一个普遍的问题,即使它在这里有一个专门的实现,我设法提取的是:
Predicate
。next()
方法。我试图概括这一点,但请注意我现在使用的是通用版本而不是专门的整数版本:
public class FiniteSupplier<E> implements Iterator<E> {
private final Predicate<E> predicate;
public FiniteSupplier(final Predicate<E> predicate) {
this.predicate = predicate;
}
@Override
public boolean hasNext() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public E next() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
我希望能够使用FiniteSupplier
来呼叫predicate
,但是现在我真的不知道如何实现我设法提取的其他要求。我理解可以通过扩展FiniteSupplier
并使其成为抽象来完成,但这是正确的方法吗?
答案 0 :(得分:0)
方法test(int/Integer)
可用作Predicate<Integer>
和IntPredicate
。编译器执行转换:
IntPredicate ip = (i) -> i>0;
Predicate<Integer> pi = (i) -> i>0;
Predicate<Integer> ip2pi = ip::test;
IntPredicate pi2ip = pi::test;
但是你不能投射这两种类型,因为它们不可分配。 IntPredicate不会扩展谓词。
所以在创建FibSupplier时只需使用:: test:
new FibSupplier(p) => new FibSupplier(p::test)
或者在构造函数中执行此操作。我引入了一个新的抽象类型FiniteIntSupplier,它带有一个额外的构造函数,它接受一个IntSupplier并将其转换为一般供应商:
public FiniteIntSupplier(IntPredicate p) {
this(p::test);
}