I have 2 class: RecursiveFibonacci and MemorizedRecursiveFibonacci. This is what I have so far.
RecursiveFibonacci Class
public class SimpleRecursiveFibonacci {
public BigInteger fibonacci(int n) {
if(n < 2) {
return BigInteger.ONE;
}
return fibonacci(n - 2).add(fibonacci(n - 1));
}
}
and MemorizedRecursiveFibonacci Class
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);
}
}
As I see, there are some duplicated code in MemorizedRecursiveFibonacci Class
if(n < 2) {
return BigInteger.ONE;
and
BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));
How can I keep it DRY? remove duplicated code?
Guidelines to help reduce repetitive codeIf you see some similar code written twice, consider pulling it out into a shared function. If the code is already systematically duplicated throughout the code, then consider working with the team to clean it up and get time to dedicate to the task. Isolate different concerns.
The conventional approach to reduce this kind of code duplication is to move the common code to a member function, which can be called from all the constructors. Usually, that member function is called init.
Code Inspection: Duplicated code fragmentReports duplicated blocks of code from the selected scope: the same file or the entire project. The inspection features quick-fixes that help you to set the size of detected duplicates, navigate to repetitive code fragments, and compare them in a tool window.
How about something like this:
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);
}
}
}
Maybe this is an option... but not the best i think.
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)),
}
}
public class MemoizedRecursiveFibonacci extends SimpleRecursiveFibonacci{
private Map<Integer, BigInteger> cache = new HashMap<>();
@Override
protected BigInteger calculate(int n) {
if(!cache.containsKey(n)){
BigInteger currentFibonacci = super.calculate(n);
cache.put(n, currentFibonacci);
}
return cache.get(n)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With