程序在逐步调试时可以运行,但在运行时却不能正常工作。

5
我正在编写一个程序,用于显示如下所示的航班信息:
package d.airlineData.engine;

import java.time.Duration;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;

import a.airlineData.exceptions.NoFlightsException;
import c.airlineData.exceptions.NoAirportException;
import d.airlineData.graph.Airport;
import d.airlineData.graph.Flight;
import d.airlineData.graph.FlightGraph;

public class FlightGrapher {

    private FlightGraph fg;

    public FlightGrapher() throws NoFlightsException {      
        throw new NoFlightsException();
    }

    public FlightGrapher(ArrayList<Flight> flights) throws NoFlightsException  {
        fg = new FlightGraph();

        for(Flight flight: flights) {
            fg.addAirport(flight.getAirportA());
            fg.addAirport(flight.getAirportB());

            try {
                fg.addFlight(flight);
            } catch (NoAirportException e) {
                System.err.println(e.getMessage());
                e.printStackTrace();
            }
        }
    }

    public void printAll() {
        HashSet<Airport> airports = fg.getAirports();

        for(Airport airport : airports) {
            System.out.println(airport + ":");
            try {
                Iterator<Flight> it = fg.getFlightsFor(airport);
                while(it.hasNext()) {
                    System.out.println("\t" + it.next());
                    System.out.println();
                }

            } catch (NoAirportException e) {
                System.err.println(e.getMessage() + " while attempting to get flights for " + airport);
                e.printStackTrace();
            }
        }

    }
        public void printItinerary(Airport airportA, Airport airportB) {
    System.out.println("Leg\tLeave\t\tAt\tOn\tArrive\tAt");
    printItinerary(airportA,airportB, 1, 0.0, Duration.ofHours(0));
}

private void printItinerary(Airport airportA, Airport airportB, int leg, double totalPrice, Duration totalDuration) {
    Iterator<Flight> aFlights = airportA.getOutgoingFlights();
    System.err.println("Enters method printItinerary");
    System.err.println("airportA "  + airportA);
    System.err.println("airportB "  + airportB);
    System.err.println("leg " + leg);
    System.err.println("total price " + totalPrice);
    System.err.println("Duration " + totalDuration.toMinutes() + "mins");
    System.err.println();
    while(aFlights.hasNext()) {

        Flight currentFlight = aFlights.next();
        System.err.println("Enters while of printItinerary currentFlight: ");
        System.err.println(currentFlight);
        if(currentFlight.getAirportB().equals(airportB)) {

            System.out.println(leg + "\t" +
                    currentFlight.getAirportA() + "\t" +
                    currentFlight.getDepartureTime() + "\t" +
                    currentFlight.getFlightNumber() + "\t" +
                    currentFlight.getAirportB() + "\t" +
                    currentFlight.getArrivalTime());

            System.out.println();
            System.out.println("Total journey costs\t= £" + (currentFlight.getPrice() + totalPrice));
            System.out.println("Total time in air\t= " + (currentFlight.getFlightDuration().plus(totalDuration)));

            return;

        }else {
            System.err.println("enters else " + "currentFlight " + currentFlight.getAirportB() + " airport B " + airportB );
            System.err.println();
            if(hasAPath(currentFlight.getAirportB(), airportB)) {
                System.out.println(leg + "\t" +
                        currentFlight.getAirportA() + "\t" +
                        currentFlight.getDepartureTime() + "\t" +
                        currentFlight.getFlightNumber() + "\t" +
                        currentFlight.getAirportB() + "\t" +
                        currentFlight.getArrivalTime());

                printItinerary(currentFlight.getAirportB(), airportB, leg + 1, 
                        (currentFlight.getPrice() + totalPrice), 
                        (currentFlight.getFlightDuration().plus(totalDuration)));   
            }
        }
    }       
}

private boolean hasAPath(Airport airportA, Airport airportB) {
    System.err.println("Enters hasAPath with airportA " + airportA + " airportB " + airportB);
    Iterator<Flight> aFlights = airportA.getOutgoingFlights();
    while(aFlights.hasNext()) {
        Flight currentFlight = aFlights.next();
        System.err.println("Enters while of hasAPath currentFlight: ");
        System.err.println(currentFlight);
        if(currentFlight.getAirportB().equals(airportB)) {  
            System.err.println("returns true for airportA " + airportA + " airportB " + airportB );
            return true;            
        }else {
            System.err.println("Calls hasAPath with airportA " + currentFlight.getAirportB() + " airportB " + airportB);
            return hasAPath(currentFlight.getAirportB(), airportB);
        }

    }
    System.err.println("returns false for airportA " + airportA + " airportB " + airportB );
    return false;
}

