[英]Pass generic type class method as parameter
有什么方法可以将通用类型的方法作为参数传递? 我试图实现的是这样的:
ListUtils.mapObjectToField( entries, Contact.getZipCode );
我传递了List<T>
和泛型T
。 到目前为止,我对通用List很好,但是我无法实现方法调用。
public static <T, U> List<U> mapObjectToField( List<T>elements, /*generic method*/ )
{
List<U> result = new ArrayList<>();
for ( T current : elements )
{
result.add(current./*generic method*/);
}
return result;
}
没有Java 8,因为我正在为Android min SDK 14编码。
最好的方法可能是像Java 8中的Stream.map
一样实现它,并提供自己的接口(也许称为Mapper
,但是要在调用站点提供实现,则必须使用匿名内部类。 Lambda更好。
它可能看起来像这样:
public interface Mapper<T, U> {
U map(T t);
}
ListUtils会这样:
public class ListUtils {
public static List<U> mapObjectToField(List<T> elements, Mapper<T, U> mapper) {
List<U> result = new ArrayList<>();
for (T current : elements) {
result.add(mapper.map(current));
}
return result;
}
}
您可以这样称呼它:
List<String> zipCodes = ListUtils.mapObjectToField(contacts,
new Mapper<Contact, String>() {
public String map(Contact contact) {
return contact.getZipCode();
}
});
您可以在其他位置定义映射器,这将稍微清理外观,但不会像使用lambda那样好。
如果您想使用反射,就可以这样做(但不建议这样做),
public static <T, U> List<U> mapObjectToField( List<T>elements, String methodName )
{
List<U> result = new ArrayList<>();
Method method = null;
for ( T current : elements )
{
if(method == null){
try {
method = current.getClass().getDeclaredMethod(methodName);
} catch (Exception e) {
e.printStackTrace();
}
}
U object = (U) invokeMethod(current, method);
result.add(object);
}
return result;
}
public static Object invokeMethod(Object obj , Method method)
{
if (method != null) {
try {
Object value = method.invoke(obj);
return value;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
您也可以在Android SDK 14中使用Retrolambda来获取lambda和方法引用。
https://github.com/evant/gradle-retrolambda
https://stackoverflow.com/a/42996933/802034中建议的代码将变为:
public void main(){
List<Integer> lengths = mapObjectToField(nCopies(5, "hello"), String::length);
}
public static <T, U> List<U> mapObjectToField(List<T> elements, Mapper<T, U> mapper) {
List<U> result = new ArrayList<>();
for (T current : elements) {
result.add(mapper.map(current));
}
return result;
}
public interface Mapper<T, U> {
U map(T t);
}
}
如果想进一步使用Streams ,可以在Android上使用以下库: https : //github.com/aNNiMON/Lightweight-Stream-API
List<Integer> lengths =
Stream.of(nCopies(5, "hello"))
.map(String::length)
.collect(Collectors.toList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.