How can I remove duplicated code between classes?
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)
}
}
Another example using Java 8 features - BiFunction
interface with lambda expression:
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);
Implementation:
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);
}
}
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);
}
}
}