工作中遇到的很多Common的问题,可以优先用短时间调研查找下功能强大高效使用广泛的开源库,退而再考虑自己闷头开发一个适用的工具。
近期项目测试需要开发很多对象比较的操作,看到前面童鞋使用了guava的ComparisonChain,很是受启发,自己果然还是太小白。路漫漫,继续努力吧。
使用过程中遇到一个坑。
场景:待比较的数据中可能有null值比较的情况。
1 int result = ComparisonChain.start().compare(actualRecord.getSciId(),2 expectedRecord.getSciId()).compare(actualRecord.getLegalName(),3 expectedRecord.getLegalName()).compare(actualRecord.getLei(),4 expectedRecord.getLei()).compare(actualRecord.getLeiSource(),5 expectedRecord.getLeiSource()).result();
抛出异常:
java.lang.NullPointerException: null
at com.google.common.collect.ComparisonChain$1.compare(ComparisonChain.java:76) ~[guava-15.0.jar:na]源码分析:
1 @Override public ComparisonChain compare(2 Comparable left, Comparable right) {3 return classify(left.compareTo(right));4 }
这里的left一旦为null时,就会抛出NullPointerException。
解决方案可参考:
源码里compare还有一个重载方法,允许left和right值为null,需要传递一个comparator函数:
1 @Override publicComparisonChain compare(2 @Nullable T left, @Nullable T right, Comparator comparator) {3 return classify(comparator.compare(left, right));4 }
于是修改实现代码,使用3个参数的重载方法,传递一个默认的comparator即完美解决。
1 // for Nullable fields, using compare with a comparator (i.e. Ordering.allEqual() )2 int result = ComparisonChain.start().compare(actualRecord.getSciId(),3 expectedRecord.getSciId()).compare(actualRecord.getLegalName(),4 expectedRecord.getLegalName()).compare(actualRecord.getLei(),5 expectedRecord.getLei(),Ordering.allEqual()).compare(actualRecord.getLeiSource(),6 expectedRecord.getLeiSource(),Ordering.allEqual()).result();
Verify actual EodSnapshot SCI records MATCH with expected: com.scb.ccp.shark.qatool.impl.dao.audit.pojo.EodSnapshotSCI@16dc5c9[fmId=400852983,sciId=11182108,legalName=MTIME HOLDINGS, LTD.,lei=<null>,leiSource=<null>,recordDatetime=2019-08-11 21:00:15.0,cptyId=79fafe32-07de-48d9-8b12-58af4764ee49]