我有两种类似的方法。其中一个打印出来的东西,其中一个可以节省一些东西。如您所见,有很多重复的代码。我该如何重构它并删除这个重复?
public static void printSomething(List<String> list) {
for (String item : list) {
if (item.contains("aaa")) {
System.out.println("aaa" + item);
}
if (item.contains("bbb")) {
System.out.println("bbb" + item);
} else {
System.out.println(item);
}
}
}
public static Map<String, String> getSomething(List<String> list) {
Map<String, String> map = new HashMap<String, String>();
for (String item : list) {
if (item.contains("aaa")) {
map.put("aaa", item);
}
if (item.contains("bbb")) {
map.put("bbb", item);
} else {
//do nothing
}
}
return map;
}
更新:
当方法不完全相似时,代码已更新以解决问题
具有方法操作(T t)的通用接口操作可以减少代码。
public interface Action<E> {
void action(E e);
}
例:
public static void forEach(List<String> list, Action <String> action) {
for(String s : list){
action.action(s);
}
现在您只需要2个不同的Action实现。
如果您不想创建类,可以使用匿名类型。
如果你知道c#,这与lambdas类似。
编辑:
使用匿名类型:
public static Map<String, String> getSomething(List<String> list) {
final Map<String, String> map = new HashMap<String, String>();
forEach(list, new Action<String>() {
@Override
public void action(String e) {
if (e.contains("aaa")) {
map.put("aaa", e);
}
if (e.contains("bbb")) {
map.put("bbb", e);
} else {
// do nothing
}
}
});
return map;
}
创建课程:
public static Map<String, String> getSomething2(List<String> list) {
final Map<String, String> map = new HashMap<String, String>();
forEach(list, new ListToMapAction(map));
return map;
}
public class ListToMapAction implements Action<String> {
Map<String, String> map;
public ListToMapAction(Map<String, String> map) {
this.map = map;
}
@Override
public void action(String e) {
if (e.contains("aaa")) {
map.put("aaa", e);
}
if (e.contains("bbb")) {
map.put("bbb", e);
} else {
// do nothing
}
}
}
假设其中的顺序 println
的 "aaa"
和 "bbb"
出现没关系,你可以替换执行 printSomething
同
public static void printSomething(List<String> list) {
Map<String, String> map = getSomething(list);
for(Map.Entry<String, String> entry : map) {
System.out.println(entry.getKey() + entry.getValue());
}
}
在具有第一类函数的编程语言中,您将传递一个函数作为参数,指示您想在循环内执行的操作(例如,请参阅下面的更新)。 Java将在版本8中使用lambdas,但它们并不完全符合要求。
在当前的Java状态中,你必须解决一些问题 - 例如,将额外的参数传递给方法;或者你可以传递实现接口的匿名内部类,但恕我直言,甚至比我建议的更丑:
static void printSomething(List<String> list, boolean print)
如果 print
是 true
然后在循环内打印,否则添加到 Map
。当然,你必须添加几个 if
在循环内部检查这种情况,并在开始时,一个额外的 if
确定是否 Map
是要初始化。无论哪种方式,该方法返回一个 Map
,但是 Map
可 null
用于印刷案例。这就是我的意思:
static Map<String, String> processSomething(List<String> list, boolean print) {
Map<String, String> map = null;
if (!print)
map = new HashMap<String, String>();
for (String item : list) {
if (item.contains("aaa")) {
if (print)
System.out.println("aaa" + item);
else
map.put("aaa", item);
}
if (item.contains("bbb")) {
if (print)
System.out.println("bbb" + item);
else
map.put("bbb", item);
} else if (print) {
System.out.println(item);
}
}
return map;
}
UPDATE
例如,在Python中 - 它允许将函数作为参数传递,这就是你如何以优雅的方式解决问题:
def processSomething(lst, func):
result = None
for item in lst:
if 'aaa' in item:
result = func(item, 'aaa', result)
elif 'bbb' in item:
result = func(item, 'bbb', result)
else:
result = func(item, '', result)
return result
def printer(item, key, result):
print key + item
def mapper(item, key, result):
if not result:
result = {}
if key:
result[key] = item
return result
看看它怎么运作:
processSomething(['aaa', 'bbb', 'ccc'], printer)
=> aaaaaa
bbbbbb
ccc
processSomething(['aaa', 'bbb', 'ccc'], mapper)
=> {'aaa': 'aaa', 'bbb': 'bbb'}