Java方法单次调用需返回两种不同列表,如何优雅实现?
优雅解决Java方法返回多个列表的方案
1. 自定义专用返回类(最推荐)
专门为这个方法的返回值创建一个语义明确的类,完全避免类型转换风险,可读性拉满。
public class DataFetchResult { private final List<ObjectA> objectAList; private final List<List<String>> groupedStrings; // 构造方法直接初始化,保证不可变性 public DataFetchResult(List<ObjectA> objectAList, List<List<String>> groupedStrings) { this.objectAList = new ArrayList<>(objectAList); // 可选:拷贝避免外部修改 this.groupedStrings = new ArrayList<>(groupedStrings); } // 仅提供Getter,不暴露Setter public List<ObjectA> getObjectAList() { return new ArrayList<>(objectAList); // 可选:返回拷贝保证内部数据安全 } public List<List<String>> getGroupedStrings() { return new ArrayList<>(groupedStrings); } // 可选:重写toString方便调试 @Override public String toString() { return "DataFetchResult{" + "objectAList=" + objectAList + ", groupedStrings=" + groupedStrings + '}'; } }
使用示例:
public DataFetchResult fetchRequiredData() { List<ObjectA> objList = new ArrayList<>(); List<List<String>> strGroups = new ArrayList<>(); // 业务逻辑填充数据 return new DataFetchResult(objList, strGroups); } // 调用方 DataFetchResult result = fetchRequiredData(); List<ObjectA> objects = result.getObjectAList(); List<List<String>> stringGroups = result.getGroupedStrings();
2. Java 16+ 用Record简化代码
如果你的项目用Java 16及以上,用Record可以省去手动写Getter、构造方法的麻烦,自动生成所有必要方法:
public record DataFetchResult(List<ObjectA> objectAList, List<List<String>> groupedStrings) {}
使用方式和自定义类完全一致,代码量骤减,适合不需要额外逻辑的纯返回场景。
3. 通用Pair类(临时场景可选)
如果不想自定义类,也可以用通用Pair来封装,但要注意语义不如自定义类清晰:
可以自己实现一个简单的Pair:
public class Pair<L, R> { private final L left; private final R right; public Pair(L left, R right) { this.left = left; this.right = right; } public L getLeft() { return left; } public R getRight() { return right; } }
使用示例:
public Pair<List<ObjectA>, List<List<String>>> fetchRequiredData() { List<ObjectA> objList = new ArrayList<>(); List<List<String>> strGroups = new ArrayList<>(); // 填充数据 return new Pair<>(objList, strGroups); } // 调用方 Pair<List<ObjectA>, List<List<String>>> result = fetchRequiredData(); List<ObjectA> objects = result.getLeft(); List<List<String>> stringGroups = result.getRight();
4. 传入容器参数(不推荐)
这种方式是把列表作为参数传入方法,方法内部直接填充数据,但可读性差,容易产生副作用(调用方可能没意识到参数会被修改):
public void fetchRequiredData(List<ObjectA> objectAList, List<List<String>> groupedStrings) { // 直接往传入的列表中添加数据 objectAList.add(new ObjectA()); groupedStrings.add(Arrays.asList("foo", "bar")); }
使用示例:
List<ObjectA> objList = new ArrayList<>(); List<List<String>> strGroups = new ArrayList<>(); fetchRequiredData(objList, strGroups);
方案对比总结
- 优先选自定义返回类/Record:类型安全、语义清晰,维护成本最低
- 临时简单场景可以用Pair:代码简洁但语义弱
- 尽量避免用Map或参数填充的方式:前者有类型转换风险,后者可读性差
内容的提问来源于stack exchange,提问作者Sainadh Makeneni
相关产品推荐
相关产品推荐

