通用Pair类的自己的迭代器

时间:2018-07-05 10:14:17

标签: java generics iterator

我正在尝试为自己的通用类编写自己的自己的Iterator 。我一直在看几个YouTube教程并在网上搜索。

var urls = ['https://www.somewebsite.fr/produit/yi-camera-3600-noir-vr-33705370/offre-81085802?utm_source=325483&utm_medium=affiliation&utm_content=catalogue-RDC&awc=6901_1530705916_88ef12642ad61dfc5239ba01bbbe5249', 'https://www.somewebsite.fr/produit/yi-camera-3600-noir-vr-33705370/offre-81085802?t=55&utm_source=325483&utm_medium=affiliation&utm_content=catalogue-RDC&awc=6901_1530705916_88ef12642ad61dfc5239ba01bbbe5249','https://www.somewebsite.fr/produit/yi-camera-3600-noir-vr-33705370/offre-81085802?awc=6901_1530705916_88ef12642ad61dfc5239ba01bbbe5249&utm_tt=78', 'https://www.somewebsite.fr/produit/yi-camera-3600-noir-vr-33705370/offre-81085802?utm=6901_1530705916_88ef12642ad61dfc5239ba01bbbe5249&utm=ewe'];

var u = 'utm[^&]*';
var rx = new RegExp("(\\?)"+u+"(?:&"+u+")*&(?=(?!utm[^\s&=]*=)[^\s&=]+=)|\\?"+u+"(?:&"+u+")*$|&"+u, "ig");
for (var url of urls) {
  console.log(url, "=>", url.replace(rx, '$1'));
}

IntelliJ指出的问题是,由于不能从静态上下文中引用非静态方法,因此我无法按我尝试的方式在Iterator-Class中使用getLeft和getRight。 。我一直在研究静态方法和更多方法,但是无法解决此问题。我是否完全走错了道路,或者至少我的做法有些接近?

更新

运行时:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Pair<T> implements Iterable<T> {

    private T left;
    private T right;

    public Pair(T left, T right){
        this.left = left;
        this.right = right;
    }

    public  T getRight(){return this.right;}
    public  T getLeft(){return this.left;}

    // own Iterator
    @Override
    public Iterator<T> iterator() {
        return new myIterator;
    }


    class myIterator implements Iterator<T>{
        T newLeft = null;

        @Override
        public boolean hasNext() {
            if(newLeft == null && Pair.getLeft() != null){
                return true;
            }
            else if(newLeft !=null){
                return Pair.getRight() !=null;
            }
            else {
                return false;
            }
        }
        @Override
        public T next() {
            if(newLeft == null && Pair.getLeft() != null){
                newLeft = Pair.getLeft();
                return newLeft;
            }
            else if(newLeft != null){
                T newRight = Pair.getLeft();
                newLeft = Pair.getRight();
                return newRight;
            }
            throw new NoSuchElementException();
        }
    }
}

我遇到一个无限循环,打印5。因此,Iterator本身可以工作,但是我的方法存在逻辑错误。正在努力,但我感谢您的投入。 :)

UPDATE2

发现逻辑错误:NewLeft从不更改为null。努力解决它。

UPDATE3

:解决了! 具有嵌入式Iterator-Class的完全配对类和具有以下调用的主类:

public static void main(String[] args) {
        Pair<Integer> intPair= new Pair(5,1);
        Pair<String> stringPair=new Pair("foo", "bar");

        Iterator<Integer> itr= intPair.iterator();
        while(itr.hasNext()){
            System.out.println(itr.next());
        }
    }

主要:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Pair<T> implements Iterable<T> {

    private T left;
    private T right;

    public Pair(T left, T right){
        this.left = left;
        this.right = right;
    }

    public  T getRight(){return this.right;}
    public  T getLeft(){return this.left;}

    // size of a pair is always 2
    public int size =2;

    // own Iterator
    @Override
    public Iterator<T> iterator() {
        return new myIterator();
    }

    // embedded iterator class
    public class myIterator implements Iterator<T>{
        T newLeft = null;
        T newRight = null;

        @Override
        public boolean hasNext() {
            if(newLeft == null && getLeft() != null){
                return true;
            }
            else if(newLeft !=null && newRight == null){
                newRight=getRight();
                return getRight() !=null;
            }
            else {
                return false;
            }
        }
        @Override
        public T next() {
            if(newLeft == null && getLeft() != null){
                newLeft = getLeft();
                return newLeft;
            }
            else if(newLeft != null && getRight() != null){
                newRight = getRight();
                return newRight;
            }
            throw new NoSuchElementException();
        }
    }
}

谢谢大家的帮助,您使我找到了这个解决方案:)

2 个答案:

答案 0 :(得分:2)

您的初始代码正在定义变量<form #f="ngForm"> <app-input [name]="'name for password'" [name]="'name for password confirm'" [ngModel]="name" ngDefaultControl> </app-input> </form> ,其唯一目的是跟踪是否消耗了左值(由非T newLeft值指示)。使用null变量(即此处的boolean)会更加清晰。然后,很明显,该类是不完整的,因为它无法跟踪是否消耗了正确的值。

在您的固定代码中,您拥有boolean hasSeenLeft;newLeft,它们可以解决问题,但仍然具有误导性,因为它们的名称和类型均未表示实际用途。如果将它们更改为newRight变量,则可以设计它们以指示是否存在待处理的值,例如

boolean

更简单,更易读。

请注意,这两个解决方案都无法处理中间的更改,但是在最佳情况下,这个final class myIterator implements Iterator<T> { // no need to make this public boolean hasPendingLeft = getLeft() != null, hasPendingRight = getRight() != null; @Override public boolean hasNext() { return hasPendingLeft || hasPendingRight; } @Override public T next() { if(hasPendingLeft) { hasPendingLeft = false; return getLeft(); } else if(hasPendingRight) { hasPendingRight = false; return getRight(); } throw new NoSuchElementException(); } } 类看起来应该是不变的。在这种情况下,值得将Pairleft声明为right

对于可变类,值得在中间修改中添加快速失败行为,类似于Collection API:

final

因此,即使在错误的情况下,这仍然可以保证非final class myIterator implements Iterator<T> { // no need to make this public boolean hasPendingLeft = getLeft() != null, hasPendingRight = getRight() != null; @Override public boolean hasNext() { return hasPendingLeft || hasPendingRight; } @Override public T next() { if(hasPendingLeft) { hasPendingLeft = false; T left = getLeft(); if(left == null) throw new ConcurrentModificationException(); return left; } else if(hasPendingRight) { hasPendingRight = false; T right = getRight(); if(right == null) throw new ConcurrentModificationException(); return right; } throw new NoSuchElementException(); } } 值,然后将引发更有意义的异常。

答案 1 :(得分:1)

我猜您想迭代这对中的0到2个可能的值?在迭代器中,您应该引用T的实例。得到的消息是因为您试图以静态方式调用Pair中的方法(即,当Pair为The时,您正在调用Pair.getLeft()。课