如何从我的代码中删除重复

时间:2013-04-23 13:51:37

标签: java refactoring

我有两种类似的方法。其中一个打印出来的东西,其中一个可以节省一些东西。正如您所看到的,有很多重复的代码。我该如何重构它并删除这个重复?

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;
}

更新:

当方法不完全相似时,代码已更新以解决问题

3 个答案:

答案 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)

如果printtrue,则在循环内打印,否则添加到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}}