[groovy-user] MissingMethodException with list.sum()

113 views
Skip to first unread message

Lothar Krenzien

unread,
Aug 5, 2009, 1:17:52 PM8/5/09
to us...@groovy.codehaus.org
Hello,

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


Jochen Theodorou

unread,
Aug 5, 2009, 2:13:22 PM8/5/09
to us...@groovy.codehaus.org
Lothar Krenzien schrieb:

> Hello,
>
> 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]

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/

Reply all
Reply to author
Forward
0 new messages