Java 如何删除类之间的重复代码?
我有两门课:递归斐波那契和记忆递归斐波那契。这就是我目前所拥有的 递归斐波那契类Java 如何删除类之间的重复代码?,java,dry,Java,Dry,我有两门课:递归斐波那契和记忆递归斐波那契。这就是我目前所拥有的 递归斐波那契类 public class SimpleRecursiveFibonacci { public BigInteger fibonacci(int n) { if(n < 2) { return BigInteger.ONE; } return fibonacci(n - 2).add(fibonacci(n - 1)); } } pub
public class SimpleRecursiveFibonacci {
public BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
return fibonacci(n - 2).add(fibonacci(n - 1));
}
}
public class MemoizedRecursiveFibonacci {
private Map<Integer, BigInteger> cache = new HashMap<>();
public BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
if(!cache.containsKey(n)){
BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));
cache.put(n, currentFibonacci);
}
return cache.get(n);
}
}
我怎样才能保持它干燥?删除重复的代码?使用静态方法:
public class SimpleRecursiveFibonacci {
public static BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
return fibonacci(n - 2).add(fibonacci(n - 1));
}
}
public class MemoizedRecursiveFibonacci {
private Map<Integer, BigInteger> cache = new HashMap<>();
public BigInteger fibonacci(int n) {
if(!cache.containsKey(n)){
BigInteger currentFibonacci = SimpleRecursiveFibonacci.fibonacci(n);
cache.put(n, currentFibonacci);
}
return cache.get(n);
}
}
公共类SimpleRecursiveFibonacci{
公共静态双整数fibonacci(int n){
if(n<2){
返回BigInteger.1;
}
返回fibonacci(n-2).add(fibonacci(n-1));
}
}
公共类MemorizedRecursiveFibonacci{
私有映射缓存=新的HashMap();
公共大整数斐波那契(整数n){
如果(!cache.containsKey(n)){
BigInteger currentFibonacci=SimpleRecursiveFibonacci.fibonacci(n);
cache.put(n,currentFibonacci);
}
返回cache.get(n);
}
}
也许这是一个选项。。。但不是我认为最好的
public class SimpleRecursiveFibonacci {
public BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
return calculate(n);
}
protected BigInteger calculate(int n){
return fibonacci(n - 2).add(fibonacci(n - 1)),
}
公共类SimpleRecursiveFibonacci{
公共大整数斐波那契(整数n){
if(n<2){
返回BigInteger.1;
}
返回计算(n);
}
受保护的BigInteger计算(int n){
返回fibonacci(n-2).add(fibonacci(n-1)),
}
}
公共类memorizedRecursiveFibonacci扩展了SimpleRecursiveFibonacci{
私有映射缓存=新的HashMap();
@凌驾
受保护的BigInteger计算(int n){
如果(!cache.containsKey(n)){
BigInteger currentFibonacci=super.calculate(n);
cache.put(n,currentFibonacci);
}
返回cache.get(n)
}
}像这样的东西怎么样:
public class SimpleRecursiveFibonacci {
/** Gets the fibonacci value for n */
public final BigInteger fibonacci(int n) {
if (n == 0) {
return BigInteger.ZERO;
} else if (n == 1) {
return BigInteger.ONE;
}
return getFibonacci(n);
}
/** Recursively calculates the fibonacci by adding the two previous fibonacci. */
protected final BigInteger calculateFibbonacci(int n) {
return fibonacci(n - 2).add(fibonacci(n - 1));
}
/**
* Somehow get the fibonacci value for n.
* Could be by calculation, getting it from a cache, or anything.
* Defaults to calculation.
*/
protected BigInteger getFibonacci(int n) {
return calculateFibbonacci(n);
}
}
public class MemoizedRecursiveFibonacci extends SimpleRecursiveFibonacci {
// Cache using an array list as recommended by user @DodgyCodeException
private ArrayList<BigInteger> cache = new ArrayList<>();
@Override
protected BigInteger getFibonacci(int n) {
if (cache.size() < n) {
BigInteger fib = calculateFibbonacci(n);
cache.add(fib);
return fib;
} else {
return cache.get(n - 1);
}
}
}
公共类SimpleRecursiveFibonacci{
/**获取n的斐波那契值*/
公共最终大整数斐波那契(整数n){
如果(n==0){
返回biginger.ZERO;
}else如果(n==1){
返回BigInteger.1;
}
返回fibonacci(n);
}
/**通过将前面的两个fibonacci相加,递归计算fibonacci*/
受保护的最终大整数calculateFibbonacci(int n){
返回fibonacci(n-2).add(fibonacci(n-1));
}
/**
*以某种方式得到n的斐波那契值。
*可以通过计算,从缓存中获取,或者其他任何方式。
*默认为“计算”。
*/
受保护的BigInteger getFibonacci(int n){
返回值计算为bbonacci(n);
}
}
公共类memorizedRecursiveFibonacci扩展了SimpleRecursiveFibonacci{
//使用用户@DodgyCodeException建议的数组列表进行缓存
私有ArrayList缓存=新建ArrayList();
@凌驾
受保护的BigInteger getFibonacci(int n){
if(cache.size()
另一个使用Java 8功能的示例-与lambda表达式的接口:
BiFunction<Fibonacci, Integer, BigInteger> func = (fibonacci, n) -> {
if (n < 2) {
return BigInteger.ONE;
}
return fibonacci.calc(n - 2).add(fibonacci.calc(n - 1));
};
new CachedFibonacci(func).calc(100);
BiFunction func=(斐波那契,n)->{
if(n<2){
返回BigInteger.1;
}
返回fibonacci.calc(n-2).add(fibonacci.calc(n-1));
};
新CachedFibonacci(func).calc(100);
实施:
interface Fibonacci {
BigInteger calc(int n);
}
class SimpleFibonacci implements Fibonacci {
private BiFunction<Fibonacci, Integer, BigInteger> fibonacci;
SimpleFibonacci(BiFunction<Fibonacci, Integer, BigInteger> fibonacci) {
this.fibonacci = fibonacci;
}
public BigInteger calc(int n) {
return fibonacci.apply(this, n);
}
}
class CachedFibonacci implements Fibonacci {
private BiFunction<Fibonacci, Integer, BigInteger> fibonacci;
private Map<Integer, BigInteger> cache = new HashMap<>();
CachedFibonacci(BiFunction<Fibonacci, Integer, BigInteger> fibonacci) {
this.fibonacci = fibonacci;
}
public BigInteger calc(int n) {
if (!cache.containsKey(n)) {
cache.put(n, fibonacci.apply(this, n));
}
return cache.get(n);
}
}
接口斐波那契{
大整数计算(整数n);
}
类SimpleFibonacci实现Fibonacci{
私有双函数斐波那契;
SimpleFibonacci(双函数fibonacci){
fibonacci=fibonacci;
}
公共大整数计算(整数n){
返回fibonacci.apply(这个,n);
}
}
类cachedfibancci实现斐波那契{
私有双函数斐波那契;
私有映射缓存=新的HashMap();
cachedfbonacci(双函数fibonacci){
fibonacci=fibonacci;
}
公共大整数计算(整数n){
如果(!cache.containsKey(n)){
put(n,fibonacci.apply(this,n));
}
返回cache.get(n);
}
}
这将只记忆最终值,而不是中间值。使用MemoizedRecursiveFibonacci并实现类似public BigInteger fibonacci(int n,bool useCache)的方法,让调用方使用或不使用缓存怎么样?或者使用属性@Cacheable来修饰方法以获得缓存?一个不相关的观察结果:记忆版本总是用连续的整数键填充HashMap。因此,使用ArrayList并使用索引而不是键会更有效。事实上这并不坏。经典模板法:)我唯一的改进是提前返回currentFibonacci
,而不是再次查找。类似于我的想法。我使用第三种方法来“获取”斐波那契值,可以从缓存中获取,也可以通过重新计算来获取。这是可行的,它完成了它应该做的事情,但我发现有点难以遵循。它似乎以减少可读性来换取消除重复。
public class SimpleRecursiveFibonacci {
/** Gets the fibonacci value for n */
public final BigInteger fibonacci(int n) {
if (n == 0) {
return BigInteger.ZERO;
} else if (n == 1) {
return BigInteger.ONE;
}
return getFibonacci(n);
}
/** Recursively calculates the fibonacci by adding the two previous fibonacci. */
protected final BigInteger calculateFibbonacci(int n) {
return fibonacci(n - 2).add(fibonacci(n - 1));
}
/**
* Somehow get the fibonacci value for n.
* Could be by calculation, getting it from a cache, or anything.
* Defaults to calculation.
*/
protected BigInteger getFibonacci(int n) {
return calculateFibbonacci(n);
}
}
public class MemoizedRecursiveFibonacci extends SimpleRecursiveFibonacci {
// Cache using an array list as recommended by user @DodgyCodeException
private ArrayList<BigInteger> cache = new ArrayList<>();
@Override
protected BigInteger getFibonacci(int n) {
if (cache.size() < n) {
BigInteger fib = calculateFibbonacci(n);
cache.add(fib);
return fib;
} else {
return cache.get(n - 1);
}
}
}
BiFunction<Fibonacci, Integer, BigInteger> func = (fibonacci, n) -> {
if (n < 2) {
return BigInteger.ONE;
}
return fibonacci.calc(n - 2).add(fibonacci.calc(n - 1));
};
new CachedFibonacci(func).calc(100);
interface Fibonacci {
BigInteger calc(int n);
}
class SimpleFibonacci implements Fibonacci {
private BiFunction<Fibonacci, Integer, BigInteger> fibonacci;
SimpleFibonacci(BiFunction<Fibonacci, Integer, BigInteger> fibonacci) {
this.fibonacci = fibonacci;
}
public BigInteger calc(int n) {
return fibonacci.apply(this, n);
}
}
class CachedFibonacci implements Fibonacci {
private BiFunction<Fibonacci, Integer, BigInteger> fibonacci;
private Map<Integer, BigInteger> cache = new HashMap<>();
CachedFibonacci(BiFunction<Fibonacci, Integer, BigInteger> fibonacci) {
this.fibonacci = fibonacci;
}
public BigInteger calc(int n) {
if (!cache.containsKey(n)) {
cache.put(n, fibonacci.apply(this, n));
}
return cache.get(n);
}
}