Groovy Goodness: Removing Elements From a Collection
There are a lot of methods added to the Java collection classes by Groovy. For example to remove elements from a collection, and indeed modify the collection itself, we can use the removeAll
and removeElement
methods. With the removeAll
method we define a closure with a condition that needs to be true for an element to be removed from the collection. The removeElement
method is added to overcome any ambiguity with the standard overloaded remove
method for collections with integer values. The remove
method accepts both an Object
or int
value, to remove either an element or an element at the specified index. When the collection contains integer values than the argument is interpreted as index value. The removeElement
method will use the remove(Object)
method implementation. When the collection is a List
Groovy adds the removeAt
method. We need to specify the index value of the element we want to remove.
def list = ['Groovy', '=', 'gr8!']
// Groovy adds removeAll method
// to remove items from collection
// that apply to the condition we
// define in the closure.
list.removeAll { it.toLowerCase().startsWith('g') }
// All values starting with a G or g
// are now removed.
// Remember the collection we use the
// removeAll method on is changed.
assert list == ['=']
// Java 8 adds removeIf method with
// a predicate. In Groovy we can implement
// the predicate as closure.
list.removeIf { it instanceof String }
assert list.size() == 0
def values = ['Hello', 'world']
// Groovy adds removeAll(Object[])
// to remove multiple elements
// from a collection.
values.removeAll(['world', 'Hello'] as Object[])
assert values.empty
def items = [1, 2, 3]
// remove method is overloaded
// for Object and index value.
// Because Groovy wraps int to
// Integer object, the method call
// is ambiguous for Integer collections.
items.remove(1)
// We want to remove object
// Integer(1) from the list,
// but item with index 1 is removed.
assert items == [1, 3]
// Groovy adds removeElement
// as alias for remove(Object).
items.removeElement(1)
assert items == [3]
// When the collection is a List
// we can use the removeAt method
// to remove based on index value.
items.removeAt(0)
assert !items
Instead of removing elements with a any of the remove...
methods we can also use the retainAll
method in Groovy. Any elements that don't apply to the condition we specify in the closure are removed from the collection. See the following example code with some usages of the retainAll
methods:
def list = ['Groovy', 42, 'gr8!', 5.2, new Date()]
// Groovy adds retainAll method
// to remove items from collection
// that do not apply to the condition we
// define in the closure and keep those
// items that do apply to the condition.
list.retainAll { it instanceof String }
// All values that are not a String
// object are removed.
// Remember the collection we use the
// retainAll method on is changed.
assert list == ['Groovy', 'gr8!']
def values = ['Hello', 'world', 'from', 'Groovy']
// Groovy adds retainAll(Object[])
// to keep multiple elements
// in a collection and remove all
// the other elements.
values.retainAll(['world', 'Hello'] as Object[])
assert values.join(' ') == 'Hello world'
Written with Groovy 2.4.4.