Converting a string to int in Groovy - groovy

I have a String that represents an integer value and would like to convert it to an int. Is there a groovy equivalent of Java's Integer.parseInt(String)?

Use the toInteger() method to convert a String to an Integer, e.g.
int value = "99".toInteger()
An alternative, which avoids using a deprecated method (see below) is
int value = "66" as Integer
If you need to check whether the String can be converted before performing the conversion, use
String number = "66"
if (number.isInteger()) {
int value = number as Integer
}
Deprecation Update
In recent versions of Groovy one of the toInteger() methods has been deprecated. The following is taken from org.codehaus.groovy.runtime.StringGroovyMethods in Groovy 2.4.4
/**
* Parse a CharSequence into an Integer
*
* #param self a CharSequence
* #return an Integer
* #since 1.8.2
*/
public static Integer toInteger(CharSequence self) {
return Integer.valueOf(self.toString().trim());
}
/**
* #deprecated Use the CharSequence version
* #see #toInteger(CharSequence)
*/
#Deprecated
public static Integer toInteger(String self) {
return toInteger((CharSequence) self);
}
You can force the non-deprecated version of the method to be called using something awful like:
int num = ((CharSequence) "66").toInteger()
Personally, I much prefer:
int num = 66 as Integer

Several ways to do it, this one's my favorite:
def number = '123' as int

As an addendum to Don's answer, not only does groovy add a .toInteger() method to Strings, it also adds toBigDecimal(), toBigInteger(), toBoolean(), toCharacter(), toDouble(), toFloat(), toList(), and toLong().
In the same vein, groovy also adds is* eqivalents to all of those that return true if the String in question can be parsed into the format in question.
The relevant GDK page is here.

I'm not sure if it was introduced in recent versions of groovy (initial answer is fairly old), but now you can use:
def num = mystring?.isInteger() ? mystring.toInteger() : null
or
def num = mystring?.isFloat() ? mystring.toFloat() : null
I recommend using floats or even doubles instead of integers in the case if the provided string is unreliable.

Well, Groovy accepts the Java form just fine. If you are asking if there is a Groovier way, there is a way to go to Integer.
Both are shown here:
String s = "99"
assert 99 == Integer.parseInt(s)
Integer i = s as Integer
assert 99 == i

also you can make static import
import static java.lang.Integer.parseInt as asInteger
and after this use
String s = "99"
asInteger(s)

toInteger() method is available in groovy, you could use that.

Several ways to achieve this. Examples are as below
a. return "22".toInteger()
b. if("22".isInteger()) return "22".toInteger()
c. return "22" as Integer()
d. return Integer.parseInt("22")
Hope this helps

Groovy Style conversion:
Integer num = '589' as Integer
If you have request parameter:
Integer age = params.int('age')

def str = "32"
int num = str as Integer

Here is the an other way. if you don't like exceptions.
def strnumber = "100"
def intValue = strnumber.isInteger() ? (strnumber as int) : null

The way to use should still be the toInteger(), because it is not really deprecated.
int value = '99'.toInteger()
The String version is deprecated, but the CharSequence is an Interface that a String implements. So, using a String is ok, because your code will still works even when the method will only work with CharSequence. Same goes for isInteger()
See this question for reference :
How to convert a String to CharSequence?
I commented, because the notion of deprecated on this method got me confuse and I want to avoid that for other people.

The Simpler Way Of Converting A String To Integer In Groovy Is As Follows...
String aa="25"
int i= aa.toInteger()
Now "i" Holds The Integer Value.

Related

difference between int and Integer type in groovy

I have just started learning groovy and I am reading "Groovy in Action".
In this book I came across a statement that it doesn’t matter whether you declare or cast a variable to be of type int or Integer.Groovy uses the reference type ( Integer ) either way.
So I tried to assign null value to a variable with type int
int a = null
But it is giving me below exception
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'null' with class 'null' to class 'int'. Try 'java.lang.Integer' instead
at Script1.run(Script1.groovy:2)
Then I tried to assign null value to a variable with type Integer
Integer a = null
and it is working just fine.
Can anyone help me understand how groovy behaves such way or the reason behind it?
The core problem is that primitives can’t be null. Groovy fakes that out with autoboxing.
If you store a null value in a number, you can’t store that in a int/long/etc field. It’s not correct to convert a null number to 0, since this might be valid values. Null means that no value or choice has been made yet.
int is a primitive type and it is not considered as an object. Only objects can have a null value while int value can't be null because It's a value type rather than a reference type
For primitive types, we have fixed memory size i.e for int we have 4 bytes and null is used only for objects because there memory size is not fixed.
So by default we can use :-
int a = 0
Groovy uses wrapper types in all time when you call primitives
int a = 100
assert Integer == a.class
groovy takes int and wrap it into Integer before using it value
But groovy cannot set int value to null, because variable is int(primitive type) but not Integer.
int a = 100
int b = 200
a + b not int + int, but Integer + Integer
As I understand it, Groovy uses the wrapper types if you use literals. For example:
def a = 11 // equivalent to Object a = 11. 11 is an java.lang.Integer
or
assert ['java.lang.Integer'] == [ 11, 22, 33 ]*.class*.name.unique()
Although if you use a specific type in your definition, the compiler has to perform casting.
You can do:
def a = 11
a = 'ssss'
but
int a = 11 // or int a
a = 'ssss'
gives GroovyCastException.
This what you see in your case

