gpt4 book ai didi

java - 重构两个几乎相同的方法

转载 作者:行者123 更新时间:2023-12-05 02:35:36 27 4
gpt4 key购买 nike

我有两个几乎相同的方法来过滤列表并返回过滤后的结果。他们的算法是相同的,区别在于第一个函数返回最频繁的元素,第二个函数返回最不频繁的元素:

private static List<List<Character>> filter(List<List<Character>> lines, int charIndex) {
List<List<Character>> result = copyList(lines);

List<List<Character>> startWith0 = new ArrayList<>();
List<List<Character>> startWith1 = new ArrayList<>();

for(int i = 0; i < result.size(); i++) {
List<Character> currentLine = result.get(i);
if (currentLine.get(charIndex) == '1') {
startWith1.add(currentLine);
} else if (currentLine.get(charIndex) == '0') {
startWith0.add(currentLine);
}
}

if (startWith1.size() > startWith0.size() ||
startWith1.size() == startWith0.size()) {
return startWith1;
} else {
return startWith0;
}
}

第二个函数的结尾是这样的:

if (startWith1.size() > startWith0.size() ||
startWith1.size() == startWith0.size()) {
return startWith0;
} else {
return startWith1;
}

我认为这种代码重复不是一个好的程序设计,但我没有看到将函数的第一部分和第二部分划分为不同方法的好方法。

最佳答案

您有几个选择。

  1. 辅助方法

创建一个辅助方法(它是private,它的名字以它是辅助方法的方法开头,虽然在这种情况下,作为 2 的辅助方法,这可能有点棘手) ,它完成所有工作,并有一个状态参数指示如何完成最后一部分。在这种情况下,您的状态参数可以只是一个 boolean。对于其他此类情况,枚举(您也可以将其写入同一源文件,并声明为 private)通常更为合适。

这个助手会以这样的方式结束:

boolean winner = startWith1.size() < startWith0.size();
return most == winner ? startWith1 : startWith0;

并且您当前的 filter 方法变成了一个单行代码:

public List<Character> filterMost(List<List<Character>> lines, int charIdx) {
return filter(lines, charIdx, true);
}

private List<Character> filter(List<List<Character>> lines, int charIdx, boolean most) {
...
}
  1. lambda 表达式

您可以传递一个函数,该函数根据 2 个列表的输入选择要执行的操作。实际上它与第一个答案相同(仍然涉及辅助方法),但不是在辅助程序中编写不同的代码路径,而是在实际方法中编写它们(将它们传递给辅助程序)。它更复杂,但可以使代码更容易维护。一般来说,“更短、更不复杂”的代码总是比“更长、更复杂,但理论上更易于维护”的代码更胜一筹,所以在这种情况下,我怀疑这是正确的做法。但是,在状态更多且不同部分涉及更多的情况下,这可能是更好的答案。看起来像这样:

public List<Character> filterMost(List<List<Character>> lines, int charIdx) {
...
}

public List<Character> filterLeast(List<List<Character>> lines, int charIdx) {
return filter(lines, charIdx, (list0, list1) -> {
if (list0.size() < list1.size()) return list0;
return list1;
};
}

private List<Character> filter(List<List<Character>> lines, int charIdx, BinaryOperator<List<Character>> op) {
...

return op.apply(startWith0, startWith1);
}

关于java - 重构两个几乎相同的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70496538/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com