vendredi 26 mars 2021

Type safe container for Bipredicate

I have a design problem that I'm not sure how to solve. I've created an Evaluator class that evaluates a parsed expression. The expression is of shape amount > 50. The operator is used to understand which predicate must be created. Then, the LHS is sent to a different object to get its actual value. The value can be String, Integer, Double and more. My problem starts when I try to create the correcet predicate and initialise it with the proper values. I get warnings that it isn't type-safe, using a raw type etc. I'd like to solve this issue if I can and not suppress the warnings. My current thought is creating a container class which I named Value, that's generic. But I'm stuck on continuing this line of thought. My code:


public class Evaluator {
    static PredicateFactory predFactory = new PredicateFactory();


    public boolean evaluate(String[] expression, Data data){ // currently doesn't actually work, just testing
        BiPredicate predicate = predFactory.createPred(expression[1]);
        predicate.test(data.getAttribute(expression[0]), 50);
    }
}

public class PredicateFactory {


    public BiPredicate<?,?> createPred(String operator) {
        return switch (operator) {
            case "<" -> (BiPredicate<Double, String>) (i, j) -> i <  Double.parseDouble(j);
            case ">" -> (BiPredicate<Double, String>) (i, j) -> i >  Double.parseDouble(j);
            case "from domain" -> (BiPredicate<String, String>) (i, j) -> i.endsWith("@" + j);
            default -> null;
        };
    }

public class Value<T>{
    private T val;

    Value(T val){
        this.val = val;
    }

    public T getVal(){
        return this.val;
    }
}


public class Data {
    private int id;
    private int total_price;
    private String date;
    private String email;
   ....

    Data(int id, int price, String date, String email, ){
        this.id = id;
        this.total_price = price;
        this.date = date;
        this.email = email;
.....
    }

    public Value<?> getAttribute(String attribute){ 
        return switch(attribute){
            case "value" -> new Value<>((double) this.total_price);
            case "email" -> new Value<>(this.email);
            default -> null;
        };

    }
}


Thank you for any pointers

Aucun commentaire:

Enregistrer un commentaire