    public static void main(String[] args) {
        ArrayList<Flight> flights = new ArrayList<>();
        HashMap<String, Airport> airports = new HashMap<>();

        airports.put("Edinburgh", new Airport("Edinburgh")); 
        airports.put("Heathrow", new Airport("Heathrow")); 
        airports.put("Amsterdam", new Airport("Amsterdam")); 
        airports.put("Boston", new Airport("Boston")); 
        airports.put("Montreal", new Airport("Montreal")); 
        airports.put("Chicago", new Airport("Chicago")); 
        airports.put("Toronto", new Airport("Toronto")); 
        airports.put("New Delhi", new Airport("New Delhi")); 
        airports.put("Shanghai", new Airport("Shanghai")); 
        airports.put("Hong Kong", new Airport("Hong Kong")); 

        flights.add(new Flight(airports.get("Edinburgh"),airports.get("Heathrow"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 110.0));

        flights.add(new Flight(airports.get("Heathrow"),airports.get("Amsterdam"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 100.0));

        flights.add(new Flight(airports.get("Heathrow"),airports.get("Boston"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 230.0));

        flights.add(new Flight(airports.get("Boston"),airports.get("Chicago"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 150.0));

        flights.add(new Flight(airports.get("Boston"),airports.get("Montreal"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 100.0));

        flights.add(new Flight(airports.get("Montreal"),airports.get("Toronto"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 90.0));

        flights.add(new Flight(airports.get("Edinburgh"),airports.get("Chicago"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 560.0));

        flights.add(new Flight(airports.get("New Delhi"),airports.get("Shanghai"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 430.0));

        flights.add(new Flight(airports.get("Shanghai"),airports.get("Hong Kong"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 230.0));


        Iterator<Entry<String,Airport>> airportIt = airports.entrySet().iterator();

        while(airportIt.hasNext()) {
            Entry<String, Airport> pair = airportIt.next();
            Airport airport = pair.getValue();
            for(Flight flight: flights) {
                if(flight.getAirportA().equals(airport)) {
                    airport.addOutgoingFlight(flight);
                }
            }
        }

        try {
            FlightGrapher fg = new FlightGrapher(flights);
            //fg.printAll();
            fg.printItinerary(airports.get("Edinburgh"), airports.get("Toronto")); // steps into this method
        } catch (NoFlightsException e) {
            System.err.println(e.getMessage() + " when trying to make a flight between a nonexistant airport");
            e.printStackTrace();
        }

    }

}

我遇到的问题是使用以下方法时:

printItinerary(Airport airportA, Airport airportB, int leg, double totalPrice, Duration totalDuration)

在正常运行时,程序由于某些原因没有执行,但是当我使用调试器逐步执行程序时,一切都可以正常执行,并且我获得了有意义的输出(格式不太好,但是我可以处理),为什么会发生这种情况?

输出应该是这样的:

Leg    Leave      At    On    Arrive    At
1      Edinburgh  10:30 BA345 Heathrow  11:30
2      Heathrow   14:00 BA657 Boston    15:30
3      Boston     18:00 AA652 Montreal  19:30
4      Montreal   22:00 AA216 Toronto   23:30

Total Journey Cost = £530
Total Time in the Air = 4 hrs 20 min

当我正常运行时,我得到了这个:

Leg    Leave      At    On    Arrive    At

当我逐步调试(或运行调试)时,会出现以下情况:

Leg     Leave           At      On      Arrive      At
1       Edinburgh       22:10   B7982   Heathrow          23:15
2       Heathrow        22:10   B7982   Boston      23:15
3       Boston  22:10   B7982   Montreal            23:15
4       Montreal        22:10   B7982   Toronto     23:15

Total journey costs = £530.0
Total time in air   = PT4H20M

我希望输出的是步进过程(格式稍后再处理)。

编辑:我已经在错误流中添加了一堆输出,这是当我运行它时的输出...由于某种原因它会停在“hasAPath”方法中:

Leg Leave       At  On  Arrive  At
Enters method printItinerary
airportA Edinburgh
airportB Toronto
leg 1
total price 0.0
Duration 0mins

Enters while of printItinerary currentFlight: 
Flight between Edinburgh & Chicago:
        For: £560.0
        Flight Number: B7982
        Leaves at: 22:10
        Arrives at: 23:15
        Duration: 1hr 5min
enters else currentFlight Chicago airport B Toronto

Enters hasAPath with airportA Chicago airportB Toronto
returns false for airportA Chicago airportB Toronto
Enters while of printItinerary currentFlight: 
Flight between Edinburgh & Heathrow:
        For: £110.0
        Flight Number: B7982
        Leaves at: 22:10
        Arrives at: 23:15
        Duration: 1hr 5min
enters else currentFlight Heathrow airport B Toronto

Enters hasAPath with airportA Heathrow airportB Toronto
Enters while of hasAPath currentFlight: 
Flight between Heathrow & Amsterdam:
        For: £100.0
        Flight Number: B7982
        Leaves at: 22:10
        Arrives at: 23:15
        Duration: 1hr 5min
Calls hasAPath with airportA Amsterdam airportB Toronto
Enters hasAPath with airportA Amsterdam airportB Toronto
returns false for airportA Amsterdam airportB Toronto

在这个时候,它应该返回出发点并检查下一班航班的hasAPath,下一班航班是波士顿和多伦多,然后检查所有波士顿出发的航班,看它们的机场是否与多伦多有连接...以此类推。


当我在使用Eclipse时,遇到了这种情况:在我的一个私有方法中添加新的sop(“Ankushy”)后,它没有在控制台上打印。首先,我查看了.class文件,发现其中并未包含新添加的代码行。然后,我尝试清理和重建项目,最终解决了问题。我建议您检查Java .class文件的工作空间输出位置。 - ankush yadav
我完全删除了该项目中使用的类文件夹,然后尝试清理项目...但并没有产生任何影响。 :( - James
1
你是否覆盖了Airport类的equals或哈希函数? - J Fabian Meier
不,我覆盖的唯一内容是toString。 - James
尝试通过java.util.Logger、Log4J或System.out.println将控制台输出添加到程序状态的信息中,以便在运行时获取程序状态。 - Pascal
1个回答

1
问题解决了。答案是,当你在调试模式下运行时,即使你返回了答案,它仍会运行所有可能性,这就是为什么它被评估为真并且起作用的原因。我将"has a path"方法从以下方式进行了更改:
private boolean hasAPath(Airport airportA, Airport airportB) {
    Iterator<Flight> aFlights = airportA.getOutgoingFlights();
    while(aFlights.hasNext()) {
        Flight currentFlight = aFlights.next();
        if(currentFlight.getAirportB().equals(airportB)) {         
            return true;            
        }else {             
            return hasAPath(currentFlight.getAirportB(), airportB);
        }

    }

    return false;
}

To this:

private boolean hasAPath(Airport airportA, Airport airportB) {
    Iterator<Flight> aFlights = airportA.getOutgoingFlights();
    while(aFlights.hasNext()) {
        Flight currentFlight = aFlights.next();
        if(currentFlight.getAirportB().equals(airportB)) {              
            return true;            
        }else {
            if(hasAPath(currentFlight.getAirportB(), airportB)) {
                return true;
            }else {
                continue;
            }
        }

    }
    return false;
} 

如果有其他人遇到这个问题,我建议在代码的每个块中都将输出放置到控制台,并跟踪发生了什么,调试模式下的执行模型必须与正常运行的模型不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接