Michele Mariotti
Michele Mariotti

Reputation: 7459

Lambda equals using optionals and mappers

Suppose I have two objects and I want to know if a specific property is equal (nulls are managed exactly as I want):

// pre java 8

public static boolean equalsProp(SomeObject a, SomeObject b)
{
    Object aProp = a != null ? a.getProp() : null;
    Object bProp = b != null ? b.getProp() : null;

    return  (aProp == bProp) || (aProp != null && aProp.equals(bProp));
}

now that I have java 8, I can rewrite it to be generic:

public static <T, U> boolean equals(T a, T b, Function<? super T, ? extends U> mapper)
{
    Object aProp = Optional.ofNullable(a).map(mapper).orElse(null);
    Object bProp = Optional.ofNullable(b).map(mapper).orElse(null);

    return (aProp == bProp) || (aProp != null && aProp.equals(bProp));
}

But I don't like to define a method like this in one of my classes.

Is there a java.lang.something.SomeJreBundledClass.equals(a, b, func) that does exactly this?

Is there a best practice on how to do this (possibly without an utility method)?


Maybe it's not clear what I'm asking, I'll try again.

I have this piece of code:

Table t1 = ...
Table t2 = ...

if(!my.package.utils.ObjectUtils.equals(t1, t2, Table::getPrimaryKey))
{
    // ok, these tables have different primary keys
}

I'm asking if:

Upvotes: 1

Views: 276

Answers (3)

Shinigami
Shinigami

Reputation: 685

Maybe you can use something like this:

Comparator.comparing(SomeObject::getProp).compare(a, b) == 0
Comparator.comparing(Table::getPrimaryKey).compare(table1, table2) == 0

Upvotes: 1

Olivier Gr&#233;goire
Olivier Gr&#233;goire

Reputation: 35427

I'm asking if:

  • There's a JRE class that does the work of my.package.utils.ObjectUtils
  • There's a better, short and null-tolerant way to compare t1.primaryKey and t2.primaryKey without writing an utility method.

To your first question, No is the answer.

To your second question, No is also the answer, unless you're ready to have your code comparing objects quite shadily.

What you're trying to express is the equivalence. Several frameworks can help you use that context. The most notable of which is Guava with its Equivalence class/framework. In that case, you don't have to write a utility method, because they exist somewhere else.

Upvotes: 1

WillShackleford
WillShackleford

Reputation: 7008

Consider this using streams:

static class MyClass {
    String prop;

    public String getProp(){
        return prop;
    }
}
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {

    MyClass a = new MyClass();
    MyClass b = new MyClass();
    a.prop = "foo";
    b.prop = "foo";
    boolean e = Stream.of(a,b).filter(Objects::nonNull).map(MyClass::getProp).distinct().count() != 2;
    System.out.println("e = " + e);
    a = null;
    b = null;
    e = Stream.of(a,b).filter(Objects::nonNull).map(MyClass::getProp).distinct().count() != 2;
    System.out.println("e = " + e);
}

Upvotes: 1

Related Questions