使用org.apache.commons.ObjectUtil类对自定义对象进行空安全检查



我一直在寻找一种强大的方法来比较我的对象,我遇到了ObjectUtils,并立即怀疑它是否能够有效地进行比较,因为我不知道它在内部是如何工作的,而且apache网站上关于这一点的文档很少。

有人能帮我做这个吗??

编辑:

当我说compare时,我真正需要比较的是MYOBJ的相等性,其中MYOBJ是我定义的一个自定义对象,其中有各种变量(所有这些变量都是原始数据类型,如int、long、float String,如果它们不为null,可以直接比较),但这在未来可能会改变。

我不确定BeanUtils.areEqual方法是否能够处理这样的情况,如果我在这个MYOBJ中包含我自己的数据类型(非基元)会怎么样。

感谢

你的问题很模糊,我真的不知道你在说什么,所以我会分几个方向回答。

"比较我的对象"可能意味着几件事。在Java中,这通常意味着通过Comparable/Comparator接口对它们进行比较以进行排序。虽然ObjectUtils确实提供了一个空安全比较方法,但除此之外,它对您没有任何帮助。您需要的是一个自定义的Comparator,或者让您的对象实现ComparableCompareToBuilder可以在一定程度上同时帮助您:

public class SomeBean implements Comparable<SomeBean>{
    private String foo;
    private int bar;
    private List<String> baz;
    public int compareTo(SomeBean other) {
        return new CompareToBuilder()
        .append(foo, other.foo)
        .append(bar, other.bar)
        .append(baz, other.baz)
        .toComparison();
    }
}

另一方面,如果你想比较不同对象类型的属性,那么你看的方向完全错误。请查看Commons/BeanUtils。样本代码:

public class BeanUtilsTester {
    public static class Foo{
        private String foo="foo";
        public String getFoo() {return foo;}
        public void setFoo(String foo) {this.foo = foo;}
        private Integer bar=123;
        public Integer getBar() {return bar;}
        public void setBar(Integer bar) {this.bar = bar;}
        private List<String> squoggle=Arrays.asList("abc","def");
        public List<String> getSquoggle() {return squoggle;}
        public void setSquoggle(List<String> squoggle) {this.squoggle = squoggle;}
    }
    public static class Bar{
        private String foo="bar";
        public String getFoo() {return foo;}
        public void setFoo(String foo) {this.foo = foo;}
        private Integer bar=456;
        public Integer getBar() {return bar;}
        public void setBar(Integer bar) {this.bar = bar;}
        private String[] fiddle=new String[]{"abc","def"};
        public String[] getFiddle() {return fiddle;}
        public void setFiddle(String[] fiddle) {this.fiddle = fiddle;}
    }
    public static void main(String[] args) throws Exception{
        Foo foo = new Foo();
        Bar bar = new Bar();
        Map<String,Object> fooProps = BeanUtils.describe(foo);
        Map<String,Object> barProps = BeanUtils.describe(bar);
        fooProps.keySet().retainAll(barProps.keySet());
        BeanUtils.populate(bar, fooProps);
        assertEquals(foo.getFoo(),bar.getFoo());
        assertEquals(foo.getBar(), bar.getBar());
    }
}

如果您只想正确地实现equals(),请查看EqualsBuilder:

@Override
public boolean equals(Object obj) {
    if (obj instanceof SomeBean) {
        SomeBean other = (SomeBean) obj;
        return new EqualsBuilder()
                .append(foo, other.foo)
                .append(bar, other.bar)
                .append(baz, other.baz)
                .isEquals();
    }
    return false;
}

ObjectUtils在比较用户定义的对象时可以很好地工作。当然,您需要在任何想要使用库函数进行比较的对象中实现Comparable接口。

刚刚做了一个简单的测试

User user1 = new User();
User user2 = new User();
Assert.assertEquals(true,ObjectUtils.equals(user1, user2)); 

此处的测试显示为false。这是不平等的。

User user1 = new User();
User user2 = user1;
Assert.assertEquals(true,ObjectUtils.equals(user1, user2));

上一个测试显示为true。

我相信您希望在不更改用户定义类的情况下进行类似于第一个测试的测试。如果我是对的,你不能用这个库来做比较。

但是,如果您在要比较的每个bean中实现compare()方法,我相信您能够使用它。