我有四种不同数量参数的方法。如何重构这些方法(是否可以制作单个通用方法?)
public Map<String, Object> addToMap(String name, Object value){
Map<String, Object> map = new HashMap<String, Object>();
map.put(name, value);
return map;
}
public Map<String, Object> addToMap(String name, Object value, String name2, Object value2){
Map<String, Object> map = new HashMap<String, Object>();
map.put(name, value);
map.put(name2, value2);
return map;
}
public Map<String, Object> addToMap(String name, Object value, String name2, Object value2, String name3, Object value3){
Map<String, Object> map = new HashMap<String, Object>();
map.put(name, value);
map.put(name2, value2);
map.put(name3, value3);
return map;
}
public Map<String, Object> addToMap(String name, Object value, String name2, Object value2, String name3, Object value3, String name4, Object value4){
Map<String, Object> map = new HashMap<String, Object>();
map.put(name, value);
map.put(name2, value2);
map.put(name3, value3);
map.put(name4, value4);
return map;
}
Run Code Online (Sandbox Code Playgroud)
这该怎么做?
你这样做是错的。这个东西已经存在了;使用例如番石榴的ImmutableMap.builder,或使用现有的Map.of(). 这不是很一样:您的方法栈“会有限制”,这是一个Map<String, Object>,但大概不值得重写ImmutableMap或Map.of API的只是利益。
请注意,您的命名已关闭。addToMap不是一个好的方法名称,特别是对于创建全新地图的方法。addToMap只是尖叫“这将提供的参数添加到现有地图中”,而这些方法不会这样做。所以我冒昧地为你修正了你的名字。这些方法也没有状态,所以应该是静态的。
选项#1:传递到私有方法。
public static Map<String, Object> newMap(String name, Object value) {
return newMap0(name, value);
}
public static Map<String, Object> newMap(String name1, Object value2, String name1, Object value2) {
return newMap0(name1, value1, name2, value2);
}
public static Map<String, Object> newMap(String name1, Object value1, String name2, Object value2, String name3, Object value3) {
return newMap0(name1, value1, name2, value2, name3, value3);
}
// and so on
private static Map<String, Object> newMap0(Object... v) {
assert v.length % 2 == 0;
var out = new HashMap<String, Object>();
for (int i = 0; i < v.length; i +=2) out.put((String) v[i], v[i + 1]);
return out;
}
Run Code Online (Sandbox Code Playgroud)
最后一种方法在类型上是一场灾难(自由地允许传入奇数个参数或非字符串键),这就是为什么它没有业务成为您的 API 的一部分。这就是为什么它是私人的。
选项2:建筑商
查看 ImmutableMap.builder 以获得完整的论文。这是一大堆复杂的代码,但它提供了一个相当不错的 API。您的目标是呼叫者可以这样做:
YourUtilityClassThing.newMap()
.put("a", 5)
.put("b", 10)
.build();
Run Code Online (Sandbox Code Playgroud)
这具有“类型安全”的显着优势(您只能传入字符串键和任何对象作为值),以及允许无限数量的 k/v 对。缺点是,您的 API 需要大量代码才能完成这项工作。
如果你喜欢这种方法,我怎么强调你不应该重新发明这个轮子并使用例如番石榴的 ImmutableMap.Builder 代替。
选项 3:元组类型
制作一个显式元组类型并编写您的 API 文档,以表明它在不积极使用静态导入的情况下无法使用,但是对于静态导入,这很好。调用者最终会写:
import static com.foo.YourThingie.*;
....
newMap(p("a", 5), p("b", 5));
Run Code Online (Sandbox Code Playgroud)
您需要相当多的代码YourThingie才能将它们结合在一起,但它是类型安全的并且支持无限参数:
class YourThingie {
public static final class KeyValuePair {
String key; Object value;
}
public static KeyValuePair p(String key, Object value) {
KeyValuePair kvp = new KeyValuePair();
kvp.key = key; kvp.value = value;
return kvp;
}
public static Map<String, Object> newMap(KeyValuePair... pairs) {
var out = new HashMap<String, Object>();
for (var pair : pairs) out.put(pair.key, pair.value);
return out;
}
}
Run Code Online (Sandbox Code Playgroud)
您可能想让 KeyValuePair 成为一个合适的类:不可变的,带有一个 2 参数的构造函数和一个合适的 toString/equals/hashCode impl。这要么涉及一整页的样板文件,要么使用 JDK16 的记录,或者使用 Lombok 项目@Value来获得它(免责声明:众所周知,我对lombok做出了很多贡献)。
| 归档时间: |
|
| 查看次数: |
60 次 |
| 最近记录: |