I need an Expression Evaluator that can allow me to evaluate an expression such as follows:
(ItemWeight + PackageWeight) * 2
So, given the following Input:
ItemWeight = new Weight(2.0, LBS);
PackageWeight = new Weight(0.2, LBS);
Output would be: Weight(4.4, LBS)
public class Weight {
private final float value;
private final Unit unit;
public float getValue() { return value; }
public Unit getUnit() { return unit; }
public enum Unit {
LB, KG, GRAMS;
}
}
Similarly, I'd like to add/subtract two Amount objects (where amount is made up of a value and currency symbol).
Note: It is OK in my use case to assume that two values that do not have the same unit cannot be added/subtracted, etc
I read about MVEL, but it didn't seem like MVEL would be able to handle arithmetic expressions involving POJOs. Other options that came to mind are Rhino and Commons EL.
What would be a good library that I can use (and if needed extend) for solving this problem?
Thanks!
Java isn't C++; you can't overload operators.
It might not be quite as visually appealing to do it using a fluent interface, but I would say it's easier than what you're proposing.
This is interesting, because you're going to have to think about more than just EL. The idea is far more general than your Weight class. It's more like QuantityWithUnits. Here are a few of the questions you'll have to answer:
How will you prohibit addition and subtraction operations on objects with differing units?
How will you account for creating new units when you divide and multiply?
Will you allow scalar multiplication and division?
Will you disallow addition of scalars to quantities with units? Or will you silently create new objects with like units behind the scenes?
Will you have other common physics operations like powers?
How will you work with systems of units and conversions?
You may think "I'm too clever for all that; I just want to do something 'simple and practical'", but eventually you'll have to answer all these.
Related
I can't find any information on this anywhere and was wondering whether such a use of a class is considered bad practise or not.
Let me explain. I have a class ToDecimalConverter which converts an integer from any base to decimal. However, I now need to add the functionality to also convert fractions. As such, I abstracted the integer conversion into a separate class and created a new class with the purpose of converting fractions. (Code isn't finished so I just added some comments to explain)
public class ToDecimalConverter {
private IntegerToDecimalConverter integerConverter;
private DoubleToDecimalConverter doubleConverter;
public double convert(String number, int baseNumber) {
this.integerConverter = new IntegerToDecimalConverter();
this.doubleConverter = new DoubleToDecimalConverter();
number = this.removeZerosAtBeginningOfNumber(number);
// split the number into integer and fraction so they can be used below:
int decimalInt = this.integerConverter.convert(integerNumber, baseNumber);
double decimalDouble = this.doubleConverter.convert(fractioNumber, baseNumber);
// add them together and return them
}
}
Now, except for the methods that remove the zero's from the start of a number and the method that splits the number into integer and fraction (both of which can easily be abstracted into their own class), the ToDecimalConverter class does nothing but group the integer and fraction converters together.
When searching online, I don't see a lot of classes being used like this. Should this be avoided or not? and if so, what are alternatives?
This meant as a more general question, the above is just to explain what I mean.
Edit: Or should I see it as a sort of mini GoF Facade pattern?
There is nothing wrong with it by default, but I would guess that you could achieve the same result with two methods. something like:
public int convertFromInt(String number, int baseNumber) {
int theConvertedInt = 0;
//Really cool convertion
return theConvertedInt;
}
public double convertFromFraction(String number, int baseNumber) {
double theConvertedInt = 0;
//Really cool convertion
return theConvertedInt;
}
Also, keep in mind that a lot of this conversions are already done by Java native classes like BigInteger, BigDecimal, Integer, Decimal, Double, the Math package and so on.
Not going into the specifics of what your class is doing, there indeed value in grouping several or many function/classes together to from a single unified API.
This is called the Facade design pattern.
The intent is that instead of relying on your client to have to know of the various classes/objects you use internally to achieve a feature and to have to look all over the place inside your implementation code is that you put in place a single entry point for given feature/set of feature. It is much better for discoverability & documentation.
Also this way, you ensure to only provide the public API that is only one or a few classes that make the facade while the implementation remains hidden and can change at any time.
The question is on the strategy approach to the problem of defining a square root algorithm in a generic numerical interface. I am aware of the existance of algorithms solving the problem with different conditions. I'm interested in algorithms that:
Solves the problem using only selected functions;
Doesn't care if the objects manipulated are integers, floating points or other, provided those objects can be added, mutiplied and confronted;
Returns an exact solution if the input is a perfect square.
Because the subtlety of the distintion and for the sake of clarity, I will define the problem in a very verbose way. Beware the wall text!
Suppose to have a Java Interface Constant<C extends Constant<C>> with the following abstract methods, that we will call base functions:
C add(C a);
C subtract(C a);
C multiply(C a);
C[] divideAndRemainder(C b);
C additiveInverse();
C multiplicativeInverse();
C additiveIdentity();
C multiplicativeIdentity();
int compareTo(C arg1);
Is not known if C represents an integer or a floating point, nor this must be relevant in the following discussion.
Using only those methods is possible to create static or default implementation of some mathematical algorithm regarding numbers: for example, dividerAndRemainder(C b); and compareTo(C arg1); allow to create algorithms for the greater common divisor, the bezout identity, etc etc...
Now suppose our Interface has a default method for the exponentiation:
public default C pow(int n){
if(n < 0) return this.additiveInverse().pow(-n);
if(n == 0) return additiveIdentity();
int m = n;
C output = this;
while(m > 1)
{
if(m%2 == 0) output = output.multiply(output);
else output = this.multiply(output.multiply(output));
m = m/2;
}
return output;
}
The goal is to define two default method called C root(int n) and C maximumErrorAllowed() such that:
x.equals(y.pow(n)) implies x.root(n).equals(y);
C root(int n); is actually implemented using only base functions and methods created from the base functions;
The interface can still be applied to any kind of numbers, including but not limiting at both integers and floating points.
this.root(n).pow(n).compareTo(maximumErrorAllowed()) == -1 for all this such that this.root(n)!=null, i.e. any eventual approximation has an error minor than C maximumErrorAllowed();
Is that possible? If yes, how and what would be an estimation of the computational complexity?
I went through some time working on a custom number interface for Java, it's amazingly hard--one of the most disappointing experiences I've had with Java.
The problem is that you have to start over from scratch--you can't really re-use anything in Java, so if you want to have implementations for int, float, long, BigInteger, rational, Complex and Vector you have to implement all the methods yourself for every single class, and then don't expect the Math package to be of much help.
It got particularly nasty implementing the "Composed" classes like "Complex" which is made from two of the "Generic" floating point types, or "Rational" which composes two generic integer types.
And math operators are right out--this can be especially frustrating.
The way I got it to work reasonably well was to implement the classes in Java and then write some of the higher-level stuff in Groovy. If you name the operations correctly, Groovy can just pick them up, like if your class implements ".plus()" then groovy will let you do instance1+instance2.
IIRC because of being dynamic, Groovy often handled cross-class pieces nicely, like if you said Complex + Integer you could supply a conversion from Integer to complex and groovy would promote Integer to Complex to do the operation and return a complex.
Groovy is pretty interchangeable with Java, You can usually just rename a Java class ".groovy" and compile it and it will work, so it was a pretty good compromise.
This was a long time ago though, now you might get some traction with Java 8's default methods in your "Number" interface--that could make implementing some of the classes easier but might not help--I'd have to try it again to find out and I'm not sure I want to re-open that can o' worms.
Is that possible? If yes, how?
In theory, yes. There are approximation algorithms for root(), for example the n-th root algorithm. You will run into problems with precision, however, which you might want to solve on a case-by-case basis (i. e. use a look-up table for integers). As such, I'd recommend against a default implementation in an interface.
What would be an estimation of the computational complexity?
This, too, is implementation varies based on your type of number, and is dependant on your precision. For integers, you can create an implementation with a look-up table, and the complexity would be O(1).
If you want a better answer for the complexity of the operation itself, you might want to check out Computational complexity of calculating the nth root of a real number.
I have property file(key/value) pair from where I currently read a value against a key and display that value as it is in the UI .
The complexity have increased,Now the value is more dynamic based on some formula. The formula includes a variable parameter whose value I will get at run time.
Is there any java design pattern to design this scenario .
I was thinking to put a method name in the property file against a key.
Now I will read the key and fetch the method name . This method will calculate the value for that particular key.
Please let me know your suggestion
Is there any java design pattern to design this scenario .
I don't know if there is a pattern.
If I understand your question right I can explain what I do usually.
Insert localizable strings in my properties values
I usually use #number#
Replace it later when variables are resolved
Little example:
messages.properties
name.of.key = sum of #0# + #1# = #2#
Then I read the value from and replace the #num# with appropiated values (NOTE: here is in the same method for shortenes, but I use an external replace method):
public void printSum(int n1, int n2) {
String myString = messageSource("name.of.key", Locale.getDefault(), null, null));
myString.replace("#0#", String.valueOf(n1));
myString.replace("#1#", String.valueOf(n2));
myString.replace("#2#", String.valueOf(n1+n2));
System.out.println(myString);
}
OUTPUT printSum(1,2);
sum of 1 + 2 = 3
Looks like the ANTLR would make here a great fit.
It is a parser generator. You give it grammar as an input and in return it provides you with a parser.
You can use the parser to transform the textual formula into a parsed tree representation. After that, you can run a visitor to evaluate each of the nodes. You just write some simple function to implement the behavior, such as:
public Double visitAdd(AntlrNode left, AntlrNode right) {
Double left = visit(left);
Double right = viist(right);
return left + right;
}
The grammar is very close to the familiar BNF notation. You just describe how your formula strings are. For example:
formula : left '+' right;
left: Number;
right: Number;
Number: [0-9]+;
Use Java built-in JavaScript engine to evaluate expressions. To match the spirit more closely, you can use JSON for properties.
If security is important, you need to provide the class filter. It can be very simple and restrictive as you only need to evaluate trivial expressions. The example on class filter can be found here.
You can use the strategy pattern putting the method/algorithm name in the property file:
public interface IFormula{
public int formula(int a, int b);
}
public class Sum implements IFormula{
public int formula(int a, int b){
return a+b;
}
}
Then you can select the method getting the name from a property file:
public static Strategy getStrategy(Name name) {
switch (name) {
case SUM:
return new Sum();
...
}
}
Another solution is to refactor your map so that the value type is a functional interface whose method accepts an arbitrary parameter. For example:
#FunctionalInterface
interface ValueType<R> {
R eval(Object param);
}
This solution (or a variant of it) would enable you to associate a lambda with your keys rather than a fixed value. The performance of a lambda ought to be much better than a run-time parser while still affording you the flexibility to make the associated value depend upon a run-time argument.
This solution should also be less vulnerable to injection attacks than a solution based on run-time parsing.
Since you seem to want a name for the pattern... the pattern is called: Domain Specific Language.
And again if you want to remain in the realms of abstract patterns and design you can peruse Martin Fowlers discussion on the topic at length.
Needless to say their are a metric ton of tools that solve the above pattern (including some of the answers here).
The other pattern which I highly recommend you NOT do is use a general purpose language that has an evaluator (ie Javascript, EL, Groovy, etc). This generally has security issues and performance issues (of course there are exceptions).
Consider a java project doing lots of floating point operations where efficiency and memory consumption can be important factors - such as a game. If this project targets multiple platforms, typically Android and the desktop, or more generally 32 and 64 bit machines, you might want to be able to build a single and a double precision build of your software.
In C/C++ and other lower level languages, this is easily achieved by typedef statements. You can have:
typedef float myfloat;
and the day you want to go 64 bit just change that to:
typedef double myfloat;
provided you use myfloat throughout your code.
How would one achieve a similar effect in java?
A global search and replace of "float" by "double" (or vice-versa) has the huge drawback of breaking compatibility with exterior libraries that only offer one flavor of floating point precision, chief among them certain functions of the java.lang.Math class.
Having a high-level polymorphic approach is less than ideal when you wish to remain efficient and keep memory tight (by having lots of primitive type arrays, for instance).
Have you ever dealt with such a situation and if so, what is in your opinion the most elegant approach to this problem?
The official Android documentation says this about float vs. double performance:
In speed terms, there's no difference between float and double on the more modern hardware. Space-wise, double is 2x larger. As with desktop machines, assuming space isn't an issue, you should prefer double to float.
So you shouldn't have to worry about performance too much. Just use the type that is reasonable for solving your problem.
Apart from that, if you really want to have the ability to switch between double and float, you could wrap your floatin point value in a class an work with that. But I would expect such a solution to be slower that using any floating point primitive directly. As Java does not support overloading operators, it would also make your math code much more complicated. Think of something like
double d = (a+b)/c;
when using primitives versus
MyFloat d = a.add(b).div(c);
when working with wrapper objects. According to my experience, the polymorphic approach makes maintaining your code much harder.
I will omit the part saying that for example double should be just fine etc. Others covered that more than good. I'm just assuming you want to do it - no matter what. Even for the sake of experiment to see what's the performance/memory difference - it's interesting.
So, a preprocessor would be great here. Java doesn't provide one.
But, you can use your own. Here are some existing implementations. Using javapp for example, you will have #define.
This is not practical without great pains.
While you could define your high level API's to work with wrapper types (e.g. use Number instead of a specific type and have multiple implementations of the API that uses Float or Double under the hood), chances are that the wrappers will eat more performance than you can ever gain by selecting a less precise type.
You could define high level objects as interfaces (e.g. Polygon etc.) and hide their actual data representation in the implementation. That means you will have to maintain two implementations, one using float and one for double. It probably requires considerable code duplication.
Personally, I think you are attempting to solve a non-existant conundrum. Either you need double precision, then float isn't an option, or float is "good enough", then there is no advantage of ever using double.
Simply use the smallest type that fits the requirements. Especially for a game float/double should make little difference. Its unlikely you spend that much time in math (in java code) - most likely your graphics will determine how fast you can go.
Generally use float and only switch to double for parts where you need the precision and the question disappears.
Java does not have such a functionality, aside from brute-force find-and-replace. However, you can create a helper class. Shown below, the type you will change to change the float precision is called F:
public class VarFloat {
F boxedVal;
public VarFloat(F f){
this.boxedVal = f;
}
public F getVal() { return boxedVal; }
public double getDoubleVal() { return (double)boxedVal; }
public double getFloatVal() { return (float)boxedVal; }
}
Where at all possible, you should use getVal as opposed to any of the type-specific ones. You can also consider adding methods like add, addLocal, etc. For example, the two add methods would be:
public VarFloat add(VarFloat vf){
return new VarFloat(this.boxedVal + vf.boxedVal);
}
public VarFloat addLocal(VarFloat vf){
this.boxedVal += vf.boxedVal;
return this; // for method chaining
}
Is it possible to use some construct to replace all floats with doubles (or the opposite) without refactoring?
For example you may be implementing some mathematical system that works perfectly interchangeably with floats or doubles. In C you may use: typedef float real and then use real in your code. Changing to double involves only replacing one line of code.
Is something like this possible in Java? Or is there some generic numeric type?
This is not possible in Java in the straightforward case which you describe. However, depending on how your code works, you could write your math classes to interfaces, and have all methods that return values be implemented with both a double and a float return type. Then, you could write two implementation classes, and switch between them depending on which one you wanted to use.
This seems like overkill. Why do you want to do this?
It's actually recommended to use BigDecimal instead of float/double. Don't think java has something similar to typedef float real
No, there is no way to achieve this in Java with primitive types. There is simply no typedef equivalent and there are also no template classes. From a functional view, you could work this with the object oriented way, the methods would take a wrapper class/interface type (something like java.lang.Number) and also return results as a wrapped type.
However, I would just scrap the entire idea and only implement the double version. Callers that want to work with float can just use the double version of any method - parameters will be automatically widened to double. The results then need to be cast back to float by the caller. The conversions to and from double will cost a little speed. Or if double was just nice to have and you can make do with float, create only a float version.
In terms of raw computation speed, there is little to no difference between float and double (on a desktop CPU). The speed advantage with float usually mostly comes from the halved memory bandwidth requirements.
If its just one or a few utility classes, you could also have two sets of them (e.g. FloatMathUtil and DoubleMathUtil). It would then be up to the user to decide which one to code against (they would be entirely unrelated classes in terms of API).
You can use object-oriented aproach.
Create your own class that implements the methods your mathematical system needs. Use this class instead of float. Inside it can use whatever you want float, double or BigDecimal. You can change later how your class works without changing the rest of your system.
Take a look at Double, it will give the general idea how to build it.
Implement methods for addition, multiplication etc.
E.g.:
public class MyDecimal
{
private float value;
public MyDecimal(int value)
{
this.value = value;
}
public MyDecimal(float value)
{
this.value = value;
}
public MyDecimal multiply(MyDecimal by)
{
return new MyDecimal(value * by.value);
}
...
}
So, if you want to use double instead of float you only need to change this class.