在commons-collections 3.2.1
中,以下单行内容可以很好地检索myProperty
中对象的myCollection
值:
Collection<MyType> myTypes = (Collection<MyType>) CollectionUtils.collect(myCollection, new BeanToPropertyValueTransformer("myProperty"))
唯一的缺点是不支持泛型,因此需要进行类型转换。
什么是在commons-collection4
中有效的解决方案,利用泛型?
答案 0 :(得分:1)
显然,他们从BeanToPropertyValueTransformer
版本中删除了apache-commons-collection4
。
我设法通过定义自定义Transformer
来实现相同的行为。泛型的引入消除了输出集合的必要性:
Collection<MyInputType> myCollection = ...
Collection<MyType> myTypes = CollectionUtils.collect(myCollection, new Transformer<MyInputType, MyType>() {
@Override
public MyType transform(MyInputType input) {
return input.getMyProperty();
}
}
您也可以编写自己使用反射的Transformer
class ReflectionTransformer<O>
implements
Transformer<Object, O> {
private String reflectionString;
public ReflectionTransformer(String reflectionString) {
this.reflectionString = reflectionString;
}
@SuppressWarnings("unchecked")
@Override
public O transform(
Object input) {
try {
return (O) BeanUtils.getProperty(input, reflectionString);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
并使用它与您之前使用的BeanToPropertyValueTransformer
Collection<MyType> myTypes = CollectionUtils.collect(myCollection, new ReflectionTransformer<MyType>("myProperty"));
答案 1 :(得分:0)
尝试使用以下类(使用 commons-collection4) -
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.lang.reflect.InvocationTargetException;
public class BeanToPropertyValueTransformer implements Transformer {
private final Log log = LogFactory.getLog(this.getClass());
private String propertyName;
private boolean ignoreNull;
public BeanToPropertyValueTransformer(final String propertyName) {
this(propertyName, false);
}
public BeanToPropertyValueTransformer(final String propertyName, final boolean ignoreNull) {
super();
if ((propertyName != null) && (propertyName.length() > 0)) {
this.propertyName = propertyName;
this.ignoreNull = ignoreNull;
} else {
throw new IllegalArgumentException(
"propertyName cannot be null or empty");
}
}
public Object transform(final Object object) {
Object propertyValue = null;
try {
propertyValue = PropertyUtils.getProperty(object, propertyName);
} catch (final IllegalArgumentException e) {
final String errorMsg = "Problem during transformation. Null value encountered in property path...";
if (ignoreNull) {
log.warn("WARNING: " + errorMsg + e);
} else {
final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
if (!BeanUtils.initCause(iae, e)) {
log.error(errorMsg, e);
}
throw iae;
}
} catch (final IllegalAccessException e) {
final String errorMsg = "Unable to access the property provided.";
final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
if (!BeanUtils.initCause(iae, e)) {
log.error(errorMsg, e);
}
throw iae;
} catch (final InvocationTargetException e) {
final String errorMsg = "Exception occurred in property's getter";
final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
if (!BeanUtils.initCause(iae, e)) {
log.error(errorMsg, e);
}
throw iae;
} catch (final NoSuchMethodException e) {
final String errorMsg = "No property found for name [" +
propertyName + "]";
final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
if (!BeanUtils.initCause(iae, e)) {
log.error(errorMsg, e);
}
throw iae;
}
return propertyValue;
}
public String getPropertyName() {
return propertyName;
}
public boolean isIgnoreNull() {
return ignoreNull;
}
}