我有两种类似的方法。其中一个打印出来的东西,其中一个可以节省一些东西。正如您所看到的,有很多重复的代码。我该如何重构它并删除这个重复?
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;
}
更新:
当方法不完全相似时,代码已更新以解决问题
答案 0 :(得分:7)
假设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());
}
}
答案 1 :(得分:3)
具有方法操作(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
}
}
}
答案 2 :(得分:2)
在具有一流函数的编程语言中,您将传递一个函数作为参数,指示您想在循环内执行的操作(例如,请参阅下面的更新)。 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;
}
,用于打印案例。这就是我的意思:
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
<强>更新强>
例如,在Python中 - 它允许将函数作为参数传递,这就是你如何以优雅的方式解决问题:
processSomething(['aaa', 'bbb', 'ccc'], printer)
=> aaaaaa
bbbbbb
ccc
processSomething(['aaa', 'bbb', 'ccc'], mapper)
=> {'aaa': 'aaa', 'bbb': 'bbb'}
了解它的工作原理:
{{1}}