How do I make the switch/case statement in this simple Calculator program into a jump table.
import java.lang.*;
import java.util.*;
public class Calculator
{
private int solution;
private static int x, y, ops;
private char operators;
public Calculator()
{
solution = 0;
}
public int addition(int x, int y)
{
return x + y;
}
public int subtraction(int x, int y)
{
return x - y;
}
public int multiplication(int x, int y)
{
return x * y;
}
public int division(int x, int y)
{
solution = x / y;
return solution;
}
public void calc(int ops){
Scanner operands = new Scanner(System.in);
System.out.println("operand 1: ");
x = operands.nextInt();
System.out.println("operand 2: ");
y = operands.nextInt();
System.out.println("Solution: ");
switch(ops)
{
case(1):
System.out.println(addition(x, y));
break;
case(2):
System.out.println(subtraction(x, y));
break;
case(3):
System.out.println(multiplication(x, y));
break;
case(4):
System.out.println(division(x, y));
break;
}
}
public static void main (String[] args)
{
System.out.println("What operation? ('+', '-', '*', '/')");
System.out.println(" Enter 1 for Addition");
System.out.println(" Enter 2 for Subtraction");
System.out.println(" Enter 3 for Multiplication");
System.out.println(" Enter 4 for Division");
Scanner operation = new Scanner(System.in);
ops = operation.nextInt();
Calculator calc = new Calculator();
calc.calc(ops);
}
}
To be completely honest, I don't know exactly what a jump table is (couldn't find any explanations online) so I don't know how it differs from a switch/case statement.
Side Note: This code only deals with integers so if you divide 5/3 its gives you 1. How can I easily change it to take floats/doubles.
As mentioned, a jump table is an array of offsets/pointers to functions. Unlike C/C++, Java doesn't really have function pointers (Function Pointers in Java)
But you can pretend, and do it the object oriented way. Define a base class (Funky) with one method (f). Derive mutiple children, one for each of your functional operations (+,-,*,/, etc), and create a single object for each child (it is just an interface, after all), and store that child into an array of type (Funky).
Lookup the operation in the table, and call the method on your arguments
Example:
Define a base class, (or an interface, which makes you happier?). Note that if you extend a class, you can use the base class method as a default (generate an error message, or throw an exception),
public class X
//or, public interface X
{
//method
Z fun(Z z1, Z z2)
{
//nothing to see here
}
}
class X1 extends X //or, implements X
{
public Z fun(Z z1, Z z2)
{
//variant1 stuff here
}
}
...
public class Xn extends X //or, implements X
{
public Z fun(Z z1, Z z2)
{
//variantn stuff here
}
}
Oh, and you will need instances, and load them into an array (the jumptable).
There are certain techniques which are idiomatic to certain languages, and jumptables are more of a systems thing and less of a Java thing, not really a Java idiom.
well, i don't know what is a jump table, but if you wanna control another type of numbers, you can change of parameter for example you method:
public int addition(int x, int y)
{
return x + y;
}
if you wanna Double-->
public int addition(Double x, Double y)
but i strongly recommend you user the type Number every other class extens from Number.
Number.class
ex:
public static String numeroToLetra(Number num)
{
Integer numero = Integer.valueOf(num.intValue()); //int value
Double numero = Double.valueOf(num.doubleValue());........
}//so you can pass whatever type of number.
This is an old question, but I think it still has value for illustrating what you can do since Java 8. Basically, you create an interface whose sole purpose is to provide a type for an operations array and then you use method references to populate the operations array. After that, you can use the index to select the proper operation. I made minimal modifications to the OP's code such that the comparison is easiest:
import java.util.Scanner;
public class Calculator
{
//
// Create an interface to use as Type for
// operations array.
//
private interface BinaryOperation {
int performOperation(int a, int b);
}
//
// Array has one unused element to make coding easier
// and use operation as a direct index.
// You can replace with 4 element array easily.
//
BinaryOperation[] operations = new BinaryOperation[5];
private int solution;
private static int x, y, ops;
private char operators;
public Calculator()
{
solution = 0;
//
// Initialize jump table using method references.
//
operations[1] = this::addition;
operations[2] = this::subtraction;
operations[3] = this::multiplication;
operations[4] = this::division;
}
public int addition(int x, int y)
{
return x + y;
}
public int subtraction(int x, int y)
{
return x - y;
}
public int multiplication(int x, int y)
{
return x * y;
}
public int division(int x, int y)
{
solution = x / y;
return solution;
}
public void calc(int ops){
Scanner operands = new Scanner(System.in);
System.out.println("operand 1: ");
x = operands.nextInt();
System.out.println("operand 2: ");
y = operands.nextInt();
System.out.println("Solution: ");
//
// Call binary operation through jump table
//
System.out.println(operations[ops].performOperation(x, y));
}
public static void main (String[] args)
{
System.out.println("What operation? ('+', '-', '*', '/')");
System.out.println(" Enter 1 for Addition");
System.out.println(" Enter 2 for Subtraction");
System.out.println(" Enter 3 for Multiplication");
System.out.println(" Enter 4 for Division");
Scanner operation = new Scanner(System.in);
ops = operation.nextInt();
Calculator calc = new Calculator();
calc.calc(ops);
}
}
If you're working with a version of Java that supports lambdas, a solution that is more true to the requirement to implement as a "jump table" would use an actual jump table, one that maps operator codes to lambda expressions that implement each the operands.
This is a pleasing way not only to eliminate clunky switch statements, but to produce more maintainable and more easily extensible code. Future new operands can easily be added later without making any changes to the Calculator implementation. Simply implement the new operator and its naming method, and add it to the jump tables. Your Calculator will automatically support the new operand.
import com.google.common.collect.ImmutableMap;
import java.lang.*;
import java.util.*;
public class Calculator
{
private static final Map<Integer,BinaryOperator<Integer>> evaluators = ImmutableMap.<Integer, BinaryOperator<Integer>>builder()
.put(1, (Integer x, Integer y) -> new IntAddition().evaluateFor(x,y))
.put(2, (Integer x, Integer y) -> new IntSubtraction().evaluateFor(x,y))
.put(3, (Integer x, Integer y) -> new IntMultiplication().evaluateFor(x,y))
.put(4, (Integer x, Integer y) -> new IntDivision().evaluateFor(x,y))
.build();
private static final Map<Integer,Nameable> names = ImmutableMap.<Integer, Nameable>builder()
.put(1, () -> new IntAddition().getName())
.put(2, () -> new IntSubtraction().getName())
.put(3, () -> new IntMultiplication().getName())
.put(4, () -> new IntDivision().getName())
.build();
private int solution;
private static int x, y, ops;
public Calculator()
{
solution = 0;
}
public void calc(int opcode)
{
Scanner operands = new Scanner(System.in);
System.out.println("Enter operand 1: ");
x = operands.nextInt();
System.out.println("Enter operand 2: ");
y = operands.nextInt();
System.out.print("Solution: ");
System.out.println(evaluators.get(opcode).evaluateFor(x, y));
}
public static void main(String[] args)
{
System.out.println("What operation?");
for (Integer opcode : evaluators.keySet())
{
System.out.println(String.format(" Enter %d for %s", opcode, names.get(opcode).getName()));
}
Scanner operation = new Scanner(System.in);
ops = operation.nextInt();
Calculator calc = new Calculator();
calc.calc(ops);
}
interface Nameable
{
String getName();
}
interface BinaryOperator<T>
{
T evaluateFor(T x, T y);
}
static class IntAddition implements BinaryOperator<Integer>, Nameable
{
IntAddition() { }
public Integer evaluateFor(Integer x, Integer y)
{
return x + y;
}
public String getName()
{
return "Addition";
}
}
static class IntSubtraction implements BinaryOperator<Integer>, Nameable
{
IntSubtraction() { }
public Integer evaluateFor(Integer x, Integer y)
{
return x - y;
}
public String getName()
{
return "Subtraction";
}
}
static class IntMultiplication implements BinaryOperator<Integer>, Nameable
{
IntMultiplication() { }
public Integer evaluateFor(Integer x, Integer y)
{
return x * y;
}
public String getName()
{
return "Multiplication";
}
}
static class IntDivision implements BinaryOperator<Integer>, Nameable
{
IntDivision() { }
public Integer evaluateFor(Integer x, Integer y)
{
return x / y;
}
public String getName()
{
return "Division";
}
}
}
Related
Hello everyone I'm currently creating a simple program. I have 2 classes the first one is calculator and the second one is parameters_return. What I want to happen is that when I read the values of x and y in my second class i want to use them in my first class Unfortunately, I can't run the program because it has an error. The code is below please help me with regards to this matter. I'm just self studying I really want to learn Java.
Code in (first class) calculator class is:
class calculator {
//with parameters with return type
int add(int a, int b) {
return (a + b);
}
//with parameters without return type
void sub(int a, int b) {
System.out.print(a - b);
}
//without parameters with return type
int mul() {
parameters_return s1 = new parameters_return();
int c = (s1.x) * (s1.y);
return c;
}
//without parameters without return type
void div() {
parameters_return s2 = new parameters_return();
int c = (s2.x) / (s2.y);
System.out.println("Division = " + c);
}
}
Code in my (second class) parameters_return class is:
class parameters_return {
int x, y;
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
x = sc.nextInt();
y = sc.nextInt();
calculator perform = new calculator();
//addition
int z = perform.add(x, y);
System.out.println("Added value = " + z);
//subtraction
System.out.println("Subtracted value = ");
perform.sub(x, y);
//multiplication
z = perform.mul();
System.out.println("Multiplication value = ");
//division
perform.div();
}
}
Is there any way to get values from main class and can be used in another class?
import java.util.*;
class ParametersReturn {
static int x, y;
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
x = sc.nextInt();
y = sc.nextInt();
Calculator perform = new Calculator();
//addition
int z = perform.add(x, y);
System.out.println("Added value = " + z);
//subtraction
System.out.println("Subtracted value = ");
perform.sub(x, y);
//multiplication
z = perform.mul();
System.out.println("Multiplication value = " + z);
//division
perform.div();
}
}
This should be your ParametersReturn Class and make sure you should start your class name with capital letter , you are using Scanner class to use it you have to import java.util package. And to use these variables in Calculator class make these variables static
class Calculator {
//with parameters with return type
int add(int a, int b) {
return (a + b);
}
//with parameters without return type
void sub(int a, int b) {
System.out.print(a - b);
}
//without parameters with return type
int mul() {
ParametersReturn s1 = new ParametersReturn();
int c = (s1.x) * (s1.y);
return c;
}
//without parameters without return type
void div() {
ParametersReturn s2 = new ParametersReturn();
int c = (s2.x) / (s2.y);
System.out.println("Division = " + c);
}
}
And in multiplication you forgot to print the value of z
I already have the class I need to implement in to my code. The instructions are: Code a testing program/class. This should construct or instantiate objects of the class you coded in step #1. Your testing program should call every method to make sure they work. You should construct at least two objects – one with the default constructor and one with the “other” constructor. For the second scenario, ask the user what values for (radius and) height. You may use any input and output that you want for this.
This is what I have so far and I'm stuck:
public class Cube
{
private double height;
public Cube(){
height = 1.0;
}
public Cube(double h){
height = h;
}
public double getHeight(){
return height;
}
public void setHeight(double h){
height = h;
}
public double calcVolume() {
return height*height*height;
}
public double calcSurface(){
return height*height*6;
}
public String toString(){
return this.toString();
}
public boolean equals(Cube c){
return (c.getHeight() == this.height);
}
}
import java.util.*
public class TestTheCube
{
public static void main(String[] args)
{
Cube cube1 = new Cube();
Scanner kb = new Scanner(System.in);
System.out.print("Enter a height as a positive number");
double height = kb.nextDouble();
Cube cube2 = new Cube(height);
System.out.println(
}
}
I've invoked calcVolume() of cube1 and cube2.
Cube cube1 = new Cube();
Scanner kb = new Scanner(System.in);
System.out.print("Enter a height as a positive number");
double height = kb.nextDouble();
Cube cube2 = new Cube(height);
System.out.println("Cube 1's volume = "+cube1.calcVolume());
System.out.println("Cube 2's volume = "+cube2.calcVolume());
.....//repeat for every instance method you have.
Can you help me find my error?
I'm trying to use these two methods here but my output is not working.
class Nine {
public static void Nine(String[] args) {
int x,y,z;
y = 3;
x = 7;
z = addEm(a, b);
System.out.println("answer= " +x);
}
public static addEm (double a, double b){
int c;
c = a+b;
}
}
Actually there are a lot of error in your code:
z=addEm(a, b);
here a and b are meaningless, you should use z=addEm(y,x); (if your intent is to sum three with seven)
System.out.println("answer= " +x);
I guess that you want to show the the results of the sum, therefore you should print z (and not x), so you should substitute with System.out.println("answer= " +z);
public static addEm (double a, double b) {
Here you missed the return type, and you need to consider also the type of parameters a and b. Since y,x and z are int, it is better if also a and b are int, and therefore specify also the return type as int:
public static int addEm (int a, int b) {
Or you can declare everything (y,x,z,a,b and return type) as a double: the important here is that they should be all of the same type. Moreover you miss also the return statement of the function addEm, that summarizing becomes:
public static int addEm (int a, int b)
{
int c;
c=a+b;
return c;
}
And finally also the function
public static void Nine(String[] args)
it is not right named for an entry point: its names should be main.
So in conclusion, if you apply all the fix (by modifying as less as possible your original code) a code that compile, run and works following some 'logic' is:
class Nine {
public static void main(String[] args) {
int x, y, z;
y = 3;
x = 7;
z = addEm(y, x);
System.out.println("answer= " + z);
}
public static int addEm(int a, int b) {
int c;
c = a + b;
return (c);
}
}
Man, this is a very basic java lesson:
every prog need an entry point, which is in java:
public static void main(String args[]){}
And then your code will execute.
You're passing arguments a and b to addEm, but those variables aren't initialized. I'm expecting you wanted to pass x and y instead.
class Nine
{
public static void Nine(String[] args)
{
int x,y,z;
y=3;
x=7;
z=addEm(x, y);
System.out.println("answer= " +x);
}
public static addEm (double a, double b)
{
int c;
c=a+b;
}
}
Your code will not work because your addEm method does not have any return type. In addition, the method you wrote takes Double params but while using you are trying to pass int to it. You also do not have any main method. I am assuming you misspelled or misunderstood the main method so below is the code which should work
class Nine
{
public static void Main(String[] args)
{
int x,y,z;
y=3;
x=7;
z=addEm(x, y);
System.out.println("answer= " + x);
}
public static int addEm (int a, int b)
{
int c;
c=a+b;
return c;
}
}
I need one static method that simply adds two different numbers together and returns the result. However, it needs to be able to accept different types of numbers such as Integer and Doubles which is where I am getting stuck. Here is the main method that I have which, cannot be changed.
public static void main(String[] args)
{
Double answer1 = add(2, 7);
Number answer2 = add(new Integer(4), new Double(5.2));
double answer3 = add(8, 1.3);
System.out.println(answer1 + " " + answer2 + " " + answer3);
}
public static Double add(Double num1, Integer num2)
{
return num1 + num2;
}
The method above has the correct body I just don't know what should be where Double is after static. Is there some type that accommodates for both doubles and integers?
New situation:
public static double add(Number num1, Number num2)
{
return num1 + num2; //error is here
}
You can use the common baseclass Number.
public class Test {
public static void main(String[] args) {
int x = 5;
double y = 10;
System.out.println(getDoubleValue(x, y));
}
private static double getDoubleValue(Number x, Number y){
return x.doubleValue() + y.doubleValue();
}
}
Output:
15.0
public void draw(String s) {
...
}
public void draw(int i) {
...
}
public void draw(double f) {
...
}
public void draw(int i, double f) {
...
}
Look at the following link
http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
Means you have to use method overloading
You should use method overloading.
Double Foo() // Version with no arguments
{
}
Double Foo(int arg) // Version with a single int
{
}
Double add(Double num1, Integer num2) // Version with integer and double parameters
{
}
You could use method overloading for that. Creating an identical method with different datatype :)
Im trying to to create a simple 4 function calculator using a jump table without switch case or if/else statements. I understand I can create the jump table via function pointers but I am kindda blanking out. I've started with the addition and subtraction part of the program but am trying to grasp the design/strategy to use. I am also getting an error when putting the method in the array, so far this is what i have:
public class Calculator {
public abstract class Functor{
abstract double Compute(double op1, double op2);
}
class Addition extends Functor
{
public double Compute(double op1, double op2){ return op1 + op2;}
}
class Subtraction extends Functor
{
public double Compute(double op1, double op2){ return op1 - op2;}
}
public static void main(String[] args) {
Functor add = new Addition(); // Problem here
Functor sub = new Subtraction(); // and here
}
}
any help or ideas for the step in the right direction is greatly appreciated!
thanks in advance!
Let's try this instead:
public enum Operation {
PLUS("+") {
double apply(double x, double y) { return x + y; }
},
MINUS("-") {
double apply(double x, double y) { return x - y; }
},
TIMES("*") {
double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
double apply(double x, double y) { return x / y; }
};
private final String symbol;
Operation(String symbol) {
this.symbol = symbol;
}
#Override public String toString() {
return symbol;
}
abstract double apply(double x, double y);
}
This will only work if you're using Java 5 or later, which has generics and enums. What this does is it gives you a static set of operations. You access them by typing Operation.PLUS or Operation.MINUS, etc.
To test it try this:
public static void main(String[] args) {
double x = Double.parseDouble(args[0]);
double y = Double.parseDouble(args[1]);
for (Operation op : Operation.values())
System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}
For more information consult Effective Java, Second Edition by Joshua Bloch.
It's worth pointing out that Java has no notion of "function pointers". Rather you simple write an interface and write a class that implements that interface. The correct class to use is selected at runtime; hence, that is a "jump table" but it's hidden behind the semantics of object-oriented programming. This is known as polymorphism.
While that's decent (aside from not having constructors that work right) I'd do it different, using anonymous classes.
abstract class Functor {
public abstract double compute(double a, double b);
public static void main(String[] args) {
Functor add = new Functor() {
// defining it here is essentially how you do a function pointer
public double compute(double a, double b) { return a + b; }
};
Functor subtract = new Functor() {
public double compute(double a, double b) { return a - b; }
};
System.out.println(add.compute(1.0,2.0));
System.out.println(subtract.compute(1.0,2.0));
}
}
Result:
C:\Documents and Settings\glowcoder\My Documents>java Functor
3.0
-1.0
C:\Documents and Settings\glowcoder\My Documents>
You don't have any constructors to pass in any arguments to your sub-classes, I don't understand how you think opt1 and opt2 are going to be set without any constructors with those as parameters. This is not correct Java code right now.