Question

I'm trying to filter a list of location objects to get back filtered list of objects.

   def result= ports?.locations?.findAll { 

        it.numberOfParkingSlots > 0
}

But I got the following exception:

Cannot compare java.util.ArrayList with value '[0, 3]' and java.lang.Integer with value '0'. Stacktrace follows:
Message: Cannot compare java.util.ArrayList with value '[0, 3]' and java.lang.Integer with value '0'

What is wrong with this code?

Was it helpful?

Solution

Your ports variable sounds like a list, and so does locations. When a getter is called on a list, Groovy does a list unpack and the result looks like a collect: the property from all the objects is put inside a list, thus, your error. I managed to reproduce your error with the following:

class Port { 
    List<Location> locations = [] 
}

class Location { 
    int numberOfParkingSlots 
}

ports = [
    new Port(locations: [ 
        new Location(numberOfParkingSlots: 0), 
        new Location(numberOfParkingSlots: 3) ]),
    new Port(locations: [ new Location(numberOfParkingSlots: 1) ]),
]

ports?.locations?.findAll { 
  it.numberOfParkingSlots > 0 
}

Which fails with:

Caught: groovy.lang.GroovyRuntimeException: 
    Cannot compare java.util.ArrayList with value '[0, 3]' and 
    java.lang.Integer with value '0'

I'm assuming this is the case here.

The problem is that ports.location is getting a list of lists, and inside findAll, it is a list of locations. A solution is to flatten() the lists befores invoking findAll:

def locations = ports?.locations.flatten().findAll {
  it.numberOfParkingSlots > 0
}

assert locations[0].numberOfParkingSlots == 3
assert locations[1].numberOfParkingSlots == 1

OTHER TIPS

Why not use isEmpty()?

     def result= ports?.locations?.findAll { !it.numberOfParkingSlots.empty }

Or just using groovy truth

def result= ports?.locations?.findAll { it.numberOfParkingSlots }

Following the code you share, you could try adding toInteger() method to numberOfParkingSlots property

something like this

def result= ports?.locations?.findAll { 
    it.numberOfParkingSlots.toInteger() > 0
}

I have not tried this, some proposed options are plausibles, i hope it help you

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top