0

I'm currently reading through a text file that looks something like this:

123 (1.0,4.4) (4,5)
4 (2,1) (6.1,7) (1,3) (1,2)
...
89122 (3,1) (56.1,1) (1.7,2)

It begins with a number followed by at least one pair of coordinates in the form (x,y). My goal: If one of the coordinates on the line matches what I'm looking for, I want to add the tag (the first number) to an arraylist and then break out of the loop right away. This is what I have so far:

ArrayList<Integer> matches = new ArrayList<Integer>();
BufferedReader reader = new BufferedReader(new FileReader(new File(args[0])));

String pattern =  "([0-9.]+),([0-9.]+)";
Pattern p = Pattern.compile(pattern);
Matcher m = null;
String line;
double x,y;

while((line = reader.readLine()) != null) {
    String[] temp = line.split(" ", 2);  //this splits the tag from the rest of the line, which are pairs of (x,y)
    m = p.matcher(temp[1]);
    while(m.find()) {
        x = Double.parseDouble(m.group(1));
        y = Double.parseDouble(m.group(2));

        if(x > 100 || y > 100) {
            matches.add(temp[0]);
            break; // ***this only breaks out of this single if, but what I really want is to break out of the m.find() while loop and get reader to read in the next line.
        }
    }
}

The problem I'm having is (* * *), commented out in the code above. How do I break out of the loop properly?

user3025403
  • 1,070
  • 3
  • 21
  • 33
  • 2
    possible duplicate of [Breaking out of nested loops in Java](http://stackoverflow.com/questions/886955/breaking-out-of-nested-loops-in-java) – AntonH Mar 13 '14 at 21:29
  • Consider switching to a language whose regex implementation supports multiple matches from the same group, such as C# – Nicola Musatti Mar 13 '14 at 21:35

4 Answers4

3

Use branching labels to direct the break statement to a specific loop

outer:
    while(....) {
        while(....) {
            if(....)
                break outer;
        }
    }

See also: Breaking out of nested loops in Java

Community
  • 1
  • 1
anttix
  • 7,709
  • 1
  • 24
  • 25
1

Label your loop

OUTER:while((line = reader.readLine()) != null) {
String[] temp = line.split(" ", 2);  //this splits the tag from the rest of the line, which are pairs of (x,y)
m = p.matcher(temp[1]);
INNER:while(m.find()) {
    x = Double.parseDouble(m.group(1));
    y = Double.parseDouble(m.group(2));

    if(x > 100 || y > 100) {
        matches.add(temp[0]);
        break INNER; // ***this breaks the loop named INNER
    }
}

}

blueygh2
  • 1,538
  • 10
  • 15
1

Well, you can break the outer loop by using labels, but it's a bad practice. You have two options here:

  • Isolate the find functionality in a separate method and do return instead of break (best approach since you'll be able to reuse the method later)
  • Declare a boolean found = false; variable, set it to true when you found the stuff you were looking for and then check it in the outer loop
dimoniy
  • 5,820
  • 2
  • 24
  • 22
  • Thanks for the informative answer. However, I've never heard of labeling loops before, so I'm going to try it even if it's bad practice. – user3025403 Mar 13 '14 at 21:42
1

Use a boolean flag:

boolean endLoop = false;
while(!endLoop && (line = reader.readLine()) != null) {
    String[] temp = line.split(" ", 2);  //this splits the tag from the rest of the line, which are pairs of (x,y)
    m = p.matcher(temp[1]);
    while(m.find()) {
        x = Double.parseDouble(m.group(1));
        y = Double.parseDouble(m.group(2));

        if(x > 100 || y > 100) {
            matches.add(temp[0]);
            endLoop = true; 
        }
    }
}
piokuc
  • 25,594
  • 11
  • 72
  • 102