如何在Java扫描器上“窥视”下一个元素?

时间:2022-09-23 07:46:58

That is, how do I get the next element of the iterator without removing it? As I may or may not want to remove it depending on its content. I have a file scanner where I iterate over XML tags using the Scanner next() method.

也就是说,如何获得迭代器的下一个元素而不删除它?因为我可能想删除它,也可能不想删除它,这取决于它的内容。我有一个文件扫描器,我使用next()方法迭代XML标记。

Thanks in advance.

提前谢谢。

6 个解决方案

#1


4  

See this answer for a more efficient solution.

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

This is a very ugly solution, but you can create a wrapper class around Scanner which keeps two internal Scanner objects. You can get peek() functionality by having the second scanner one ahead of the other

这是一个非常糟糕的解决方案,但是您可以围绕扫描器创建一个包装器类,它保留两个内部扫描器对象。您可以通过让第二个扫描器一个在另一个前面,来获得peek()功能

This is a very basic solution (just to give you an idea of what I'm talking about) and doesn't implement all that you would need (but you would only need to implement those parts you would use). (also, this is untested, so take it with a grain of salt).

这是一个非常基本的解决方案(只是为了让您了解我所说的内容),并且没有实现您需要的所有功能(但是您只需要实现您将使用的那些部分)。(同样,这是未经检验的,所以要带点盐。)

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;
    }
}

#2


13  

Here is another wrapper based solution, but this one has only one internal scanner. I left the other up to show one solution, this is a different, and probably better solution. Again, this solution doesn't implement everything (and is untested), but you will only have to implement those parts that you intend to use.

这是另一个基于包装器的解决方案,但是这个只有一个内部扫描器。我留下另一个来展示一个解,这是一个不同的,可能更好的解。同样,这个解决方案并没有实现所有的东西(并且没有经过测试),但是您只需要实现您想要使用的那些部分。

In this version you would keep around a reference to what the next() actually is.

在这个版本中,您将保留对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;
    }
}

#3


8  

I don't think there is a peek-like method, but you can use hasNext(String) to check if the next token is what you are looking for.

我不认为有类似于窥视的方法,但是您可以使用hasNext(String)检查下一个令牌是否是您要查找的。

#4


5  

There is a PeekingIterator in Google Guava: https://code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained#PeekingIterator

在谷歌Guava有一个窥视者:https://code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained#PeekingIterator

#5


0  

If the Iterator is a ListIterator you can do something like this:

如果迭代器是ListIterator,你可以这样做:

if(it.hasNext()) {
   if(it.next() ... 
   it.previous();
}

#6


0  

I don't know if this is how you're supposed to use a scanner, but you can use:

我不知道这是不是你应该使用的扫描仪,但是你可以使用:

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"

#1


4  

See this answer for a more efficient solution.

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

This is a very ugly solution, but you can create a wrapper class around Scanner which keeps two internal Scanner objects. You can get peek() functionality by having the second scanner one ahead of the other

这是一个非常糟糕的解决方案,但是您可以围绕扫描器创建一个包装器类,它保留两个内部扫描器对象。您可以通过让第二个扫描器一个在另一个前面,来获得peek()功能

This is a very basic solution (just to give you an idea of what I'm talking about) and doesn't implement all that you would need (but you would only need to implement those parts you would use). (also, this is untested, so take it with a grain of salt).

这是一个非常基本的解决方案(只是为了让您了解我所说的内容),并且没有实现您需要的所有功能(但是您只需要实现您将使用的那些部分)。(同样,这是未经检验的,所以要带点盐。)

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;
    }
}

#2


13  

Here is another wrapper based solution, but this one has only one internal scanner. I left the other up to show one solution, this is a different, and probably better solution. Again, this solution doesn't implement everything (and is untested), but you will only have to implement those parts that you intend to use.

这是另一个基于包装器的解决方案,但是这个只有一个内部扫描器。我留下另一个来展示一个解,这是一个不同的,可能更好的解。同样,这个解决方案并没有实现所有的东西(并且没有经过测试),但是您只需要实现您想要使用的那些部分。

In this version you would keep around a reference to what the next() actually is.

在这个版本中,您将保留对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;
    }
}

#3


8  

I don't think there is a peek-like method, but you can use hasNext(String) to check if the next token is what you are looking for.

我不认为有类似于窥视的方法,但是您可以使用hasNext(String)检查下一个令牌是否是您要查找的。

#4


5  

There is a PeekingIterator in Google Guava: https://code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained#PeekingIterator

在谷歌Guava有一个窥视者:https://code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained#PeekingIterator

#5


0  

If the Iterator is a ListIterator you can do something like this:

如果迭代器是ListIterator,你可以这样做:

if(it.hasNext()) {
   if(it.next() ... 
   it.previous();
}

#6


0  

I don't know if this is how you're supposed to use a scanner, but you can use:

我不知道这是不是你应该使用的扫描仪,但是你可以使用:

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"