I am trying to understand the difference between passing a Closure vs a Comparator to the min function on a collection:
// Example 1: Closure/field/attribute?
Sample min = container.min { it.timespan.start }
// Example 2: Comparator
Sample min2 = container.min(new Comparator<Sample>() {
#Override
int compare(Sample o1, Sample o2) {
return o1.timespan.start <=> o2.timespan.start
}
})
They both return the correct result.
Where:
class Sample {
TimeSpan timespan
static constraints = {
}
}
And:
class TimeSpan {
LocalDate start
LocalDate end
}
In Example 1 I just pass the field timespan.start to min which I guess means that I am passing a Closure (even though its just a field in a class)?
In Example 1 does groovy convert the field timespan.start into a Comparator behind the scenes like the one I create explicitly in Example 2?
The difference is, that those are two different min methods both
taking different arguments. There is one for passing
a closure
and one for the
comparator
(there is a third one using identity and some deprecated ones, but we can ignore that for now).
The first version (Closure with one (implicit argument)) you have to
extract the value from the passed value, you want to make the min
aggregate with. Therefor this versions has some inner working to deal
with comparing the values.
But the docs also state:
If the closure has two parameters it is used like a traditional
Comparator. I.e. it should compare its two parameters for order,
returning a negative integer, zero, or a positive integer when the
first parameter is less than, equal to, or greater than the second
respectively. Otherwise, the Closure is assumed to take a single
parameter and return a Comparable (typically an Integer) which is then
used for further comparison.
So you can use a Closure version also to the same as your second example
(you have to define two params explicitly):
container.min{ a, b -> a <=> b }
And there is also a shorter version of the second example. You can cast
a Closure to an interface with groovy. So this works too:
container.min({ a, b -> a <=> b } as Comparator)
I have an ArrayList storing cars (for instance). Each instance of a car has three data fields (make, model, and year). Make and Model are both Strings, and year is an Int value. I want to be able to search the ArrayList and return the index location of every car that was produced in 2014 (say). I can use a simple search to return the first index location using something like this:
public static int searchYear(ArrayList<Cars> cars, int key)
{
int size = cars.size();
for (int i = 0; i < size; i++)
{
if (cars.get(i).getYear() == key)
return i;
}
return - 1;
}
where key == 2014 (the year I am searching for). How can I get this to return the index value of all cars with that key rather than only the first instance of it?
Short answer: you shall return an array of values, instead of a single int. Like in this signature:
public static ArrayList<Integer> searchYear (ArrayList<Cars> cars, int key)
More comments:
It is misleading that your parameter is named key if there is more than one instance that matches that key. The key is not an unique key, but just a value... I'd call that parameter year instead.
The signature of your method shall be something like this:
public static int[] searchYear (Cars[] cars, int year)
Of course you shall implement in your method the creation of an array of ints, appending the indexes those cars that match your year parameter.
You may ask yourself why I changed ArrayList<Cars> by Cars[]. Well, it is a matter of flexibility of future uses of this method you are creating. A plain array [] is a more common construction that ArrayList. Actually I would not put ArrayList in my method signature unless I'm using any method specific of ArrayList.
Since you are accessing by index with .get(i), this method is defined at the java.util.List interface, so a List argument makes sense:
public static int[] searchYear (List<Cars> cars, int year)
We can talk about the int[] return type: another option would be a Collection<Integer> or even Iterable<Integer>. The reasoning to choose one or another would be the same as for the cars argument: it all depends on what you want to do with the list of indexes returned by your method.
I am using DataListView from Bright Idea Software's ObjectListView to show real time data. I need to show double values correct upto 4 decimal point. How can I implement the same?
I suppose you currently use AspectName property to get/set value. Use the AspectGetter instead and format the return value as required.
Assuming you have an model object of type "Item" with a property "DoubleValue" of type double:
olvColumn1.AspectGetter += delegate(object rowObject) {
Item item = rowObject as Item;
return Math.Round(item.DoubleValue, 4);
};
You could also convert the DoubleValue using ToString(), but that would only be advisable if you do not need to edit the property from the OLV. Because the OLV "sees" the type you return from the AspectGetter (which would then be string instead of double) and not use a NumericUpDown control if you would try to edit the value.
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)
}
}
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.