Java泛型问题:为自定义List实现元素映射转换方法
嘿,这个问题我当初刚啃Java泛型的时候也纠结过!咱们一步步拆解,保证你搞明白~
首先得把基础的自定义函数式接口IMapper定义对,这是整个映射逻辑的核心:
@FunctionalInterface public interface IMapper<S, T> { // 接收源类型S的元素,返回转换后的目标类型T元素 T map(S source); }
这里用<S, T>两个泛型参数分别代表「源元素类型」和「目标元素类型」,符合函数式接口单一抽象方法的要求。
接下来就是你自定义List类里的映射方法签名了。假设你的自定义List叫MyCustomList<E>(E是当前列表的元素类型),这个map方法得是个泛型方法——因为转换后的新列表元素类型和原列表不一样,需要引入新的泛型参数T:
public class MyCustomList<E> { // 假设内部用List<E>存储元素 private List<E> elements = new ArrayList<>(); // 核心的map方法签名 public <T> MyCustomList<T> map(IMapper<? super E, ? extends T> mapper) { MyCustomList<T> resultList = new MyCustomList<>(); // 遍历原列表,用mapper转换每个元素后加入新列表 for (E element : elements) { resultList.add(mapper.map(element)); } return resultList; } // 别忘了补充add、构造器这些基础方法 public void add(E element) { elements.add(element); } }
这里解释下签名里的细节,保证灵活性拉满:
<T>:放在方法返回值前声明,说明这是个泛型方法,T是转换后的目标元素类型,调用时会自动推断(或者你也可以显式指定)。IMapper<? super E, ? extends T>:用通配符遵循PECS原则:? super E:允许接收能处理E父类型的mapper(比如原元素是String,mapper可以接受CharSequence类型的输入),毕竟父类型能兼容子类型,这样mapper的适用范围更广。? extends T:允许mapper返回T的子类型(比如目标类型是Number,mapper可以返回Integer),因为子类型对象可以安全存入T类型的列表。
如果你的需求是返回标准List<T>而非自定义列表,把签名改成这样就行:
public <T> List<T> map(IMapper<? super E, ? extends T> mapper) { List<T> resultList = new ArrayList<>(); // 遍历转换逻辑同上 return resultList; }
最后给个调用示例,一看就懂:
// 初始化一个存字符串的自定义列表 MyCustomList<String> stringList = new MyCustomList<>(); stringList.add("100"); stringList.add("200"); stringList.add("300"); // 用lambda表达式作为IMapper实现,把字符串转成Integer MyCustomList<Integer> intList = stringList.map(s -> Integer.parseInt(s));
内容的提问来源于stack exchange,提问作者michelson
相关产品推荐
相关产品推荐

