首页 > 解决方案 > 如何使用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;
    }

标签: javalistiteratorpredicatenext

解决方案


创建一个布尔字段并将其分配给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();

    }
}

推荐阅读