How to implement a generic calculator class - java

An instructor recently set the task of coding a small calculator class for integers and doubles. As worded the assignment is covered by the following:
public final class Calculator {
public int add(int augend, int addend) { return augend + addend; }
public double add(double augend, double addend) { return augend + addend; }
public int subtract(int minuend, int subtrahend) { return minuend - subtrahend; }
public double subtract(double minuend, double subtrahend) { return minuend - subtrahend; }
public int divide(int dividend, int divisor) { return dividend / divisor; }
public double divide(double dividend, double divisor) { return dividend / divisor; }
public int multiply(int multiplicand, int multiplier) { return multiplicand * multiplier; }
public double multiply(double multiplicand, double multiplier) { return multiplicand * multiplier; }
}
I am wondering though, given that the methods are functionally the same if the
duplication of the functionality could be removed somehow by the use of generics?
I have tried a couple of routes to make this happen, the latest is to make the entire class generic as follows, but keep getting stuck where it comes to actually applying the mathematical operations to the variables
public class Calculator<T extends Number> {
public T add(T augend, T addend) {
// addition is the same for any number type
return augend + addend; // "operator '+' cannot be applied to 'T','T'"
}
// etc...
}
The error message, or a variant thereof, comes into play with whichever method I try... Is there a better way to do this? (with or without generics)

I don't think you can apply operators on Type T. Since during compilation this will get replaced with the object in case of unbounded Type and with the first bound in case of bounded type. Refer https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html. In the below code, it would get replaced with Number but Number doesn't work with operators.
You can create an generic interface like this :
interface Calc<T extends Number>{
T add(T a, T b);
}
Now create Concrete Classes for Integer and Doubles
class IntegerCalc implements Calc<Integer>{
#Override
public Integer add(Integer a, Integer b) {
return a+b;
}
}
class DoubleCalc implements Calc<Double>{
#Override
public Double add(Double a, Double b) {
return a+b;
}
}

You did it fine! Pretty simple and reliable code. Good Job.
P.S. Think about that generics work with Object, and Integer and int is not absolutely the same thing. If you can work with a simple type, you should do it and avoid wrappers.

Related

Return Comparator's compare method using a double?

So I have a class to compare the rating of a film. It implements the comparator class as seen below:
public class FilmComparator implements Comparator<Film> {
private Map<Film, List<Rating>> ratings;
public FilmComparator(Map<Film, List<Rating>> ratings) {
this.ratings = ratings;
}
#Override
public int compare(Film o1, Film o2) {
double average1 = average(o1);
double average2 = average(o2);
return average2 - average1; // I cant do this because it need to return an int
}
private double average(Film f) {
int sum = 0;
for (Rating r : ratings.get(f)) {
sum += r.getValue();
}
return sum / ratings.get(f).size();
}
}
As you can see, the average might not always be an integer. I am wondering how I would be able to have a more accurate compare. For example, I am having issues when the average returns 3.6 for one object but 3.0 for the other. To the compare method, the are the same but I need to show a difference. Is this possible?
Simple, let Double do the work for you. Do
return Double.compare(average1, average2); // or swap if desired

Reusing same function in different ways

