3 java iterable predicate java-8
我想使用Iterable<String>和 谓词来执行一个字符串列表过滤函数来选择要保留的字符串,其他字符串必须从列表中删除,但我并没有低估如何进行删除。
static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) {
for (T s: it) {
if (pred.test(s)==false) {
// what to do here?
}
}
return ...;
}
Run Code Online (Sandbox Code Playgroud)
对于此输入:
{"a","","b",""}
Run Code Online (Sandbox Code Playgroud)
我预计
{"a","b"}
Run Code Online (Sandbox Code Playgroud)
An代表根据请求Iterable提供的能力。Iterator因此,要使用过滤逻辑装饰现有的可迭代对象,您必须实现装饰Iterator.
static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) {
return () -> new Iterator<T>() {
Iterator<T> sourceIterator = it.iterator();
T current;
boolean hasCurrent;
@Override
public boolean hasNext() {
while(!hasCurrent) {
if(!sourceIterator.hasNext()) {
return false;
}
T next = sourceIterator.next();
if(pred.test(next)) {
current = next;
hasCurrent = true;
}
}
return true;
}
@Override
public T next() {
if(!hasNext()) throw new NoSuchElementException();
T next = current;
current = null;
hasCurrent = false;
return next;
}
};
}
Run Code Online (Sandbox Code Playgroud)
你可以通过它进行测试
List<String> original = new ArrayList<>();
Collections.addAll(original, "foo", "bar", "baz");
Iterable<String> filter = select(original, s -> s.startsWith("b"));
System.out.println(String.join(", ", filter));
original.removeIf(s -> !s.endsWith("r"));
System.out.println(String.join(", ", filter));
Run Code Online (Sandbox Code Playgroud)
实现这样的 时最大的挑战Iterator是提供两种方法hasNext并next具有正确的语义,而不能保证调用者将如何调用它们,即您不能假设它永远不会调用hasNext()两次,也next()不能假设它总是用前面hasNext().
使用 Stream API 可以更轻松地实现相同的逻辑:
static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) {
return () -> StreamSupport.stream(it.spliterator(), false)
.filter(pred).iterator();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9699 次 |
| 最近记录: |