title: Interesting system.exit() behaviour and break behaviour - what is happening?
body: <p>I am trying to implement BFS as follows:</p>
  
  <pre><code>package search;
  
     import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.LinkedList;
  import java.util.Queue;
  
  import common.MyNode;
  import common.Parser;
  
  public class BFS extends Search {
  
      Queue&lt;MyNode&gt; frontier;
      Queue&lt;MyNode&gt; visited;
      ArrayList&lt;MyNode&gt; route;
      Parser p;
      boolean found = false;
      private int toWriteInt = 0;
      private double distance;
  
  public BFS(MyNode startNode, MyNode goalNode, Parser p) {
      super(startNode, goalNode, p);
      frontier = new LinkedList&lt;MyNode&gt;();
      visited = new LinkedList&lt;MyNode&gt;();
      this.p = p;
      route = new ArrayList&lt;MyNode&gt;();
  
  }
  
  public void Search() {
  
      visited.add(this.getStartNode());
  
      if (isGoal(this.getStartNode())) {
          System.out.println("goal found at start");
          goalFound();
      }
      ArrayList&lt;MyNode&gt; successors = this.getStartNode().getSuccessors();
  
      for (int i = 0; i &lt; successors.size(); i++) {
          successors.get(i).setParent(this.getStartNode());
          if (!(visited.contains(successors.get(i)))
                  &amp;&amp; !(frontier.contains(successors.get(i)))) {
              if (isGoal(successors.get(i))) {
                  visited.add(successors.get(i));
                  System.out.println("goal found at start successor");
  
                  goalFound();
                  break;
              } else {
                  frontier.add(successors.get(i));
  
              }
  
          }
  
      }
      while (!frontier.isEmpty()) {
          MyNode current = frontier.poll();
  
          ArrayList&lt;MyNode&gt; currentSuccessors = current.getSuccessors();
  
          visited.add(current);
  
          for (int i = 0; i &lt; currentSuccessors.size(); i++) {
  
              if (!(visited.contains(currentSuccessors.get(i)))
                      &amp;&amp; !(frontier.contains(currentSuccessors.get(i)))) {
                  currentSuccessors.get(i).setParent(current);
  
                  if (isGoal(currentSuccessors.get(i))) {
                      visited.add(currentSuccessors.get(i));
                      System.out.println("goal found in loop");
                      goalFound();
                      break;
                  } else {
                      frontier.add(currentSuccessors.get(i));
                  }
  
              }
  
          }
      }
  }
  
  private boolean isGoal(MyNode toCheck) {
      boolean goal = false;
      if (toCheck.equals(this.getGoalNode())) {
          goal = true;
      }
      return goal;
  
  }
  
  private void goalFound() {
      System.out.println("goal found with " + visited.size());
      printRoute();
      System.exit(0);
  
  }
  </code></pre>
  
  <p>This all works find. The print route method is as follows:</p>
  
  <pre><code>public void printRoute() {
          MyNode i = this.getGoalNode();
          while (i.getParent() != null) {
  
              System.out.println(i.getId());
              distance = distance
                      + Search.distFrom(i.getLat(), i.getLon(), i.getParent()
                              .getLat(), i.getParent().getLon());
  
              i = i.getParent();
  
          }
          System.out.println(this.startNode.getId());
  
  
          System.out.println("completed routing");
          System.out.println("path length of " + distance + "km");
      }
  </code></pre>
  
  <p>}</p>
  
  <p>Once again, this works fine and prints the correct route. However, If i remove the system.exit(0) the code does not work and the while loop of printRoute() will simply print forever, printing out the same two nodes twice (i and i.getParent()). I find this really strange, as the method must have completed to hit my system.exit.</p>
  
  <p>Can anyone tell me why this is? It's very problematic to have to call system.exit as i would like to embed BFS in my code and it means I cannot.</p>
  
  <p>thanks,
  MJB</p>
  
  <p>edit: It was suggested below that returning would fix my issue. Below is A* search that exhibits the same behaviour and only works if I System.Exit even though I return:</p>
  
  <pre><code>    package search;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Stack;
  
  import common.MyNode;
  import common.Parser;
  
  public class AStar extends Search {
  
      private ArrayList&lt;MyNode&gt; openList; // This is basically our frontier
      private ArrayList&lt;MyNode&gt; closedList;// This is the visited set.
  
      public AStar(MyNode startNode, MyNode goalNode, Parser p) {
          super(startNode, goalNode, p);
          openList = new ArrayList&lt;MyNode&gt;();
          closedList = new ArrayList&lt;MyNode&gt;();
  
      }
  
      public Stack&lt;MyNode&gt; Search() {
          Stack&lt;MyNode&gt; toReturn = new Stack&lt;MyNode&gt;();
          openList.add(this.getStartNode());
          while (!openList.isEmpty()) {
  
              Collections.sort(openList);
              MyNode q = openList.remove(0);
              openList.remove(q);
  
              // generate q's 8 successors and set their parents to q
              // if successor is the goal, stop the search
              if (isGoal(q)) {
                  System.out.println("search completed- goal found");
                  MyNode i = this.getGoalNode();
                  while (i.getParent() != null) {
                      toReturn.add(i);
                      i = q.getParent();
                  }
                  return toReturn;
              }
  
              closedList.add(q);
              ArrayList&lt;MyNode&gt; successors = q.getSuccessors();
  
              for (MyNode node : successors) {
                  if (closedList.contains(node)) {
                      continue;
                  }
  
                  node.setParent(q);
  
                  /*
                   * successor.g = q.g + distance between successor and q
                   * successor.h = distance from goal to successor
                   * successor.f=successor.g + successor.h
                   */
  
                  double g = q.getG()
                          + Search.distFrom(q.getLat(), q.getLon(),
                                  node.getLat(), node.getLon());
  
                  double h = Search.distFrom(this.getGoalNode().getLat(), this
                          .getGoalNode().getLon(), q.getLat(), q.getLon());
  
                  node.setG(g);
                  node.setH(h);
  
                  node.setF(g + h);
  
                  // if a node with the same position as successor is in the OPEN
                  // list
                  // has a lower f than successor, skip this successor
  
                  int openIndex = openList.indexOf(node);
                  int closedIndex = closedList.indexOf(node);
  
                  if (openIndex &gt; -1) {
  
                      if (openList.get(openIndex).compareTo(node) == -1)
                          continue;
  
                  }
  
                  // if a node with the same position as successor is in the
                  // CLOSED list
                  // which has a lower f than successor, skip this successor
                  if (closedIndex &gt; -1) {
                      if (closedList.get(closedIndex).compareTo(node) == -1)
                          continue;
  
                  }
  
                  if (openIndex &gt; -1)
                      openList.remove(openIndex);
                  Collections.sort(openList);
  
                  if (closedIndex &gt; -1)
                      closedList.remove(closedIndex);
  
                  openList.add(node);
                  Collections.sort(openList);
  
              }
              closedList.add(0, q);
  
          }
          return toReturn;
      }
  </code></pre>
  
  <p>edit: as requested, main method:</p>
  
  <pre><code>public static void main(String[] args) {
  
          AStar search = new AStar(parse.getAllNodes().get(new Long("21295291")),
                  parse.getAllNodes().get(new Long("319561075")), parse);
  
           search.Search();
  
      }
  </code></pre>
  
  <p>These nodes have the following attributes:</p>
  
  <pre><code>    node [id=21295291, lat=52.4737031, lon=-1.8747258]
  node [id=119126329, lat=52.4701337, lon=-1.8716235]
  </code></pre>