给定这样一个对象:
Matcher matcher = pattern.matcher(sql);
用法如下:
Set<String> matches = new HashSet<>();
while (matcher.find()) {
matches.add(matcher.group());
}
我想用更面向对象的东西来代替这个while循环,比如:
new Iterator<String>() {
@Override
public boolean hasNext() {
return matcher.find();
}
@Override
public String next() {
return matcher.group();
}
}
因此,我可以很容易地,例如,使匹配流,坚持使用流畅的API等。
问题是,我不知道也找不到更简洁的方法来创建这个流或迭代器。像上面这样的匿名类对我来说太冗长了。
我曾希望在jdk中找到像IteratorFactory.from(matcher::find,matcher::group)
或StreamSupport.of(matcher::find,matcher::group)
这样的东西,但到目前为止还没有运气。毫无疑问,像apache commons或番石榴这样的库为此提供了一些东西,但让我们说我不能使用这些。
对于流或迭代器来说,有没有一个方便的工厂,在jdk中采用hasNext/next方法组合?
我写的这门课体现了我想在jdk中找到的东西。显然,虽然它根本不存在。不过,eugene接受的答案提供了一个java 9 Stream解决方案。
public static class SearchingIterator<T> implements Iterator<T> {
private final BooleanSupplier advancer;
private final Supplier<T> getter;
private Optional<T> next;
public SearchingIterator(BooleanSupplier advancer, Supplier<T> getter) {
this.advancer = advancer;
this.getter = getter;
search();
}
private void search() {
boolean hasNext = advancer.getAsBoolean();
next = hasNext ? Optional.of(getter.get()) : Optional.empty();
}
@Override
public boolean hasNext() {
return next.isPresent();
}
@Override
public T next() {
T current = next.orElseThrow(IllegalStateException::new);
search();
return current;
}
}
用法:
Matcher matcher = Pattern.compile("\\d").matcher("123");
Iterator<String> it = new SearchingIterator<>(matcher::find, matcher::group);
在java-9中,你可以通过:
Set<String> result = matcher.results()
.map(MatchResult::group)
.collect(Collectors.toSet());
System.out.println(result);
在java-8中,您需要一个后端端口来实现这一点
编辑
有一种方法可以包含<code>find/group
static class MyIterator extends AbstractSpliterator<String> {
private Matcher matcher;
public MyIterator(Matcher matcher) {
// I can't think of a better way to estimate the size here
// may be you can figure a better one here
super(matcher.regionEnd() - matcher.regionStart(), 0);
this.matcher = matcher;
}
@Override
public boolean tryAdvance(Consumer<? super String> action) {
while (matcher.find()) {
action.accept(matcher.group());
return true;
}
return false;
}
}
和用法举例:
Pattern p = Pattern.compile("\\d");
Matcher m = p.matcher("12345");
Set<String> result = StreamSupport.stream(new MyIterator(m), false)
.collect(Collectors.toSet());
问题内容: 有没有一种方法来获取数组的迭代器?像这样: 问题答案: 您可以使用: 它只是将数组包装在列表实现中,以便您可以在其上调用方法。 请注意,这种方法仅适用于对象数组。对于原始数组,您将必须实现自己的迭代器(例如,使用匿名类)。 从Java 8开始,您还可以使用开箱即用的迭代器(并且如果是或,也可以使此代码进行编译: 尽管您将无法使用原始数据类型,并且因为没有相应的流实现。但是,您可以使用以
将这些视为对象: 查看java文档,对于LinkedList类,LinkedList类中没有迭代器方法的实现,但是,实现是在AbstractSequentialList类中。 listIterator()方法在AbstractList类中实现,AbstractSequentialList的父类,总结一下,如果我没弄错的话,它返回一个不使用节点概念的迭代器对象。 但是方法是在LinkedList类中
问题内容: 考虑: 因此,按预期方式,通过更改同一对象来处理迭代器。 在这种情况下,我希望: 跳过每第二个元素:对的调用应使迭代器前进一次,然后循环进行的隐式调用应使它第二次进行-并将第二次调用的结果分配给。 没有。该循环将打印列表中的 所有 项目,而不会跳过任何项目。 我的第一个想法是可能发生这种情况,因为循环调用了它所传递的内容,并且这可能会提供一个独立的迭代器-事实并非如此。 那么,为什么在
问题内容: 假设我们有一个迭代器(一个无限的迭代器)返回列表(或有限迭代器),例如一个由 获得一个迭代器(显然是无限的)是一个好的Python习惯用法,该迭代器将从第一个迭代器返回每个元素,然后从第二个迭代器返回每个元素,依此类推。在上面的示例中它将返回。迭代器是无限的,因此将无法使用。 有关 在python中展平浅表 问题答案: 从Python 2.6开始,您可以使用: 您也可以使用嵌套的生成器
问题内容: 我想将多处理池与迭代器一起使用,以便在将迭代器拆分为N个元素的线程中执行函数,直到迭代器完成为止。 我的问题是,此脚本是正确的方法吗?有没有更好的办法? 该脚本可能出了点问题,因为我在 问题答案: 如果我不得不猜测代码的主要问题,那是因为将您的代码传递给了流程函数-工作方式是解压缩传递给它的参数,因此您的函数实际上是获取参数,而不是列出一个参数的元素。这会在过程功能甚至没有机会启动之前