如何"窥视"Java Scanner上的下一个元素?

Jua*_*tos 14 java iterator

也就是说,如何在不删除迭代器的情况下获取迭代器的下一个元素?因为我可能会或可能不想根据其内容删除它.我有一个文件扫描程序,我使用Scanner next()方法迭代XML标记.

提前致谢.

Ree*_*ore 17

这是另一种基于包装器的解决方案,但这只有一个内部扫描器.我离开了另一个以显示一个解决方案,这是一个不同的,可能更好的解决方案.同样,此解决方案并未实现所有内容(并且未经测试),但您只需实现您打算使用的那些部分.

在这个版本中,你会保留对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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*bbs 9

我不认为有类似peek的方法,但你可以使用hasNext(String)来检查下一个标记是否是你正在寻找的.


pop*_*str 7

Google Guava中有一个PeekingIterator:https: //code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained#PeekingIterator

  • Guava的"PeekingIterator"是这里最优雅的解决方案 - 它快速,经过良好测试,基本上是OP问题的单线解决方案. (2认同)

Dyl*_*guy 6

这是对所有其他问题的简单得多的答案。

\n\n

我们可以使用该match()方法检索 的最后一个匹配项hasNext,并查看第 0 个捕获组(这是正则表达式匹配的整个字符串——正是我们想要的)。

\n\n
Scanner s = \xe2\x80\x8bnew Scanner("a\\nb")\xe2\x80\x8b\xe2\x80\x8b\xe2\x80\x8b\xe2\x80\x8b\xe2\x80\x8b\xe2\x80\x8b;\n\ns.hasNext(".*"); // ".*" matches anything, similar to hasNext(), but updates the scanner\'s internal match variable\ns.match().group(0)\xe2\x80\x8b;\xe2\x80\x8b // returns "a"\n\ns.next() // returns "a"\n
Run Code Online (Sandbox Code Playgroud)\n


Ree*_*ore 4

请参阅答案以获得更有效的解决方案。

这是一个非常丑陋的解决方案,但您可以创建一个包装类,围绕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;
    }
}
Run Code Online (Sandbox Code Playgroud)