【发布时间】:2010-11-26 21:28:33
【问题描述】:
也就是说,如何在不移除迭代器的情况下获取下一个元素?因为我可能想也可能不想删除它,具体取决于它的内容。我有一个文件扫描器,我在其中使用 Scanner next() 方法迭代 XML 标记。
提前致谢。
【问题讨论】:
也就是说,如何在不移除迭代器的情况下获取下一个元素?因为我可能想也可能不想删除它,具体取决于它的内容。我有一个文件扫描器,我在其中使用 Scanner next() 方法迭代 XML 标记。
提前致谢。
【问题讨论】:
这是另一种基于包装器的解决方案,但这个解决方案只有一个内部扫描器。我留下另一个来展示一个解决方案,这是一个不同的,可能是更好的解决方案。同样,此解决方案并未实现所有内容(并且未经测试),但您只需实现您打算使用的那些部分。
在此版本中,您将保留对 next() 实际含义的引用。
import java.util.Scanner;
public class PeekableScanner
{
private Scanner scan;
private String next;
public PeekableScanner( String source )
{
scan = new Scanner( source );
next = (scan.hasNext() ? scan.next() : null);
}
public boolean hasNext()
{
return (next != null);
}
public String next()
{
String current = next;
next = (scan.hasNext() ? scan.next() : null);
return current;
}
public String peek()
{
return next;
}
}
【讨论】:
我认为没有类似 peek 的方法,但是您可以使用hasNext(String) 来检查下一个令牌是否是您要查找的。p>
【讨论】:
Google Guava 中有一个PeekingIterator,即documented。
【讨论】:
PeekingIterator 是这里最优雅的解决方案——它速度快,经过充分测试,本质上是解决 OP 问题的单行解决方案。
这是对所有其他人的简单得多的答案。
我们可以使用match() 方法检索hasNext 的最后一个匹配项,并查看第0 个捕获组(这是正则表达式匹配的整个字符串——正是我们想要的)。
Scanner s = new Scanner("a\nb");
s.hasNext(".*"); // ".*" matches anything, similar to hasNext(), but updates the scanner's internal match variable
s.match().group(0); // returns "a"
s.next() // returns "a"
【讨论】:
请参阅this 答案以获得更有效的解决方案。
这是一个非常丑陋的解决方案,但您可以围绕Scanner 创建一个包装类,它保留两个内部Scanner 对象。您可以通过将第二个扫描仪放在另一个前面来获得peek() 功能
这是一个非常基本的解决方案(只是为了让您了解我在说什么)并且没有实现您需要的所有内容(但您只需要实现您将使用的那些部分)。 (此外,这是未经测试的,因此请谨慎对待)。
import java.util.Scanner;
public class PeekableScanner
{
private Scanner scan1;
private Scanner scan2;
private String next;
public PeekableScanner( String source )
{
scan1 = new Scanner(source);
scan2 = new Scanner(source);
next = scan2.next();
}
public boolean hasNext()
{
return scan1.hasNext();
}
public String next()
{
next = (scan2.hasNext() ? scan2.next() : null);
return scan1.next();
}
public String peek()
{
return next;
}
}
【讨论】:
next() 对象的引用。
如果 Iterator 是 ListIterator,你可以这样做:
if(it.hasNext()) {
if(it.next() ...
it.previous();
}
【讨论】: