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...
Related
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.
Say we have variables int a = 0; and int c;.
Is it possible to make it so that c is always equal to something like a + 1 without having to redundantly retype c = a + 1 over and over again
Thanks!
No, it is not possible to make one variable track another variable. Usually, this is not desirable either: when a value of one variable is tied to the value of another variable, you should store only one of them, and make the other one a computed property:
int getC() { return a+1; }
A less abstract example is a connected pair of age and date of birth. Rather than storing both of them, one should store date of birth alone, and make a getter method for computing the current age dynamically.
Since you have 2 variables tied in a specific way, consider using custom object to wrap a and c values. Then you can control the object state inside the class logic. You can do something like this:
public class ValuePair {
private final int a;
private final int c;
public ValuePair(int a) {
this.a = a;
this.c = a + 1;
}
public int getA() {
return a;
}
public int getC() {
return c;
}
}
Firstly, The answer is no, you can't do it directly in Java, but you can redesign your int class, There is an example:
public class Test {
public static void main(String[] args) throws IOException {
MyInt myInt1 = new MyInt(1);
KeepIncrementOneInt myInt2 = new KeepIncrementOneInt(myInt1);
System.out.println(myInt2.getI());
myInt1.setI(2);
System.out.println(myInt1.getI());
System.out.println(myInt2.getI());
}
}
class MyInt { //your own int class for keep track of the newest value
private int i = 0;
MyInt(int i) {
this.i = i;
}
public int getI() {
return this.i;
}
public void setI(int i) {
this.i = i;
}
}
class KeepIncrementOneInt { //with MyInt Class to get the newest value
private final MyInt myInt;
KeepIncrementOneInt(MyInt myInt) {
this.myInt = myInt;
}
public int getI() {
return this.myInt.getI() + 1; //get the newest value and increment one.
}
}
Create your own Int class, because we need a reference type to keep track of the newest the value a. like the MutableInt in apache commons.
Create a always increment 1 class with your own Int class as a member.
In getI method, it's always from the reference Int class get the newest value a.
I have read up on Java Interfaces (callbacks) because I was told by a professor I should use callbacks in one of my programs. In my code, there are two Mathematical functions I can 'pick' from. Instead of making a method activate() and changing the code inside (from one function to the other) when I want to change functions, he said I should use callbacks. However, from what I've read about callbacks, I'm not sure how this would be useful.
EDIT: added my code
public interface
//the Interface
Activation {
double activate(Object anObject);
}
//one of the methods
public void sigmoid(double x)
{
1 / (1 + Math.exp(-x));
}
//other method
public void htan(final double[] x, final int start,
final int size) {
for (int i = start; i < start + size; i++) {
x[i] = Math.tanh(x[i]);
}
}
public double derivativeFunction(final double x) {
return (1.0 - x * x);
}
}
If you want to use interfaces something like this would work.
I have a MathFunc interface that has a calc method.
In the program I have a MathFunc for mutliplication and one for addition.
With the method chooseFunc you can choose one of both and with doCalc the current chosen MathFunc will do the calculation.
public interface MathFunc {
int calc(int a, int b);
}
and you can use it like that:
public class Program {
private MathFunc mult = new MathFunc() {
public int calc(int a, int b) {
return a*b;
}
};
private MathFunc add = new MathFunc() {
public int calc(int a, int b) {
return a+b;
}
};
private MathFunc current = null;
// Here you choose the function
// It doesnt matter in which way you choose the function.
public void chooseFunc(String func) {
if ("mult".equals(func))
current = mult;
if ("add".equals(func))
current = add;
}
// here you calculate with the chosen function
public int doCalc(int a, int b) {
if (current != null)
return current.calc(a, b);
return 0;
}
public static void main(String[] args) {
Program program = new Program();
program.chooseFunc("mult");
System.out.println(program.doCalc(3, 3)); // prints 9
program.chooseFunc("add");
System.out.println(program.doCalc(3, 3)); // prints 6
}
}
I'm trying to average 6 grades for two different people for school, I have all the grades for each student in different classes I was wondering
How can I import the numbers that I enter for each students object that I create?
//first class
public class GradesA {
int art;
int math;
int science;
int AddGrades(int a, int b, int c){
art = a;
math = b;
science = c;
return a+b+c;
}}
//second class
public class GradesB {
int english;
int carpentry;
int geography;
int AddGradesB(int a,int b,int c){
english = a;
carpentry = b;
geography = c;
return a+b+c;
}}
//final class
public class Classes {
public static void main(String[]args){
GradesA objGrades = new GradesA();
System.out.println(objGrades.AddGrades(100,85,95));
GradesB objGradesB = new GradesB();
System.out.println (objGradesB.AddGradesB(95,85,75));
}}
Hope I understood what you are looking for
Since
int addGrades(int a, int b, int c){
return and integer
why do not you just divide return number from this function by 3 and get your average that you are looking for.
If you want to have access to data fields art, math, and science values
you need getters and setters like follwing example for art data filed
setter function is
public void setArt(int art){
this.art = art;
}
getter function is
public int getArt(){
return this.art;
}
Read More About Setter and Getter
How can I swap the contents of two Integer wrappers?
void swap(Integer a,Integer b){
/*We can't use this as it will not reflect in calling program,and i know why
Integer c = a;
a= b;
b = c;
*/
//how can i swap them ? Does Integer has some setValue kind of method?
//if yes
int c = a;
a.setValue(b);
b.setValue(c);
}
You can't, precisely because Integer is immutable (along with the other primitive wrapper types). If you had a mutable wrapper class, it would be fine:
public final class MutableInteger {
{
private int value;
public MutableInteger(int value) {
this.value = value;
}
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
void swap(MutableInteger a, MutableInteger b) {
int c = a.getValue();
a.setValue(b.getValue());
b.setValue(c);
}
However, due to the lack of the equivalent of setValue in Integer, there's basically no way of doing what you're asking. That's a good thing. It means that for most cases, where we may want to pass an Integer value to another method, we don't need to worry about whether the method will mutate it. Immutability makes it much easier to reason about your code, without having to carefully trace what every method does, just in case it changes your data under your feet.
Wrapper types in Java are immutable hence provide no setter methods. Plus Java works by passing references by value. Can you tell us why you want to swap stuff?
The type java.lang.Integer represents an immutable number that will never change its value. If you want a mutable number, try MutableInt from Apache Commons.
In Java, as opposed to C++, you cannot pass references to arbitrary memory locations, so swapping is impossible in most cases. The closest thing you can get is this:
public static void swap(Integer[] ints, int index1, int index2) {
Integer tmp = ints[index1];
ints[index1] = ints[index2];
ints[index2] = tmp;
}
You can write similar code using a List<T>, but you always need a container (or two) in which you can swap things.
Refer this article to get a clear idea Article
You will get a clear idea about pass by value pass by reference and and its concepts
you can try something like this :
class MyClass{
int a = 10 , b = 20;
public void swap(MyClass obj){
int c;
c = obj.a;
obj.a = obj.b;
obj.b = c;
}
public static void main(String a[]){
MyClass obj = new MyClass();
System.out.println("a : "+obj.a);
System.out.println("b : "+obj.b);
obj.swap(obj);
System.out.println("new a : "+obj.a);
System.out.println("new b : "+obj.b);
}
}
public class NewInteger {
private int a;
private int b;
public int getA() {
return a;
}
public int getB() {
return b;
}
public NewInteger(int a, int b) {
this.a = a;
this.b = b;
}
public void swap(){
int c = this.a;
this.a = this.b;
this.b = c;
}
}
NewInteger obj = new NewInteger(1, 2);
System.out.println(obj.getA());
System.out.println(obj.getB());
obj.swap();
System.out.println(obj.getA());
System.out.println(obj.getB());
output :
1
2
2
1