简体   繁体   中英

Calling a method of an Object in a HashMap in Java

I have 2 classes: truck and sedan. When some action occurs, I want to add a sedan to the hashMap in Truck class. The map tells what Sedans are currently in the Truck's cargo. I don't want Truck and Sedan to know about each other so I have made a method in CarManager that Sedan can call which passes the id of the sedan and the id of the Truck that Sedan wants to be added to. Then CarManager will inform Truck that a Sedan wants to be added to the list. The issue is I don't know how CarManager will inform the Truck and what I should have in that addSedan method. I do have a HashMap in CarManager that has a collection of CarEntities. The Truck's addCar method cannot be accessed by CarManager since it isnt in the interface and I dont want to add it in the interface because not all CarEntity will use it. Can anyone help?

public interface CarEntity {
    String getId();
    double getSpeed();
    void move();
}

public class CarManager {
    private HashMap<String, CarEntity> hash = new HashMap<String, CarEntity>();
    public void addSedan(String carId, String truckId) {
    ???
    hash.get(truckId).addCarr(carId); //I don't think this will work
    }

}

public class Truck implements CarEntity { 
    private HashMap<String, CarEntity> cargo = new HashMap<String, CarEntity>();
    public void addCar(String id, CarEntity ce) {
        cargo.put(id,ce);
}

public class Sedan implements CarEntity {
    CarManager.addSedan("Car 1", "Truck 5");
}

If you may not use casts and instanceof and must use polymorphism, then add two methods to your CarEntity interface :

boolean canBeLoadedWithCars();
void addCar(CarEntity c) throws IllegalStateException;

The trucks can be loaded with cars, and thus implement the first methof by returning true. The other ones return false.

The addCar method of Truck adds the car to their map, whereas the other implementations throw an IllegalStateException because they can't be loaded with cars.

So the addCar method of the manager becomes

CarEntity truck = hashMap.get(truckId);
if (truck.canBeLoadedWithCars() {
    truck.addCar(sedan);
}

I guess one thing that you can do is

CarEntity t = hash.get(truckId); 
if (t instanceof Truck)
   downcast car entity to truck
   call add car method

The answer depends on who is doing the action. If the Sedan s add themselves to the truck then you should have an addTruck method which adds all of the trucks into the manager. The manager would store the Truck s in a Map .

private Map<String, Truck> trucks = new HashMap<String, Truck>();
public void registerTruck(Truck truck) {
    trucks.put(truck.getId(), truck);
}

Then the addCar() method on the manager would do:

public void addCar(String truckId, CarEntity car) {
    Truck truck = trucks.get(truckId);
    // null handling needed here
    truck.addCar(car);
}

If, instead, the trucks take the cars then you could register the cars instead. If you need to have both be by string id then you'll need to register both cars and trucks and do something like:

private Map<String, Truck> trucks = new HashMap<String, Truck>();
private Map<String, Sedan> sedans = new HashMap<String, Sedan>();

public void registerTruck(Truck truck) {
    trucks.put(truck.getId(), truck);
}
public void registerSedan(Sedan sedan) {
    sedans.put(sedan.getId(), sedan);
}

public void addSedan(String sedanId, String truckId) {
    Sedan sedan = sedans.get(sedanId);
    Truck truck = trucks.get(truckId);
    // null handling needed here
    truck.addCar(sedan);
}

Typically we use Java interfaces to accomplish the decoupling. The Truck class should be able to add a CarEntity to its load without knowing that it is a Sedan . In this case an addCar(CarEntity car) method on Truck sounds fine. The Sedan will never know it is on a Truck and all the truck knows are the methods exposed through the CarEntity interface. In this case maybe the manager goes away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM