Java泛型 - 将函数映射到列表

3
我在Java中对泛型不是很熟悉,我遇到了这样一个问题:假设您有自己的List实现,并且您想提供一种机制来同时使用某种映射(函数接口)将所有元素转换并将它们收集到一个新的列表中。
虽然函数接口(在我的情况下为IMapper)的想法和使用是直截了当的,但我无法想出执行映射的函数应该具有什么签名?
以下是一个小用例示例以及我所考虑的内容。不幸的是,它不起作用,我认为主要问题是:在这种情况下第二个V参数类型应该如何传递?
public interface IMapper<T,V> { V map(T v); }

public class MyList<T> extends ArrayList<T> {
  public MyList<V> map(IMapper <T,V> mapper) {
    MyList<V> list = new MyList<>();
    for(T v : this) {
      list.add(mapper.map(v));
    }
    return list;
  }
}
// in main
MyList<Integer> list1 = new MyList<>(); 
// fill etc..
IMapper<Integer,String> m = (i) -> { return i.toString(); };
// "Change" list
MyList<String> list2 = list1.map(m);

PS: 我认为这种事情在Java中很可能已经实现了 (stream()以及后面的内容我猜?),但这对我来说是一项练习。任何提示都将不胜感激 :)

2个回答

2
您可以将泛型参数定义为map方法上的类型参数,如下所示:
public <V> MyList<V> map(IMapper <T,V> mapper) {
    ...
}

类型参数可以通过两种方式进行定义,一种是在类上定义,另一种是在方法上定义。如果在类上定义,它可以在整个类中使用。如果在方法上定义,则只能在该方法中使用。

在您的情况下,T参数是在类上定义的,而V参数可以在方法上定义。


2
您可以将 map 结果类型添加到您的函数定义中,如下所示:
class MyList<T> extends ArrayList<T> {

public <V> MyList<V> map(IMapper<T, V> mapper) {
    MyList<V> list = new MyList<>();
    for (T v : this) {
        list.add(mapper.map(v));
    }
    return list;
}

示例:

MyList<Integer> number = new MyList<>();

number.add(1);
number.add(2);
number.add(3);

number.map(v -> "#" + v).forEach(System.out::println);

您可以使用Java8流来获得相同的结果,如下所示:

List<Integer> numberStream = new ArrayList<>();
numberStream.add(1);
numberStream.add(2);
numberStream.add(3);
numberStream.stream().map(v -> "#" + v).forEach(System.out::println);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接