I have got class like this
class Calculate {
int operation(int a, int b){
return Math.max(a,b);
}
int calc(int a, int b){
int x=100+a*b;
int y=a+a*b;
retun operation(x,y);
}
int calc1(int a, int b){
int x=100+a*b;
int y=b+a*b;
return operation(x,y);
}
}
Now I make two objects of this class as
Calculate obj1=new Calculate();
Calculate obj2=new Calculate();
I want function operation of Class calculate to act like returning maximum of two values for obj1, and return minimum of two values for obj2. Can this be done?
I could only think of creation two different classes Calculate1 and Calculate2 and defining operation as maximum in Calculate1 and minimum in Calculate2 and defining rest thing as same as it is. I hope some easier method also exist without defining two classes.
You can pass the operation to the constructor as an IntBinaryOperator, for example:
class Calculate {
private final IntBinaryOperator op;
public Calculate(IntBinaryOperator operator) {
this.op = operator;
}
int operation(int a, int b) {
return op.applyAsInt(a, b);
}
}
Now you can write:
Calculate c1 = new Calculate(Math::max);
Calculate c2 = new Calculate(Math::min);
And adding an operation is easy - say you want the sum instead of min or max:
Calculate c3 = new Calculate((x, y) -> x + y);
You can override the operation method.
If you don't want to create explicit sub-classes, you can do this with anonymous classes :
Calculate obj1=new Calculate();
Calculate obj2=new Calculate() {
int operation(int a, int b){
return Math.min(a,b);
}
};
obj1.operation(a,b) // calculates maximum
obj2.operation(a,b) // calculates minimum
You can use an OOP concept called Inheritance
public abstract class Calculate {
public abstract int operation(int a, int b);
int calc(int a, int b){
int x=100+a*b;
int y=a+a*b;
return operation(x,y);
}
int calc1(int a, int b){
int x=100+a*b;
int y=b+a*b;
return operation(x,y);
}
}
class Obj1 extends Calculate{
#Override
public int operation(int a, int b) {
return Math.min(a, b);
}
}
class Obj2 extends Calculate{
#Override
public int operation(int a, int b) {
return Math.max(a, b);
}
}
Each new class implements it own method of operation.
You can have something like this :
interface Operation
{
int operation(int a,int b);
}
class Calculate
{
Operation operation;
//rest of class
}
you use the class like this :
Calculate obj1=new Calculate();
obj1.operation=(a,b)->Math.max(a,b);
Calculate obj2=new Calculate();
obj2.operation=(a,b)->Math.max(a,b);
A couple of notes :
you can add a constructor that takes Operation to initialize operation variable.
you should probably have a call method in Calculate class and make operation private for better encapsulation
operation is probably better to be final
This solution may not be as straight forward as other languages but it's the best I can have.
Languages that supported functions as first class citizens from the beginning would make that easier because you can have a function variable which you assign,pass,return just like any variable.
In java we have to use interfaces and anonymous classes to support this, the lambda expressions above were added to java 8 so for java 7 we would write the above like this :
Calculate obj1=new Calculate();
obj1.operation=new Operation{
#Override
int operation(int a,int b)
{
return Math.max(a,b);
}
}
//code for obj2
Edit
You can replace Operation with functional interfaces introduced in java 8(specifically IntBinaryOperator).
You can use strategy pattern to achieve your goal.
Basically you want externalize operation to an interface and specify the object that implements the interface (with min or max) in constructor of Calculate.
This approach gives you most flexible solution that is proof to changes of requirements.
You can modify your class as follows:
class Calculate {
private boolean calcMax;
public Calculate(boolean calcMax){
this.calcMax = calcMax;
}
int operation(int a, int b){
return calcMax ? Math.max(a,b) : Math.min(a,b);
}
}
public class Calculate {
public int a=0;
public int b=0;
public int maxVal = 0;
public int minVal = 0;
public Calculate(int a, int b){
this.a=a;
this.b=b;
this.maxVal=Math.max(a,b);
this.minVal = Math.min(a, b);
}
}
Assuming you are finding the mins and max of the same variables...

Signing up Codewars - Java Exercise

