I would like to use the groovy 'sum' method for a java ArrayList - but can't get it work.
The list is created in a java class like this:
java.util.List<InverterPerformance> results = new java.util.ArrayList<InverterPerformance>();
The list contains about 10-20 entries and I would like to 'summarise' the objects with the groovy command 'results.sum()' . The 'InverterPerformance' object implements a 'plus' method like this:
public BigDecimal plus(InverterPerformance value) {
if (value == null) {
return null;
}
if (this.getIrradiation() == null || value.getIrradiation() == null) {
return value.getIrradiation();
}
return this.getIrradiation().add(value.getIrradiation());
}
Is it really right ? The 'getIrradiation()' method returns a java.math.BigDecimal object. But the 'plus' method is called only once (without an error) and after that I always get an exception:
groovy.lang.MissingMethodException: No signature of method: java.math.BigDecimal.plus() is applicable for argument types: (model.report.InverterEnergy) values: [model.report.InverterEnergy@15d31ae0]
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:272)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:52)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:43)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:121)
So what I'm doing wrong ? How can I get the sum() function working ?
Thank you, Lothar
________________________________________________________________
Neu: WEB.DE Doppel-FLAT mit Internet-Flatrate + Telefon-Flatrate
für nur 19,99 Euro/mtl.!* http://produkte.web.de/go/02/
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
sum is basically a+b+c..., first it will do a+b. which is a.plus(b). The
type of a and b will determine what plus method will be called, btu the
method has to be declared for a. Adding of c follows, but for the result
of a+b. So if there is a type change here, then most probably a
different method will be called. In your case it is
InverterPerformance#plus first, and since that returns a BigDecimal, it
is BigDecimal#plus later. But there is no such plus method on
BigDecimalfor InverterPerformance... which means it will fail.
I you remove the plus method and use instead
results.sum() {it.irradiation?:0}
the form with the block here will not do a+b+c but cl(a)+cl(b)+cl(c)
with cl={it.irradiation?:0}. "it" is the parameter given to the closure,
so it is either a,b or c. it.irradiation will use your getIrradiation()
method. The evlis-operator will eval it.iarradiation to a boolean, which
is false for a BigDecimal if it is 0.0g or null. If this is not the
case, then the attached value will be returned, which is 0 here. It is a
but surplus for the 0.0g case, but it handles the null case well and is
short. All other numbers will be returned direclty. This way I can use
this one liner to sovle your problem easily ;)
bye blackdrag
--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/