Why this Integer comparison in Groovy is returning false?

I've found a bug in my project because of the following behavior:
int a = 1
Integer b = 2
assert a.class == b.class // ok, they are the same class
assert Integer.class != int.class // what?! they are different!
Somebody knows why and how to handle this?
I'm using Groovy 2.3.7
Regards
Using #alfasin link and #Nathan comments, I've discovered that the a is being autocoverted (autoboxing) to Integer.
That's why a.class == b.class but Integer.class != int.class
In my specific problem I'm using reflection to get the class of a field using clazz.getDeclaredFields(). The value in class is int, but the value that I have to compare is Integer.
To solve this I'm using the helper class below, which converts int to Integer for me:
import org.apache.commons.lang.ClassUtils
ClassUtils.primitiveToWrapper(int.class) == Integer.class
Thanks everybody!

Why is a double primitive a BigDecimal in groovy

I call an overloaded method (assertThat) which has one signature with a BigDecimal parameter and another one with double primitive parameter.
When I launch this snippet in groovy, it calls the one with BigDecimal parameter when I was expecting the double primitive parameter one to be called.
double[] erreur = Seg.erreur(xtab, ytab, 0, 2)
Assertions.assertThat(erreur[1]).isEqualTo(-0.3333333333333333)
Can someone explain me why ?
Thanks in advance.
By default, a decimal number in groovy is a BigDecimal. If you want it to be a double, you should use the suffix D or d:
From Number type suffixes in the docs:
assert 123.45 == new BigDecimal('123.45') // default BigDecimal type used
assert 1.200065D == new Double('1.200065')
Your isEqualsTo() is passing a BigDecimal as parameter, whereas your assertThat() is passing a double. Just add a d at the end of that -0.3333333333333333 and it should work:
import static org.assertj.core.api.Assertions.assertThat
class Doubles extends GroovyTestCase {
void testAssertions() {
double[] erreur = [0.1, -0.3333333333333333, 0.3]
assertThat(erreur[1]).isEqualTo(-0.3333333333333333d)
}
}

How do I round a number in Groovy?

