обновить значения динамически? - PullRequest
0 голосов
/ 22 сентября 2011

Так что мне нужно написать программу, которая будет принимать формулы от пользователя и вычислять их.

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

Но теперь, допустим, я изменяю значения и хочу, чтобы столбец формулы динамически обновлялся. Есть ли способ сделать это? Я храню каждой строкой в ​​списке массивов, который является списком массивов списка массивов. Любой совет или руководство будет очень полезно, спасибо :)

Ответы [ 4 ]

0 голосов
/ 22 сентября 2011

Если честно, я буду использовать больше ОО манеры, пожалуйста, посмотрите:

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();
    // }

}

Я бы также сделал объект Parameter и Equation неизменным, если есть необходимость изменения, я сделаю другой объект уравнения, но если это требование, вы можете написать метод в Equation для добавления / установки Parameter s. Set будет обрабатывать их правильно, если они будут иметь одинаковые идентификаторы.

0 голосов
/ 22 сентября 2011

Возможно, вы захотите написать прослушиватель событий для этих массивов.С документацией можно ознакомиться здеськод).Если это домашнее задание или действительно маленький проект, вы можете использовать этот подход, иначе я бы предложил написать слушателя.

0 голосов
/ 22 сентября 2011

Мы можем пересмотреть это, чтобы сделать простой движок

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

}

Имея это, мы можем определять различные функции и вычисления

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
}

Проблема возникает, когда вы пытаетесь сделатьэто не только пользователь, но и пользователь.Например, пользователь может определить функцию как одну из набора функций, которые вы предварительно ввели.В этом случае вам понадобится парсер, который превращает что-то вроде этого:

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

в следующее:

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

Но это может выходить за рамки вашего задания.Или, может быть, это не так.

Надеюсь, это немного ближе к вашим требованиям, чем мой предыдущий пример.

0 голосов
/ 22 сентября 2011

Возможно, вы захотите использовать один из нескольких механизмов вычисления выражений вместо ArrayLists. Вы можете увидеть Expr4J или BIRT для возможных решений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...