Как "заглянуть" в следующий элемент на сканере Java?

То есть, как мне получить следующий элемент итератора без его удаления? Поскольку я могу или не хочу удалять его в зависимости от его содержимого. У меня есть сканер файлов, где я перебираю теги XML с помощью метода next() сканера.

Спасибо заранее.

Ответ 1

См. этот ответ для более эффективного решения.

Это очень уродливое решение, но вы можете создать класс оболочки вокруг 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;
    }
}

Ответ 2

Вот еще одно решение на основе обертки, но у этого есть только один внутренний сканер. Я оставил другой, чтобы показать одно решение, это другое и, вероятно, лучшее решение. Опять же, это решение не реализует все (и не проверено), но вам нужно будет только реализовать те части, которые вы собираетесь использовать.

В этой версии вы бы оставили ссылку на то, что на самом деле есть 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

Я не думаю, что есть похожий на подглядывание метод, но вы можете использовать hasNext (String), чтобы проверить, является ли следующий токен что вы ищете.

Ответ 5

Здесь гораздо проще ответить на все остальные.

Мы можем использовать метод match(), чтобы получить последнее совпадение hasNext и посмотреть на 0-ую группу захвата (которая является всей строкой, совпадающей с регулярным выражением - именно то, что мы хотим).

Scanner s = ​new Scanner("a\nb")​​​​​​;

s.hasNext(".*"); // ".*" matches anything, similar to hasNext(), but updates the scanner internal match variable
s.match().group(0)​;​ // returns "a"

s.next() // returns "a"

Ответ 6

Если Iterator является ListIterator, вы можете сделать что-то вроде этого:

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