openGeeksLab / codenameone

Automatically exported from code.google.com/p/codenameone
0 stars 0 forks source link

Number utility class #1146

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
In my past several projects I have found the need to use a utility class for 
dealing with numbers like the one I've attached here.  This has been handy 
especially when dealing with the result of processing JSON values that contain 
numerical data.  Is there something like this already in the CN1 core that I 
have missed?  Is this something that you think could add value to the core?

Summary:

A utility class with static methods:
intValue(Object)
longValue(Object)
doubleValue(Object)

.. you could also have floatValue() but I didn't implement it.

Original issue reported on code.google.com by st...@weblite.ca on 24 Jun 2014 at 5:14

Attachments:

GoogleCodeExporter commented 8 years ago
Hm... is that really needed? If you have a number type, you can just use a 
plain old cast. I agree implementation of the Number interface would be of use, 
but I think that might be difficult since it wasn't introduced to Java ME 
before 1.8.

This class would only be of use when dealing directly with Object, which most 
of the time should not be necessary since we can use generics in codename one 
(like List<Integer> instead of just List).

When parsing JSON, do you want to create your numbers from String values? Then 
it should be more straightforward to use Double.valueOf(), Integer.valueOf(), 
etc. directly.

Original comment by mailxze...@gmail.com on 24 Jun 2014 at 7:11

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
In my use case, I would be loading POJOs with data obtained from 
JSONParser.parseJSON.  parseJSON currently uses Double for all numbers, since 
it is the most flexible.  So, suppose I have something like this:

int myId = (int)map.get("theId");    // where theId is a Double.

this will give a class cast exception.  You can't cast Double to Integer.

So in the*many* cases where the original number was an integer (on the server 
side), you need to do something like this.

int myId = ((Double)map.get("theId")).intValue();

But this required me to know that this particular implementation of parseJSON() 
uses Doubles for all numbers.   If I'm dealing with a case with another parser, 
it might handle numbers differently.  I don't want to have to worry about what 
type of number I'm dealing with.  All I know, is I want an int, or a long, or 
whatever. 

With this utility class I can have:

int myInt = NumberUtil.intValue("2")
or
int myInt = NumberUtil.intValue(2.0)
of
int myInt = NumberUtil.intValue(2);
etc..

It just results in more robust code.  The less I am having to code to private 
implementation details, the less likely my code will break later on.

Original comment by st...@weblite.ca on 24 Jun 2014 at 7:32

GoogleCodeExporter commented 8 years ago
I forgot to mention, that in my use case, I have a separation of domains so 
that the actual place where I'm converting a Map into a POJO is separate from 
the fact that the Map was produced by parseJSON.

E.g.

I have a method:
MyPOJOClass obj = mapToPOJO(map);

inside mapToPOJO, there is something like:
obj.id = NumberUtil.intValue(map.get("id"));

The map could have bee produced with something like:

Map m = new HashMap();
m.put("id", 5);

or as was parsed by parseJSON.

So, in this case, either I have to make document my library so that its callers 
know to make all numbers doubles - even if they are just ints.  Or my 
mapToPOJO() function has to test the value to see what type of number it is 
before I can set the POJO id with its value.   Which is recreating the 
functionality of NumberUtil.intValue().

Original comment by st...@weblite.ca on 24 Jun 2014 at 7:48

GoogleCodeExporter commented 8 years ago
Perhaps this is not the place for a discussion, but this seems more like a 
corner case to me (you get something back from an API where you do not know 
exactly what it is, but it definitely should be a number). And all of the above 
could be dealt with Integer.valueOf(""+o), but then of course it would be a 
round-trip if o were already an int.

I am not 100% opposed, and Looking at the API of JSONParser, I see what you 
mean. But I think it's rather that API that should be fixed than introducing 
another class that looks like it has not many use cases beyond trying to cope 
with a sub-optimal API...

Original comment by mailxze...@gmail.com on 24 Jun 2014 at 8:24

GoogleCodeExporter commented 8 years ago
Integer.valueOf(""+o) will throw a parse exception for o =:

"2.0"
new Double(2.0)
2.0
2f,
etc...

Original comment by st...@weblite.ca on 24 Jun 2014 at 8:30

GoogleCodeExporter commented 8 years ago
"has not many use cases beyond trying to cope with a sub-optimal API"

I disagree with this statement.  There is a reason why the Number class exists. 
 This is not a corner case.  And the solution of adding a Number class in a 
cross platform way is not trivial - and may even be impossible (or at least 
impractical).  Using a utility class like this follows the same pattern of 
workaround that was used for String and Math - both of which face similar 
challenges.

Original comment by st...@weblite.ca on 24 Jun 2014 at 8:34