[英]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.