0

I was looking up alternatives to using instance of in java 8, since I wanted to call different classes based on the type of the input object. I came across a solution by Jhon Vester on dzone (https://dzone.com/articles/using-instanceof-and-alternatives-within-java ), where it was recommended that I can use Map<Class, Runnable>. Since I want to call a method which inputs an object and returns another object, I came across functional interfaces in java 8 and decided to use Map<Class,Function<T,R>> for the same.

Now from my understanding while using Function<T,R> with lambdas, the lambda is written as below:

(Parameter x of type T) -> return value of type R and given the definition of what abstract method apply should do

In my use-case this definition of abstract method is very long, it has a lot of business logics that I want to check in it and also call the DB within that method. So I am writing this method in another class (the service layer, since its part of an API). And when i try to put this in a map it does not work the map size remains 0.

I have tried to simplify my problem in the below code snippets: Train.class

public class Train {

public Integer getCostPerPassenger(DataTrain dataTrain){
    return dataTrain.getPriceTicket()/ dataTrain.getNoOfSeats();
}

}

DataTrain.class

public class DataTrain {
int priceTicket;
int noOfSeats;

public int getPriceTicket() {
    return priceTicket;
}

public void setPriceTicket(int priceTicket) {
    this.priceTicket = priceTicket;
}

public int getNoOfSeats() {
    return noOfSeats;
}

public void setNoOfSeats(int noOfSeats) {
    this.noOfSeats = noOfSeats;
}

}

Process.class

public class Process {
Train train = new Train();
private HashMap<Class, Function<DataTrain,Integer>> classFunctionHashMap = new HashMap<>();

public Integer getData(){
    DataTrain dataTrain = new DataTrain();
    dataTrain.setNoOfSeats(100);
    dataTrain.setPriceTicket(50);
    createMap();
    return classFunctionHashMap.get(Train.class).apply(dataTrain);
}

public HashMap<Class, Function<DataTrain,Integer>> createMap(){
    classFunctionHashMap.put(Train.class, (DataTrain data) -> train.getCostPerPassenger(data));
    return classFunctionHashMap;
}

}

In classFunctionHashMap.put is working as expected and even though the code is running , the size of the map remains 0.

I want to know how I can get this Map<Class,Fucnction<T,R> to get running? Is this the best way to approach the problem or are there better ways to implement the same.

Edit: The above code works perfectly, the issue was running the Junit for the code.

I have implemented an alternative method to achieve the same goal by using .getClass().getSimpleName().

if(train.getClass().getSimpleName().equals("Train")){ //call whatever method you want to }

My aim was to be able to identify the class.

Wasp98
  • 41
  • 6
  • *"the size of the map remains 0"* - how are you determining this? There's nothing in your code which checks the map's size. – kaya3 Jan 25 '21 at 13:19
  • I wrote unit test for the method and ran it in debug mode. This is a parallel simple example of the actual problem that I am facing. – Wasp98 Jan 25 '21 at 13:31
  • If you have a test which demonstrates the issue your question is about, then you should include that test in your question. You are expected to provide a [mcve] as this makes it easier for people to help you. – kaya3 Jan 25 '21 at 15:28

1 Answers1

0

The calculation in method getCostPerPassenger() is an Integer based division. Your example calculates 50/100, which is 0 in integer math.

I would also reommend, you make it a static method in class Train:

public class Train {
    public static Integer getCostPerPassenger(DataTrain dataTrain) {
        int result = dataTrain.getPriceTicket() / dataTrain.getNoOfSeats();
        return result;
    }
}

Then you can remove the Train instance from class Process and change the code in method createMap() to this:

public HashMap<Class, Function<DataTrain,Integer>> createMap(){
    classFunctionHashMap.put(Train.class, data -> Train.getCostPerPassenger(data));
    return classFunctionHashMap;
}
Andi80
  • 54
  • 4
  • Agreed on the flaws. But this is just a simple example of the real problem that I am facing. Essentially my aim is to call a particular method within a class based on the instance of the input class. This i am trying to achieve my populating a map and then get key (the class) of the map which will call the desired method – Wasp98 Jan 25 '21 at 13:44