Java中含多ArrayList类的同类逻辑方法通用化实现咨询
通用化处理重复逻辑方法的几种方案
嘿,这个场景太常见了!写一堆几乎一模一样的方法不仅冗余,后期改需求的时候还得挨个改,简直是给自己挖坑。下面给你分享几个实用的通用化方案,根据你的Java版本和实际情况选就行:
方案一:Java 8+ 用函数式接口+通用方法(最推荐)
利用Java 8引入的Lambda表达式和函数式接口,我们可以把重复的遍历、提取名称的逻辑完全抽成一个通用方法,然后每个具体的获取方法只需要传入对应的列表和名称提取逻辑就行。
代码示例:
import java.util.ArrayList; import java.util.List; import java.util.function.Function; public class Foo { private ArrayList<Rapper> rapperList = new ArrayList<>(); private ArrayList<Musician> musicianList = new ArrayList<>(); private ArrayList<Stadium> stadiumList = new ArrayList<>(); // 抽取所有重复逻辑的通用方法 private <T> List<String> getNames(List<T> itemList, Function<T, String> nameExtractor) { ArrayList<String> nameList = new ArrayList<>(); for (T item : itemList) { nameList.add(nameExtractor.apply(item)); } return nameList; } // 原来的方法现在只需要一行调用 public List<String> getRapperName() { return getNames(rapperList, Rapper::getName); } public List<String> getMusicianName() { return getNames(musicianList, Musician::getName); } public List<String> getStadiumName() { return getNames(stadiumList, Stadium::getName); } }
为什么推荐这个?
- 逻辑只需要维护一处,后续要改遍历逻辑(比如过滤空值、排序),只改通用方法就行;
- 新增类似的列表和获取方法时,只需要加一行调用,成本极低;
- 方法引用
Rapper::getName的写法可读性拉满,一眼就能看懂是在提取什么。
如果想更简洁,还可以用Stream API重构通用方法:
import java.util.stream.Collectors; private <T> List<String> getNames(List<T> itemList, Function<T, String> nameExtractor) { return itemList.stream() .map(nameExtractor) .collect(Collectors.toList()); }
方案二:Java 8之前版本?用统一接口约束实体类
如果你的项目还在使用Java 7或更早的版本,没法用Lambda,那可以让所有实体类实现一个统一的接口,把getName()方法抽象出来。
代码示例:
首先定义一个接口:
public interface Named { String getName(); }
然后让所有实体类实现这个接口:
public class Rapper implements Named { // 原有的属性和方法,确保getName()已实现 @Override public String getName() { // 返回名称逻辑 } } // Musician、Stadium类同理,都实现Named接口
最后修改Foo类,写一个接收List<? extends Named>的通用方法:
public class Foo { private ArrayList<Rapper> rapperList = new ArrayList<>(); private ArrayList<Musician> musicianList = new ArrayList<>(); private ArrayList<Stadium> stadiumList = new ArrayList<>(); private List<String> getNames(List<? extends Named> namedList) { ArrayList<String> nameList = new ArrayList<>(); for (Named item : namedList) { nameList.add(item.getName()); } return nameList; } public List<String> getRapperName() { return getNames(rapperList); } public List<String> getMusicianName() { return getNames(musicianList); } public List<String> getStadiumName() { return getNames(stadiumList); } }
这个方案的缺点是需要修改所有实体类的代码,如果实体类是第三方库的、没法修改的,那这个方案就不适用了。
方案三:直接用Stream API简化每个方法(轻量方案)
如果觉得写通用方法有点“重”,也可以直接在每个获取方法里用Stream API一行搞定,虽然还是每个方法单独写,但代码量极少,维护成本也很低:
import java.util.stream.Collectors; public class Foo { private ArrayList<Rapper> rapperList = new ArrayList<>(); private ArrayList<Musician> musicianList = new ArrayList<>(); private ArrayList<Stadium> stadiumList = new ArrayList<>(); public List<String> getRapperName() { return rapperList.stream().map(Rapper::getName).collect(Collectors.toList()); } public List<String> getMusicianName() { return musicianList.stream().map(Musician::getName).collect(Collectors.toList()); } public List<String> getStadiumName() { return stadiumList.stream().map(Stadium::getName).collect(Collectors.toList()); } }
这种方式适合不想额外写通用方法的场景,代码简洁直观,后期修改单个方法的逻辑也很方便。
内容的提问来源于stack exchange,提问作者bigfocalchord
相关产品推荐
相关产品推荐

