49

I am new to groovy (worked on java), trying to write some test cases using Spock framework. I need the following Java snippet converted into groovy snippet using "each loop"

Java Snippet:

List<String> myList = Arrays.asList("Hello", "World!", "How", "Are", "You");
for( String myObj : myList){
    if(myObj==null) {
        continue;   // need to convert this part in groovy using each loop
    }
    System.out.println("My Object is "+ myObj);
}

Groovy Snippet:

def myObj = ["Hello", "World!", "How", "Are", "You"]
myList.each{ myObj->
    if(myObj==null){
        //here I need to continue
    }
    println("My Object is " + myObj)
}
Raedwald
  • 46,613
  • 43
  • 151
  • 237
Karthikeyan
  • 569
  • 1
  • 5
  • 10
  • Possible duplicate of [Best pattern for simulating "continue" in Groovy closure](http://stackoverflow.com/questions/205660/best-pattern-for-simulating-continue-in-groovy-closure) – kriegaex Jan 04 '17 at 14:52

3 Answers3

80

Either use return, as the closure basically is a method that is called with each element as parameter like

def myObj = ["Hello", "World!", "How", "Are", "You"]
myList.each{ myObj->
    if(myObj==null){
        return
    }
    println("My Object is " + myObj)
}

Or switch your pattern to

def myObj = ["Hello", "World!", "How", "Are", "You"]
myList.each{ myObj->
    if(myObj!=null){
        println("My Object is " + myObj)
    }
}

Or use a findAll before to filter out null objects

def myList = ["Hello", "World!", "How", "Are", null, "You"]
myList.findAll { it != null }.each{ myObj->
    println("My Object is " + myObj)
}

Or if you are concerned that you first iterate through the whole collection to filter and only then start with the each, you can also leverage Java streams

def myList = ["Hello", "World!", "How", "Are", null, "You"]
myList.stream().filter { it != null }.each{ myObj->
    println("My Object is " + myObj)
}
Vampire
  • 35,631
  • 4
  • 76
  • 102
  • 1
    OP wants to filter entries and therefore `findAll {...}` is the top answer here +1 – Alex Sep 04 '20 at 13:33
  • 1
    Last version with findAll looks the niciest. But isn't that more time consuming? Aren't you iterating over the whole collection twice then? – Yaerius Sep 17 '20 at 15:26
  • I don't think it is significantly more time-consuming as you do the same actions even with iterating twice. The `each` will not start though until the filtering is done. If that is an issue, you can leverage Java streams. I added that to the answer. – Vampire Apr 05 '23 at 15:16
26

you can either use a standard for loop with continue:

for( String myObj in myList ){
  if( something ) continue
  doTheRest()
}

or use return in each's closure:

myList.each{ myObj->
  if( something ) return
  doTheRest()
}
injecteer
  • 20,038
  • 4
  • 45
  • 89
1

You could also only enter your if statement if the object isn't null.

def myObj = ["Hello", "World!", "How", "Are", "You"]
myList.each{ 
    myObj->
    if(myObj!=null){
        println("My Object is " + myObj)
    }
}
Andrew_CS
  • 2,542
  • 1
  • 18
  • 38
  • 1
    code is cleaner with the "continue" approach, when there is a lot of code to be executed when the condition is not satisfied. – Pablo Pazos Jun 09 '17 at 18:00