我试图为自己的泛型类编写自己的迭代器。我一直在看几个YouTube教程,在网上搜索。
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();
}
}
}
IntelliJ指出的问题是,我不能像我试图的那样在迭代器类中使用getleft和getright,因为非静态方法不能从静态上下文中引用。我一直在研究静态和更多,但无法解决这个问题。我是完全走错了路,还是至少我的方法有点接近?
运行时:
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());
}
}
我遇到了一个无休止的循环,打印5。因此,迭代器本身可以工作,但我的方法有一个逻辑错误。为此而努力,但我感谢任何投入。:)
逻辑错误发现:新左派永远不会从空值改变。努力解决它。
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();
}
}
}
主要:
import java.util.Iterator;
public class main {
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());
}
Iterator<String> itrS= stringPair.iterator();
while(itrS.hasNext()){
System.out.println(itrS.next());
}
}
}
谢谢大家,谁帮助了我,你带领我找到了这个解决方案:)
我猜你想迭代这对中的0到2个可能的值?在你的迭代器中,你应该引用t的实例。你得到的消息是因为你试图以静态方式调用Pair中的一个方法(也就是说,当Pair是类时,你正在调用Pair.getLeft())
您的初始代码正在定义一个变量 T newLeft
,其唯一目的是跟踪左值是否已被使用,由非空
值指示。使用布尔
变量会更清晰,即布尔变量在这里看到左派
。然后,很明显,这个类是不完整的,因为它不跟踪是否使用了正确的值。
在您的固定代码中,您有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();
}
}
这更简单易读。
注意,这两种解决方案都不能处理中间的更改,但是这个< code>Pair类看起来在最好的情况下应该是不可变的。在这种情况下,值得将< code>left和< code>right声明为< code>final。
对于可变类,值得为中间修改添加一个快速失败行为,类似于集合API:
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();
}
}
因此,即使在错误的情况下,这仍然保证非空
值,并且会引发更有意义的异常。
如何将此迭代器与泛型类型一起使用?以下是我在“main”函数中尝试的方法: 结果是:<代码>无法从静态上下文引用非静态类项 结果是:<代码>无法从静态上下文引用非静态类项 结果: 编辑: 我调用的是类而不是方法。这项工作: 迭代器it=deq。迭代器(); 我认为,由于iterator()中返回的实例的类型是ListIterator,因此我需要使用该类型声明“it”。
我想创建一个自定义的树数据结构,只有节点,我可以迭代他们。然后,我可以扩展这个类,并有非常基本的树 我已经开始工作了,但是当我试图扩展Node类时,问题就来了。对于扩展类,继承的迭代器方法仍然返回节点迭代器,这意味着我每次都要强制转换。下面是我遇到的问题的一个基本示例。让我们建立一个包含整数的树: 是否有一种简单的方法可以解决这个问题,而不需要将iterator()方法从Node类复制到Integ
所以我有一个抽象类,它准备我的查询,直到after where子句。它看起来像这样: 然后返回,具体实现使用该实例向其添加内容。 是否可以让此通话返回
问题内容: 我有一个旧类,该类本身不是泛型,但其方法返回类型之一使用泛型: 使用泛型返回字符串的集合。因此,我可以进行遍历,而无需将元素强制转换为: 但是,如果我将自己更改为通用名称,但其他所有内容均保持不变: 然后继续使用对的非泛型引用,不再返回,而是返回非类型。因此,客户端代码无法编译: 为什么是这样?有哪些解决方法? 我的猜测是,通过使用对泛型类的非泛型引用,Java将关闭整个类的所有泛型。
问题内容: 我偶然发现了对Java继承的好奇心,我希望您对此提出更好的想法: 假设两个接口A和A1 接口A1扩展了A 接口A具有返回泛型类型的方法。 通用类型将是。 现在的基本思想是将这种通用返回类型从接口A中更改 为 接口A1中的 一开始似乎很容易(不好的事情会在以后出现) 我们将接口A声明为 和接口A1一样 如您所见,我们被迫编写接口A本身,以允许使用基于泛型的“子类”覆盖它。(实际上,gen
如何获取这个类的类型?对于上下文,我使用ModelMapper,我需要类类型T从S转换为T。 背景: 我已经尝试了N种方法,其中我放置了“//一些方法来获取类型”,但没有任何效果。例如: 或