The code is
public class Multiply
{
public static Double multiply(Double a, Double b)
{
return a * b
}
}
I cannot solve the above code.
I tried a few things, like
public class Multiply
{
public double multiply(double a, double b)
{ return a * b;}
}
It still shows errors in code.
Kindly help, please.
You essentially had the answer Codewars wanted. I imagine they expected for you to just add the semicolon, as you did, but keep the rest of the code the same.
public class Multiply
{
public static Double multiply(Double a, Double b)
{
return a * b;
}
}
I went to try it out, and this worked for me. Looks like they wanted you to keep static and the wrapper class Double.
Here is the answer:
public class Multiply
{
public double multiply(double a, double b)
{ return a * b;}
}
Think about how it will work if it is executed without any main method and what all things are missing / incorrect format in the code
E.g. Where you can add any double value
public class Multiply {
public static double multiply(double a, double b) {
return a * b;
}
public static void main(String[] args) {
double result = multiply(20.01, 10.10);
System.out.println("The result is: " + result);
}
}
public class Multiply {
public double multiply(double a , double b )
//just change the wrapper to primitive
{
return a*b ;
// add semicolon over here that it
}

Manipulating Generics through auto/unboxing

public class Generics {
public static <T> T increaseBalance (T amount){
//say I want to increase the amount here, put it into finalBalance and return
return finalBalance;
}
public static void main(String[] args){
System.out.println(increaseBalance (new Integer(10)));
System.out.println(increaseBalance (new Double(20)));
}
}
Hi. I am just into Generics and auto/unboxing. In this simple code segment, I am trying to send two different objects to increaseBalance(T amount) method and would like to increase the amount by 10 and return the final balance. How can this be achieved? It would make my understanding of generics and auto/unboxing clearer. Thanks a lot.
Unfortunately, there's no easy way to apply the + operator to a Generic type T.
You have two options:
Overloading
or
Checking the type and casting to a specific boxed type
If you pick to overloading, you can implement two methods, both for each of the possible parameter types.
public static Integer increaseBalance (Integer amount){
return amount + 10;
}
public static Double increaseBalance (Double amount){
return amount + 10;
}
If you want to stick to the generic method, you will have to check the parameter type and then do a cast.
public static <T extends Number> Number increaseBalance (T amount){
Number result = null;
if (amount instanceof Integer) {
result = new Integer((Integer) amount + 10);
} else if (amount instanceof Double) {
result = new Double((Double) amount + 10);
} else {
//do nothing
}
return result;
}

Workaround for passing a method into a method?

I am looking for a way to pass a method as a parameter into another method.
I am currently trying to simulate the Newton's-method (http://en.wikipedia.org/wiki/Newton%27s_method) in Java with the following code:
public class Newton {
// Iterationmethod
public void newtonCalc(double x0) {
double x;
// counter
int i = 0;
//Newton-Iteration for x0
x = x0 - (y2(x0) / y2Deriv(x0));
while (Math.sqrt(y2(x)*y2(x)) >= Math.pow(10, -10)){
//Newton-Iteration x(n+1)
x = x - (y2(x))/ y2Deriv(x);
i++;
System.out.printf("%d. %.11f\n",i,y2(x));
}
System.out.printf("%d steps were necessary for a resolution of 10^-10", i);
}
// Function for (2)
public static double y2(double x) {
return Math.sin(x) / (1 - Math.tan(x));
}
// Derivative for (2)
public static double y2Deriv(double x) {
return (Math.cos(x) + Math.sin(x) * Math.tan(x) * Math.tan(x))
/ ((Math.tan(x) - 1) * (Math.tan(x) - 1));
}
// Function for (4)
public static double y4(double x) {
return Math.exp(-1/Math.sqrt(x));
}
// Derivative for (4)
public static double y4Deriv(double x) {
return Math.exp(-1/Math.sqrt(x))/(2*Math.pow(x, 3d/2));
}
public static void main(String[] args) {
Newton newton = new Newton();
newton.newtonCalc(1);
}
}
newtonCalc(x0) gets an x0 at wich the iteration should be started.
But the function (y2) now is hardcoded into this method. I want it to be flexible.
For example newtonCalc(double x0, Method y) to run the iteration for y starting at x0.
I have 2 different functions (y2 and y4 which are both functions from a excercise sheet from my lecture plus its derivatives y2Deriv and y4Deriv which are used in the Iterationmethod).
I know passing a method is not possible but i dont get any easy workaround.
Forgive me if this is unclear or i have missed any necessary information!
Regards,
Tak3r07
It's entirely possible since Java 8, using lambda expressions
If you want to stay with pre-Java-8 methods, make an interface Function with member functions eval and deriv and pass (possibly anonymous) instances of derived classes to the Newton class invocation.
This could look like (I'm not sure that all details are correct, these are just code fragments to illustrate the idea)
interface Function {
public double eval(double x);
public double deriv(double);
}
class Example1 implements Function {
#override
public double eval(double x) { return x*(x+3)+1; }
#override
public double deriv(double) { return 2*x+3; }
}
....
Solver solver1 = new Newton(new Example1(),x0);
....
Solver solver2 = new Newton(new Function(){
#override
public double eval(double x) { return cos(x); }
#override
public double deriv(double) { return -sin(x); }
}, x0);

Categories