Balkrishan Nagpal Balkrishan Nagpal - 1 month ago 13
Java Question

Understanding Scanner's findWithinHorizon method

I am trying to use and understand Java's

method.

I have written following piece of code which uses this method but I am not able to understand how it is working.

private static void findWithinHorizon() {
String string = "Balkrishan Nagpal --> 1111, 2222, 3333";
Pattern pattern = Pattern.compile("[0-9]+");

Scanner scanner = new Scanner(string);

while (scanner.hasNext()) {
System.out.println("scanner.findWithinHorizon(pattern) = " + scanner.findWithinHorizon(pattern, 26));
}
}


When I run the above method, I get the following output

scanner.findWithinHorizon(pattern) = 1111
scanner.findWithinHorizon(pattern) = 2222
scanner.findWithinHorizon(pattern) = 3333


but I would expect output to contain only

scanner.findWithinHorizon(pattern) = 1111


as I have provided the horizon value as 26.

My understanding is that while finding the matching result scanner won't go beyond index 26 in the string.

Can someone please explain how this is working?

Answer

From the JavaDoc it behaves as expected:

This method searches through the input up to the specified search horizon, ignoring delimiters. If the pattern is found the scanner advances past the input that matched and returns the string that matched the pattern. If no such pattern is detected then the null is returned and the scanner's position remains unchanged. This method may block waiting for input that matches the pattern.

A scanner will never search more than horizon code points beyond its current position.

After successfully finding 1111 the position is advanced to just after that match. The next findWithinHorizon call searches through a maximum of 26 characters after the first match.


scanner.hasNext() returns true if there is something else than whitespace after the current position. scanner.findWithinHorizon(pattern, 26) then searches the next 26 characters for the pattern and returns it (at the same time advancing the current position to just after the match).

So your code proceeds as follows:

  • Creating the scanner: the current position is 0.
  • scanner.hasNext() returns true, since the string contains not only whitespace.
  • scanner.findWithinHorizon(pattern, 26) searches for the pattern in the position range from 0 to 26, finds 1111 at positions 22 to 25, sets the new position to 26 and returns 1111
  • scanner.hasNext() returns true, since the string starting at position 26 contains not only whitespace
  • scanner.findWithinHorizon(pattern, 26) searches for the pattern in the position range 26 to 52, finds 2222 at positions 28 to 31, sets the new position to 32 and returns 2222
  • and so on...