Search code examples
javahamcrestlambdaj

LambdaJ: matching on fields of the same object


Can someone get me out of LambdaJ pit I fell into please?

let's assume I have a list of objects of this class:

private class TestObject {
    private String A;
    private String B;
    //gettters and setters
}

Let's say I want to select the objects from the list where A.equals(B)

I tried this:

 List<TestObject> theSameList = select(testList, having(on(TestObject.class).getA(), equalTo(on(TestObject.class).getB())));

but this returns an empty list

And this:

List<TestObject> theSameList = select(testList, having(on(TestObject.class).getA().equals(on(TestObject.class).getB())));

but that throws an exception [EDIT: due to known limitations of proxying final classes]

Note, One way of getting around this is to have a method that compares the two fields inside the TestObject, but let's assume I cannot do this for a reason of your choice.

What am I missing?


Solution

  • After poking and fiddling with LambdaJ to match on the fields of the same object, the only solution that is working for me is writing a custom matcher. Here's quick and dirty implementation of one that would do the job:

    private Matcher<Object> hasPropertiesEqual(final String propA, final String propB) {
        return new TypeSafeMatcher<Object>() {
    
    
            public void describeTo(final Description description) {
                description.appendText("The propeties are not equal");
            }
    
            @Override
            protected boolean matchesSafely(final Object object) {
    
                Object propAValue, propBValue;
                try {
                    propAValue = PropertyUtils.getProperty(object, propA);
                    propBValue = PropertyUtils.getProperty(object, propB);
                } catch(Exception e) {
    
                    return false;
                }
    
                return propAValue.equals(propBValue);
            }
        };
    }
    

    The PropertyUtils is the class from org.apache.commons.beanutils

    The way to use this matcher:

    List<TestObject> theSameList = select(testList, having(on(TestObject.class), hasPropertiesEqual("a", "b")));