有没有办法将泛型类型的方法作为参数传递? 我试图实现的是这样的:
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。
答案 0 :(得分:0)
可能最好的方法是在Java 8中像Stream.map
一样实现它并提供您自己的接口,可能称为Mapper
,但是为了在呼叫站点提供实现,您必须使用匿名内部类。 Lambdas更好。
可能看起来像这样:
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那样好。
答案 1 :(得分:0)
如果你想使用反射,就这样做(但不建议使用它),
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;
}
答案 2 :(得分:0)
您可以使用 Retrolambda 在Android SDK 14中使用lambdas和方法引用。
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());