Reputation: 333
for ( Route r : timetable.keySet())
{
for (Station s: r?) //compile error here.
}
Hi all, basically I'm trying to write a method that adds stations to a combobox from a timetable. The timetable is essentially a hashmap that returns a Route, List(of type service), and a route is definined by a string representing the name of the route, and
// a list of stations visited on this route
private ArrayList<Station> stations;
Basically I need to access the stations in the route so I'm using a foreach loop to get each route in the timetable and then trying to get all the stations in that route, but I'm not sure how I would do the second nested loop, as in which list should I be referring to as I am getting a compile error if I refer the route.
I cannot modify the Route class, as that has been provided and I need to work around that but it does have this method to return the stations
public Station getStop(int i) {
if (i < 1 || i > stations.size()) {
throw new NoSuchStopException("No " + i + "th stop on route" + this);
}
return stations.get(i - 1);
}
Upvotes: 0
Views: 570
Reputation: 11832
You could achieve a solution as follows but it doesn't use nested for-each loops since it requires catching the exception to know when there are no more stations for that route (this solution does not require any changes to the Route class):
for ( Route r : timetable.keySet())
{
int stationIndex = 1;
try {
do {
Station station = route.getStop(stationIndex++);
// todo - put the station in the combo box
} while(true);
} catch(NoSuchStopException nsse) {
// we have reached the index where there wasn't a stop, so move to the next route
}
}
Upvotes: 1
Reputation: 79838
You could write this as
for ( Route r : timetable.keySet()) {
for (Station s: r.getStations()) {
// ...
}
}
provided the Route
class has a method like
public List<Station> getStations() {
return Collections.unmodifiableList(stations);
}
Note the use of unmodifiableList
. This prevents someone from writing code that calls getStations
and then modifies the result. Basically, it should be impossible to use a "getter" method to modify a class; hence using the various "unmodifiable" wrapper methods in the Collections
class is best practice for a getter that returns a collection.
Edit
Dealing with the new requirement of not being able to change Route
, and assuming that there is a method getNumberOfStops
as well as the getStop
of the question, you could write
for (Route r : timetable.keySet()) {
for (int stopNumber = 1; stopNumber <= r.getNumberOfStops(); stopNumber++) {
Station s = r.getStop(stopNumber);
// ...
}
}
Upvotes: 0
Reputation: 2952
Explanation of for each loop
for(XXX a : YYY)
YYY --- > should be any class that implements iterable
and XXX objects should be in YYY
Upvotes: 0
Reputation: 41200
for-each
loop iterate collection or array type and Route
object r
is not iterable type that is why it raised compiler error.
for ( Route r : timetable.keySet()){
for (Station s: r.getStations()){ // Get the station List from route object
...
}
}
Note: assumed there must be getter method of stations
in Route
class.
Upvotes: 0
Reputation: 34146
You will have to modify the class Route
and add a getter method that returns the ArrayList
(because it's private
):
public class Route {
// ...
public List<Station> getStations()
{
return stations;
}
}
Then you can use that method in the for
loop:
for (Route r : timetable.keySet()) {
for (Station s : r.getStations()) {
// ...
}
}
Edit: As @DavidWallace mentioned, if you don't want someone to modify the ArrayList
through the getter method, you can return an unmodifiableList
:
return Collections.unmodifiableList(stations);
Upvotes: 2