java - 如何使用Iterator java获取前一个元素
问题描述
我有以下问题。我一直在做一个任务,其中给出了迭代器并且 Predicate 类必须检查迭代器中是否存在字符串。我覆盖了迭代器中的hasNext()
和next()
方法。更高级的是 PredicateIteratorTest。我收到消息junit.framework.AssertionFailedError: expected:<Java [and UML]> but was:<Java [11]> at PredicateIteratorTest.providesValuesBeginningWithJava(PredicateIteratorTest.java:37)
它应该返回前一个元素。
public class PredicateIteratorTest {
private final List<String> values = List.of(//
"Java and UML", "UML and Java", "Java 11", "UML 2.0", "Effective Java");
private Iterator<String> valuesEndingWithJava;
private Iterator<String> valuesBeginningWithJava;
private Iterator<String> noValues;
@Before
public void setUp() {
valuesEndingWithJava = new PredicateIterator<>(values.iterator(), new EndsWith("Java"));
valuesBeginningWithJava = new PredicateIterator<>(values.iterator(), new StartsWith("Java"));
noValues = new PredicateIterator<>(values.iterator(), new StartsWith("Doesn't match"));
}
@Test
public void providesValuesEndingWithJava() {
assertTrue(valuesEndingWithJava.hasNext());
assertEquals("UML and Java", valuesEndingWithJava.next());
assertTrue(valuesEndingWithJava.hasNext());
assertEquals("Effective Java", valuesEndingWithJava.next());
}
}
这是 PredicateIterator 类。在if(predicate.test(iterator.next())){
我想做与 ListIterator 中的方法类似的事情之后iterator.previous()
,但不使用 ListIterator,因为测试只使用 Iterator。我怎样才能做到?
public class PredicateIterator<T> implements Iterator<T>{
private Iterator<T> iterator;
private Predicate<T> predicate;
public PredicateIterator(Iterator<T> iter, Predicate<T> predicate){
this.iterator = iter;
this.predicate = predicate;
}
@Override
public boolean hasNext(){
while(iterator.hasNext()){
if(predicate.test(iterator.next())){
return true;
}
}
return false;
}
@Override
public T next(){
T elem;
while (iterator.hasNext()){
elem = iterator.next();
if(predicate.test(elem)){
return elem;
}
}
throw new NoSuchElementException();
}
}
我通过添加 ListIterator 和 iterator.previous() 更改了 PredicateIterator。但现在我有测试错误java.lang.UnsupportedOperationException at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:73) at java.base/java.util.ImmutableCollections$ListItr.previous(ImmutableCollections.java:260) at PredicateIterator.hasNext(PredicateIterator.java:20) at PredicateIteratorTest.providesValuesBeginningWithJava(PredicateIteratorTest.java:36)
private ListIterator<T> iterator;
private Predicate<T> predicate;
public PredicateIterator(Iterator<T> iter, Predicate<T> predicate){
this.iterator = (ListIterator<T>) iter;
this.predicate = predicate;
}
@Override
public boolean hasNext(){
while(iterator.hasNext()){
if(predicate.test(iterator.next())){
iterator.previous();
return true;
}
}
return false;
}
解决方案
创建一个布尔字段并将其分配给false,但在找到值后在hasNext方法中将其分配给true,然后在next方法中检查该字段,如果它为false,则意味着您在hasNext方法之前调用了next方法,然后你必须在 next 方法中调用 hasNext 方法。
public class PredicateIterator<T> implements Iterator<T> {
private Predicate predicate;
private Iterator<T> iter;
private T type;
private boolean test = false;
public PredicateIterator(Iterator<T> iter, Predicate<T> predicate) {
if (iter == null || predicate == null) throw new NoSuchElementException();
this.predicate = predicate;
this.iter = iter;
}
@Override
public boolean hasNext() {
if (iter == null) throw new NoSuchElementException();
while (iter.hasNext()) {
type = iter.next();
if (predicate.test(type)) {
test = true;
return true;
}
}
return false;
}
@Override
public T next() {
if (!test) {
if ( hasNext()) {
T newTyp = type;
type = null;
test = false;
return newTyp;
}
}
else if (type != null) {
T newTyp = type;
type = null;
test = false;
return newTyp;
}
throw new NoSuchElementException();
}
}
推荐阅读
- django - 将旧的 Django URL 更改为新路径
- haskell - 使用 Aeson 在 Haskell 中生成 JSON 的上下文
- ruby-on-rails - 用户索引测试失败 Rails 教程
- react-native - React Native - Redux - 如何从非组件调用操作?
- tensorflow - Tensorflow:在一个网络中训练两个网络
- ruby - 如何应用 if/then 语句来反驳/断言方法
- recaptcha - recaptcha v3 前端返回奇怪的、空洞的(无效的?)结果与 )]}'
- c - 利用金丝雀保护的缓冲区溢出
- machine-learning - 如何学习和创建语音识别系统?
- mysql - MySql 在主查询中使用 group by 排序子查询