То есть, как мне получить следующий элемент итератора без его удаления? Поскольку я могу или не хочу удалять его в зависимости от его содержимого. У меня есть сканер файлов, где я перебираю теги XML с помощью метода next() сканера.
Спасибо заранее.
То есть, как мне получить следующий элемент итератора без его удаления? Поскольку я могу или не хочу удалять его в зависимости от его содержимого. У меня есть сканер файлов, где я перебираю теги XML с помощью метода next() сканера.
Спасибо заранее.
См. этот ответ для более эффективного решения.
Это очень уродливое решение, но вы можете создать класс оболочки вокруг 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()
.
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;
}
}
Я не думаю, что есть похожий на подглядывание метод, но вы можете использовать hasNext (String), чтобы проверить, является ли следующий токен что вы ищете.
В Google Guava есть PeekingIterator: https://code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained#PeekingIterator
Здесь гораздо проще ответить на все остальные.
Мы можем использовать метод 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"
Если Iterator является ListIterator, вы можете сделать что-то вроде этого:
if(it.hasNext()) {
if(it.next() ...
it.previous();
}