Java 将泛型类型类方法作为参数传递

Java 将泛型类型类方法作为参数传递,java,android,list,generics,reflection,Java,Android,List,Generics,Reflection,有没有办法将泛型类型的方法作为参数传递? 我试图实现的目标如下: ListUtils.mapObjectToField( entries, Contact.getZipCode ); public interface Mapper<T, U> { U map(T t); } public class ListUtils { public static List<U> mapObjectToField(List<T> elements, Ma

有没有办法将泛型类型的方法作为参数传递? 我试图实现的目标如下:

ListUtils.mapObjectToField( entries, Contact.getZipCode );
public interface Mapper<T, U> {
    U map(T t);
}
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();
        }
    });
我从泛型类
T
传递一个
列表和一个方法。
到目前为止,我对泛型列表很满意,但无法实现方法调用

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;
}
公共静态列表mapObjectToField(列表元素,/*泛型方法*/)
{
列表结果=新建ArrayList();
对于(T电流:元件)
{
结果.添加(当前./*通用方法*/);
}
返回结果;
}

没有Java 8,因为我正在为Android min SDK 14编写代码。

最好的方法可能是像Java 8中的
Stream.map
那样实现它,并提供自己的接口,可能称为
Mapper
,但要在调用站点提供实现,必须使用匿名内部类。兰姆达斯好得多

可能是这样的:

ListUtils.mapObjectToField( entries, Contact.getZipCode );
public interface Mapper<T, U> {
    U map(T t);
}
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();
        }
    });
公共接口映射器{
U图(T);
}
ListUtils希望这样:

ListUtils.mapObjectToField( entries, Contact.getZipCode );
public interface Mapper<T, U> {
    U map(T t);
}
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();
        }
    });
公共类ListUtils{
公共静态列表mapObjectToField(列表元素、映射器映射器){
列表结果=新建ArrayList();
对于(T电流:元件){
添加(mapper.map(当前));
}
返回结果;
}
}
你可以这样称呼它:

ListUtils.mapObjectToField( entries, Contact.getZipCode );
public interface Mapper<T, U> {
    U map(T t);
}
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();
        }
    });
List zipCodes=ListUtils.mapObjectToField(联系人、,
新映射器(){
公共字符串映射(联系人){
return contact.getZipCode();
}
});

您可以在其他地方定义映射器,这将在一定程度上清理外观,但它不会像使用lambdas那样好。

如果您想使用反射,就这样做(但这不是推荐的解决方案)

公共静态列表mapObjectToField(Listelements,String methodName)
{
列表结果=新建ArrayList();
方法=null;
对于(T电流:元件)
{
if(方法==null){
试一试{
method=current.getClass().getDeclaredMethod(methodName);
}捕获(例外e){
e、 printStackTrace();
} 
}
U对象=(U)invokeMethod(当前,方法);
结果。添加(对象);
}
返回结果;
}
公共静态对象调用方法(对象对象,方法)
{
if(方法!=null){
试一试{
对象值=方法调用(obj);
返回值;
}捕获(例外e){
e、 printStackTrace();
}
}
返回null;
}

您可以使用Retrolambda将lambda和方法引用也包含在android SDK 14中

中建议的代码将变为:

  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);
  }


}
public void main(){
列表长度=mapObjectToField(nCopies(5,“hello”),字符串::长度);
}
公共静态列表mapObjectToField(列表元素、映射器映射器){
列表结果=新建ArrayList();
对于(T电流:元件){
添加(mapper.map(当前));
}
返回结果;
}
公共接口映射器{
U图(T);
}
}
如果您想进一步使用,您可以在android上使用此库:

列表长度=
流(nCopies(5,“你好”))
.map(字符串::长度)
.collect(Collectors.toList());

如果您将方法的名称作为字符串传递,您可以使用反射进行传递,但这样做并不美观。当您实现要在其他地方执行的实际代码时,为什么还需要此方法?我建议您查看java.util.function.function,它几乎满足了您的需要。--这正是你所需要的。虽然它不能真正回答通过一个方法的问题,但它正是我试图实现的,所以非常感谢你!