How do I round a number in Groovy? I would like to keep 2 decimal places.
For example (pseudo-code):
round(1.2334695) = 1.23
round(1.2686589) = 1.27
If you're dealing with doubles or floats
You can simply use
assert xyz == 1.789
xyz.round(1) == 1.8
xyz.round(2) == 1.79
You can use:
Math.round(x * 100) / 100
If x is a BigDecimal (the default in Groovy), this will be exact.
Use mixin.
class Rounding {
public BigDecimal round(int n) {
return setScale(n, BigDecimal.ROUND_HALF_UP);
}
}
Add this to your startup class and round() is a first-class method of BigDecimal:
BigDecimal.mixin Rounding
Test cases:
assert (new BigDecimal("1.27")) == (new BigDecimal("1.2686589").round(2))
assert (1.2686589).round(2) == 1.27
assert (1.2334695).round(2) == 1.23
Like this:
def f = 1.2334695;
println new DecimalFormat("#.##").format(f);
Or like this:
println f.round (new MathContext(3));
Output:
1.23
Reference: Formatting a Decimal Number
Groovy adds a round() method to the Double and Float classes, so:
(123.456789f).round(2) == 123.46f
Source: Rounding Numbers in Groovy
Probably, more Groovysh way would be to use this snippet (x as double).round(2) like this:
def a = 5.2355434
println "a = $a, a.class = ${a.getClass()}"
def b = (a as double).round(2)
println "b = $b, b.class = ${b.getClass()}"
Looking at #sjtai's and #cdeszaq's answers you don't need to get mixed up with mixin if you just define a method like this:
def bigDecimalRound(n,decimals){
return(n.setScale(decimals, BigDecimal.ROUND_HALF_UP))
}
It is the BigDecimal builtin method setScale that performs the rounding.
println(1.2334695.setScale(2, BigDecimal.ROUND_HALF_UP))
>> 1.23
It's worth noting also that setScale accepts negative arguments in order to round things to larger order of magnitude, i.e.
println(123.2334695.setScale(-1, BigDecimal.ROUND_HALF_UP))
>> 1.2E+2
Working from #sjtai's great answer, this is the Mixin I use for just about all my decimal rounding needs:
class Rounding {
public BigDecimal round(int decimalPlaces = 0, RoundingMode roundingMode = RoundingMode.HALF_EVEN) {
return setScale(decimalPlaces, roundingMode);
}
}
If rounds to an int by default, and uses an "even" rounding method (reducing statistical error by default is always a good thing), but it still allows the caller to easily override these.
as simple as this:
YOUR_NUMBER = 1.234567
((int) YOUR_NUMBER * 100)/100
note: this would cut off the extra decimal points; it doesn't round up.
For example:
def rd = 1.3425345352
sd = ((float)rd).round(3)
println sd
>> 1.343
This is surprisingly complex for Groovy. It's usually... groovier.
You need to create a MathContext object to do the rounding.
num = 9.59123331333g
// rounds to 2 places, rounding up by default
mc = new java.math.MathContext(2)
num.round(mc)
==> Result: 7.0
with help from
https://blogs.oracle.com/fadevrel/rounding-numbers-and-decimal-places-in-numerical-fields
https://docs.oracle.com/javase/7/docs/api/java/math/MathContext.html
https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#round(java.math.MathContext)
You can convert any number to float and then use the round() function as:
((float)1.2334695).round(2)

Best way to build object from delimited string (hopefully not looped case)

this question feels like it would have been asked already, but I've not found anything so here goes...
I have constructor which is handed a string which is delimited. From that string I need to populate an object's instance variables. I can easily split the string by the delimited to give me an array of strings. I know I can simply iterate through the array and set my instance variables using ifs or a switch/case statement based on the current array index - however that just feels a bit nasty. Pseudo code:
String[] tokens = <from generic string tokenizer>;
for (int i = 0;i < tokens.length;i++) {
switch(i) {
case(0): instanceVariableA = tokens[i];
case(1): instanceVarliableB = tokens[i];
...
}
}
Does anyone have any ideas of how I do this better/nicer?
For what it's worth, I'm working in Java, but I guess this is language independant.
Uhm... "nasty" is in the way the constructor handles the parameters. If you can't change that then your code snippet is as good as it may be.
You could get rid of the for loop, though...
instanceVariableA = tokens[0];
instanceVariableB = tokens[1];
and then introduce constants (for readibilty):
instanceVariableA = tokens[VARIABLE_A_INDEX];
instanceVariableB = tokens[VARIABLE_B_INDEX];
NOTE: if you could change the string parameter syntax you could introduce a simple parser and, with a little bit of reflection, handle this thing in a slightly more elegant way:
String inputString = "instanceVariableA=some_stuff|instanceVariableB=some other stuff";
String[] tokens = inputString.split("|");
for (String token : tokens)
{
String[] elements = token.split("=");
String propertyName = tokens[0];
String propertyValue = tokens[1];
invokeSetter(this, propertyName, propertyValue); // TODO write method
}
Could you not use a "for-each" loop to eliminate much of the clutter?
I really think the way you are doing it is fine, and Manrico makes a good suggestion about using constants as well.
Another method would be to create a HashMap with integer keys and string values where the key is the index and the value is the name of the property. You could then use a simple loop and some reflection to set the properties. The reflection part might make this a bit slow, but in another language (say, PHP for example) this would be much cleaner.
just an untested idea,
keep the original token...
String[] tokens = <from generic string tokenizer>;
then create
int instanceVariableA = 0;
int instanceVariableB = 1;
if you need to use it, then just
tokens[instanceVariableA];
hence no more loops, no more VARIABLE_A_INDEX...
maybe JSON might help?
Python-specific solution:
Let's say params = ["instanceVariableA", "instanceVariableB"]. Then:
self.__dict__.update(dict(zip(params, tokens)))
should work; that's roughly equivalent to
for k,v in zip(params, tokens):
setAttr(self, k, v)
depending on the presence/absence of accessors.
In a non-dynamic language, you could accomplish the same effect building a mapping from strings to references/accessors of some kind.
(Also beware that zip stops when either list runs out.)

Resources