Guava Equivalence Example

0

There are two forms of equivalence, ‘identity’ equivalence and ‘equals’ equivalence.

In ‘identity’ equivalence, the objects being compared to are identical, that is, they share the same address in memory thus the objects refer to the same instance of a class.

In ‘equals’ equivalence, two objects are equivalent if the instances are of the same type and if the properties of the first object and second object are same.

The Equivalence.equivalent(a, b) follows

  1. Reflexive – If x is a reference to an object then equivalent(x, x) should always return true.
  2. Symmetric – If x and y are references to objects of the same type then equivalent(x, y) and equivalent(y, x) should return same result.
  3. Transitive – If equivalent(x, y) returns true and equivalent(y, z) returns true then equivalent(x, z) returns true.
  4. Consistent – If equivalent(x, y) is called multiple times it should return the same result as long as neither x not y is modified.

Example of Reflexive

Employee:

package com.javarticles.guava;

public class Employee {
    private String id;
    private String name;

    Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String toString() {
        return "Emp<" + id + "," + name + ">";
    }
    
    public boolean equals(Object o) {
         if (!(o instanceof Employee)) {
             return false;
         }
         Employee emp = (Employee) o;
         return emp.getId().equals(id) &&
                 emp.getName().equals(name);
    }
}

ReflexiveExample:

package com.javarticles.guava;

import com.google.common.base.Equivalence;

public class ReflexiveExample {
    public static void main(String[] args) {
        Equivalence<Object> identity = Equivalence.identity();
        System.out.println("Identity Reflexive eq(null, null)="
                + identity.equivalent(null, null));
        
        Employee emp = new Employee("01", "Joe");
        System.out.println("Identity Reflexive eq(emp, emp)="
                + identity.equivalent(emp, emp));
        
        Employee sameEmp = new Employee("01", "Joe");
        System.out.println("Identity Reflexive eq(emp, sameEmp)="
                + identity.equivalent(emp, sameEmp));
        
        Equivalence<Object> equals = Equivalence.equals();
        System.out.println("Equals Reflexive eq(emp, sameEmp)="
                + equals.equivalent(emp, sameEmp));
    }
}

Output:

Identity Reflexive eq(null, null)=true
Identity Reflexive eq(emp, emp)=true
Identity Reflexive eq(emp, sameEmp)=false
Equals Reflexive eq(emp, sameEmp)=true

Example of Symmetric

SymmetricExample:

package com.javarticles.guava;

import com.google.common.base.Equivalence;

public class SymmetricExample {
    public static void main(String[] args) {
        Equivalence<Object> identity = Equivalence.identity();
        System.out.println("Identity Symmetric eq(2, 3)=eq(3, 2)? "
                + (identity.equivalent(2, 3) == identity.equivalent(3, 2)));
        
        Employee emp1 = new Employee("01", "Joe");       
        Employee emp2 = new Employee("02", "Sam");
        
        Equivalence<Object> equals = Equivalence.equals();
        System.out.println("Equals Symmetric eq(emp1, emp2)=eq(emp2, emp1)? "
                + (equals.equivalent(emp1, emp2) == equals.equivalent(emp2, emp1)));
    }
}

Output:

Identity Symmetric eq(2, 3)=eq(3, 2)? true
Equals Symmetric eq(emp1, emp2)=eq(emp2, emp1)? true

Example of Transitive

TransitiveExample:

package com.javarticles.guava;

import com.google.common.base.Equivalence;

public class TransitiveExample {
    public static void main(String[] args) {
        Employee emp1 = new Employee("01", "Joe");       
        Employee emp2 = new Employee("01", "Joe");
        Employee emp3 = new Employee("01", "Joe");
        
        Equivalence<Object> equals = Equivalence.equals();
        System.out.println("eq(emp1, emp2)=" + equals.equivalent(emp1, emp2));
        System.out.println("eq(emp2, emp3)=" + equals.equivalent(emp2, emp3));
        System.out.println("eq(emp1, emp3)=" + equals.equivalent(emp1, emp3));
    }
}

Output:

eq(emp1, emp2)=true
eq(emp2, emp3)=true
eq(emp1, emp3)=true

Functional Equivalence Example

Functional equivalence evaluates equivalence of the functional outputs. It first applies function to the argument, then evaluates the equivalence on the returned outputs. That is, for any pair of non-null objects x and y, functional equivalence would be:

equivalence.onResultOf(function).equivalent(a, b)}

Which is same as:

equivalence.equivalent(function.apply(a), function.apply(b))}

In our example, the function that we apply converts a string to its lower case. This is useful if we want to compare case insensitive strings.

StringToLowercase:

package com.javarticles.guava;

import com.google.common.base.Function;

public class StringToLowercase implements Function<String, String>{
    public static final StringToLowercase INSTANCE = new StringToLowercase();
    public String apply(String input) {
        return input.toLowerCase();
    }

}

Equivalence strategy used is Equivalence.equals(). It is used only after applying StringToLowercase.INSTANCE function.

FunctionalEquivalenceExample:

package com.javarticles.guava;

import com.google.common.base.Equivalence;

public class FunctionalEquivalenceExample {
    public static void main(String[] args) {
        System.out.println("Case insensitive equality check");
        Equivalence strEqEqual = Equivalence.equals().onResultOf(
                StringToLowercase.INSTANCE);
        System.out.println("heLLo equals HellO ? " + strEqEqual.equivalent("heLLo", "HellO"));
    }
}

Output:

Case insensitive equality check
heLLo equals HellO ? true

Download the source code

This was an example about Guava Equivalence.

You can download the source code here: guavaEquivalenceExamples.zip

 

Share.

Comments are closed.