Skip to content
AgileLogics
5 min read

Operator Overloading

Prerequisites: Classes and objects

Every Groovy operator maps to a method name. Define the method in your class and the operator works on your objects.

Operator Method
a + b, a - b, a * b, a / b plus, minus, multiply, div
a % b, a ** b mod, power
-a, a++ negative, next
a[i], a[i] = v getAt, putAt
a << b leftShift
a <=> b, <, > compareTo
a == b equals
a in b, case a: isCase
a() call
if (a) asBoolean
import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode
class Vector implements Comparable<Vector> {
    final BigDecimal x, y
    Vector(x, y) { this.x = x; this.y = y }

    Vector plus(Vector o) { new Vector(x + o.x, y + o.y) }
    Vector minus(Vector o) { new Vector(x - o.x, y - o.y) }
    Vector multiply(Number k) { new Vector(x * k, y * k) }
    Vector negative() { new Vector(-x, -y) }
    BigDecimal getAt(int i) { i == 0 ? x : y }
    BigDecimal getLength() { Math.sqrt((x * x + y * y) as double) }
    int compareTo(Vector o) { length <=> o.length }
    boolean asBoolean() { x != 0 || y != 0 }
    String toString() { "<$x, $y>" }
}

def a = new Vector(1, 2)
def b = new Vector(3, 4)
println a + b
println b - a
println a * 3
println(-a)
println "${b[0]}, ${b[1]}"
println b.length
println a < b
println([b, a].max())
println a + b == new Vector(4, 6)
println new Vector(0, 0) ? 'non-zero' : 'zero vector'
<4, 6>
<2, 2>
<3, 6>
<-1, -2>
3, 4
5.0
true
<3, 4>
true
zero vector

call and leftShift

class Pipeline {
    private List<Closure> steps = []
    Pipeline leftShift(Closure step) { steps << step; this }
    def call(input) { steps.inject(input) { value, step -> step(value) } }
}

def clean = new Pipeline()
clean << { it.trim() } << { it.toLowerCase() } << { it.replaceAll(/\s+/, '-') }
println clean('  Hello Groovy World ')
hello-groovy-world

<< adds steps and call makes the object callable like a function.

Guidelines

  • Overload only when the meaning is obvious — + for money or vectors, << for "append". A surprising * is worse than a named method.
  • Keep operators free of side effects (except << and putAt).
  • Implement Comparable for <, >, <=>, max, min, and sort.