java - 重构 Java 代码以使其可重用

标签 java refactoring

我最近创建了一个简单的方法,它采用 HashMap 和 LinkedList 作为参数。它遍历 HashMap,找到遵循以下规则的任意两个条目:

  1. 此条目的键总和必须能被 100 整除
  2. 键的总和必须小于 1000
  3. 如果具有相同值的条目出现多次,则应跳过大小写

遵循这些规则的对将被添加到 LinkedList 中。它看起来像这样:

private static void compare2(HashMap<Integer,String> values,List<String>results){
    if (values.size()>1) {
        for(HashMap.Entry<Integer,String> entry1:values.entrySet()){
            for (HashMap.Entry<Integer,String> entry2:values.entrySet()){
                if (entry1.getValue().equals(entry2.getValue()))continue;
                if ((entry1.getKey() + entry2.getKey())%100 == 0 && (entry1.getKey() + entry2.getKey())<1000){
                    results.add(entry1.getKey() + "+" + entry2.getKey() + "=" + entry1.getKey() + entry2.getKey());
                    results.add(entry1.getValue());
                    results.add(entry2.getValue());
                }
            }
        }
    }
}

现在我想创建类似的方法来查找遵循相同规则的 3 个条目。问题是我想重用现有代码,而不是复制/粘贴此代码并进行修改,但我似乎找不到方法来做到这一点。只要结果相同,我不介意是否需要改变方法。

最佳答案

您可以将数字数量设置为参数:N。

您可以继续使用 for 循环,但另一种示例方法可能是使用 lambda 和流重构您的方法,如下所示:

List<List<Map.Entry<Integer, String>>> compareN(HashMap<Integer, String> map, int n) {
    return map.entrySet().stream()
              .map(entry -> listOfNAccompanyingEntriesThatSatisfyTheConditions(entry, emptyList(), map, n - 1))
              .filter(list -> !list.isEmpty())
              .collect(toList());
}

其中方法 listOfNAccompanyingEntriesThatSatisfyTheConditions 是递归方法:

private List<Map.Entry<Integer, String>>
                listOfNAccompanyingEntriesThatSatisfyTheConditions(Map.Entry<Integer, String> newEntry,
                                                                   List<Map.Entry<Integer, String>> selectedEntries,
                                                                   HashMap<Integer, String> originalMap,
                                                                   int n) {

        List<Map.Entry<Integer, String>> newSelectedEntries = join(newEntry, selectedEntries);

        if (n == 0) return satisifiesCondition(newSelectedEntries) ? selectedEntries : emptyList();

        return originalMap.entrySet().stream()
                          .filter(entry -> !selectedEntries.contains(entry) && !entry.equals(newEntry))
                          .map(entry -> listOfNAccompanyingEntriesThatSatisfyTheConditions(entry, newSelectedEntries, originalMap, n - 1))
                          .flatMap(Collection::stream)
                          .collect(toList());
    }

对于每个n,该方法都会对原始完整列表进行另一次拍摄,以累积可能满足要求的子列表。如果达到数字数量(n==0),则递归停止并验证停止条件:

private static boolean satisifiesCondition(List<Map.Entry<Integer, String>> entries) {
    int sum = sumOfTheKeysFrom(entries);
    return sum % 100 == 0 && sum < 1000;
}

但是,这种方法实际上是您的实现的精确翻译,并且仍然存在相同的几个问题。例如,如果您运行它

HashMap<Integer, String> map = new HashMap<Integer, String>() {{
        put(1, "fred");
        put(2, "anja");
        put(24, "tom");
        put(45, "eddy");
        put(22, "lenny");
        put(77, "tommy");
        put(55, "henry");
        put(43, "alfred");
    }};

您将产生双重结果,并且相同条目两次都会产生结果,例如:

[1=fred, 22=lenny, 1=fred, 77=tommy] [2=anja, 55=henry, 2=anja, 43=alfred]

但是,通过一些小调整就可以轻松解决这些问题。

如果您不熟悉流、lambda 或递归,我建议您使用命令式方法来实现相同的功能。另请注意,我并不关心示例代码中的性能,因为我认为这个问题是某种练习。

关于java - 重构 Java 代码以使其可重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46944867/

相关文章:

java - 如何重构这个验证方法

javascript - 如何进一步重构 ctx.fillStyle 的列和行?

java - Java 中的 StringBuilder 初始化

java - 如何将所有包名称重命名为小写

java - 如何设置tomcat spring boot项目上传文件路径?

java - 在 Java 中创建等待线程的 main() 循环的黄金标准是什么

python - Emacs 24,Rope 重命名 : "calculating rename changes", 然后变得无响应

java - 如何在Java中重构大量的if语句?

java - 当一个可能为空时比较字符串

java - 如何使用 Spring JPA 在同一事务中的不同数据库上维护多个 sql 查询