开发者

update values dynamically ?

So I have to write a program that will take formulas from the user and calculate them.

    Age, Height, fights, (age+height)*fights <- user defined
    10, 5, 10, 150 <- I calculate this 
    1, 2, 1, 3 <- I calculate this 

But now let say I change the values around and I开发者_开发知识库 want the formula column to update dynamically is there anyway to go about doing that ? I am storing by each row into an array list which is array list of array list. Any advice or guidance would be really helpful thank you :)


We can revise this to make a simple engine

public interface Function<T> {
    T operate(Map<String,T> values);
}

public class Calculation<T> {

     private Map<String,T> values;

     private Function<T> function;

     public Calculation(Map<String,T> values, Function<T> function) {
         this.values = new HashMap<String,T>(values);
         this.function = function;
     }

     public T calculate() {
         return function.operate(Collections.unmodifiableMap(values));
     }

     // assume setters and getters are in place to manipulate the backing map and the functor object

}

With this in place, we can define various functions and calculations

public static void main(String[] args) {
    Function<Integer> original = new Function<Integer>() {
        public Integer operate(Map<String,Integer> values) {
            // these will throw exceptions if they don't exist, which is desired
            // granted it's NullPointerException instead of IllegalStateException, but close enough for this example
            int age = values.get("age").intValue();
            int height = values.get("height").intValue();
            int fights = values.get("fights").intValue();
            return (age+height)*fights;
        }
    };
    Map<String,Integer> map = new Map<String,Integer>();
    map.put("age",10);
    map.put("height",100);
    map.put("fights",25);
    Calculation<Integer> calc = new Calculation<Integer>(map,original);

    // later someone can replace either the values in the backing map
    // or replace the function altogether to get a new function
}

The problem comes when you try to make it not only user defined, but user entered. As in, a user could define the function as being one of a set of functions you have pre-entered. In this case, you'll need to have a parser that turns something like this:

value + (other + (something * that)) / wazook

into this:

EquationBuilder<Integer> eb = new EquationBuilder<Integer>();
eb.append(map.get("value"));
eb.append(OPERATOR.PLUS);
// etc
return eb.evaluate();

But that may be beyond the scope of your assignment. Or maybe it's not.

Hopefully this is a little closer to your requirements than my previous example.


You might want to look at using one of a number of expression calculation engines instead of ArrayLists. You can see Expr4J or BIRT for possible solutions.


You might want to write an event listener for those arrays. Documentation can be found here http://download.oracle.com/javase/tutorial/uiswing/events/listdatalistener.html

An easier solution is to write a simple method that computes the formula and call it from each portion of the program that triggers a change in the list values (but this solution can clutter the code). If this is a homework or really small project you can go with this approach otherwise I would suggest writing a listener.


To be honest I'll use more OO manner, please take a look:

public class Parameter {
    private String id;
    private Number value;

    public Parameter(String id, Number value) {
        this.id = id;
        this.value = value;
    }

    public String getId() {
        return id;
    }

    public Number getValue() {
        return value;
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Parameter) {
            Parameter parameter = (Parameter) obj;
            return id.equals(parameter.getId());
        }

        return super.equals(obj);
    }

}

public class Equation {
    private String formula;
    private Set<Parameter> parameters;

    public Equation(String formula, Parameter ... parameters) {
        this.formula = formula;
        this.parameters = new HashSet<Parameter>();
        for(Parameter parameter : parameters) {
            this.parameters.add(parameter);
        }
        validatePresenceOfAllParameters();
    }

    private void validatePresenceOfAllParameters() {
        // here you parse formula and check if all parameters are present
    }

    public Number doTheMagic() {
        Number result = null;
        // here you do the all magic related to equation and its parameters
        return result;
    }

    // public void setParameter(Parameter parameter)  {
    //  parameters.add(parameter);
    //  validatePresenceOfAllParameters();
    // }

}

I would also make Parameter and Equation object immutable, if there is a necessity of change I'll make another equation object but if this is the requirement you could write method in Equation for adding/setting Parameter's. Set will handle them properly if they will have same id's.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