Java enum instatiate using constructor parameter - java

I have this enum:
public enum Operation {
ADD {
public double apply(double a, double b) {
return a + b;
}
},
SUBTRACT {
public double apply(double a, double b) {
return a - b;
}
}
} ;
public abstract double apply(double a, double b);
`}`
I want to instantiate this like:
Operation op=new Operation("+");
op.aply(2,3);//now use ADD
Is it possible to write a constructor with string parameter that tells to enum which operation to aply?

You can define a public static method to get the correct operation based on a String:
public static Operation get(String input) {
if(input.equals("+")) {
return ADD;
}
if(input.equals("-")) {
return SUBTRACT;
}
throw new IllegalArgumentException();
}
Then you would call it like:
Operation op = Operation.get("+");
op.apply(2, 3);

Unfortunately, no. You can create a method with a String parameter that returns the specific Operation depending on what is the parameter. Example :
public enum Operation {
ADD("+") {
public double apply(double a, double b) {
return a + b;
}
},
SUBTRACT("-") {
public double apply(double a, double b) {
return a - b;
}
};
private String operationChar;
private Operation(String s) {
this.operationChar = s;
}
public static Operation getOperation(String s) {
for (Operation o : Operation.values()) {
if (o.operationChar.equals(s))
return o;
}
return null;
}
public abstract double apply(double a, double b);
}
You can get the instance like this :
Operation op = Operation.getOperation("+");
op.apply(2,3); // ADD will be used here
(You can use a char instead of a String, since most operations only have one char (1+1, 1-1, 1*1, 1/1))

You can try the following example.
It's a bit over-engineered (you could ditch the whole "+" or "-" and call elements by name) but it works.
public enum Operation {
ADD("+") {
public double apply(double a, double b) {
return a + b;
}
},
SUBTRACT("-") {
public double apply(double a, double b) {
return a - b;
}
};
public abstract double apply(double a, double b);
String type;
Operation(String type) {
this.type = type;
}
public String getType() {
return type;
}
static Operation get(String type) {
for (Operation o: Operation.values()) {
if (o.getType().equals(type)) {
return o;
}
}
throw new NoSuchElementException();
}
public static void main(String[] args) throws Exception {
System.out.println(Operation.get("+").apply(1, 2));
}
}
Output
3.0

You can define a constructor in an enum, but you cannot use it outside of the enum definition. The available enum values are fixed at compile time and you can't create more at runtime by using new. If you want to look up the enum by symbol, you need to define a lookup in the code.
For example by switching on the symbol:
public enum Operation {
ADD {/*...*/};
// ...
public static Operation forSymbol(String symbol) {
switch(symbol) {
case "+":
return ADD;
//...
default:
throw new IllegalArgumentException("Unsupported symbol: " + symbol);
}
}
}
Or by defining the symbol together with the enum, and using that in the look up:
public enum Operation {
ADD("+") {/*...*/};
private final String symbol;
private Operation(String symbol) {
this.symbol = symbol;
}
// ...
public static Operation forSymbol(String symbol) {
for (Operation operation : Operation.values()) {
if (operation.symbol.equals(symbol)) return operation
}
throw new IllegalArgumentException("Unsupported symbol: " + symbol);
}
}

It is not possible, due to the fact that enums cannot have public constructors (more information in this question). To use an Operation you will have to manually tell the compiler which Operation to use. This can be done by:
Operation op = ADD;
double x = op.apply(2,3);
which uses ADD as the Operation.

Related

Looking for an implementation of an abstract method

I need to make a programm which is like a rally, theres 2 types of vehicles, motorcycle and cars, two types of motorcycle, with and without sidecar, the thing is that I need to verify if there is just a motorcycle in an array list, I mean, two wheels vehicle. That verification should be done in a method called esDe2Ruedas(), which is called by an abstract overrided method called check() that should be the one that verifies if a group of vehicles from an array are able to run in the rally, if its true all the elements of the array must be from the same type.
Here is the code
this is how the program arrays the vehicles
GrandPrix gp1 = new GrandPrix();
gp1.agregar(v1);
//gp1.mostrar(v1);
gp1.agregar(v2);
System.out.println(gp1.check());
GrandPrix gp2 = new GrandPrix();
gp2.agregar(vt1);
gp2.agregar(vt2);
gp2.agregar(m2);
System.out.println(gp2.check());
GrandPrix gp3 = new GrandPrix();
gp3.agregar(vt1);
gp3.agregar(vt2);
gp3.agregar(m1);
System.out.println(gp3.check());
GrandPrix gp4 = new GrandPrix();
gp4.agregar(m1);
gp4.agregar(m2);
System.out.println(gp4.check());
This is the class that is using
import java.util.ArrayList;
public class GrandPrix extends Rally{
ArrayList<Vehiculo> ve = new ArrayList<Vehiculo>();
public void agregar(Vehiculo v) {
ve.add(v);
}
public void agregar(Carro c) {
ve.add(c);
}
public void agregar(Moto m) {
ve.add(m);
}
#Override
boolean check() {// HERE I VERIFY IF THE VEHICLES ARE COMPATIBLE
return false;
}
}
This is the class where everything goes on
public class Vehiculo {
private String Nombre;
private double velocidad_max;
private int peso;
private int comb;
public Vehiculo() {
setNombre("Anónimo");
setVel(130);
setPeso(1000);
setComb(0);
}
public Vehiculo(String string, double d, int i, int j) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
}
double rendimiento() {
return velocidad_max/peso;
}
public boolean mejor(Vehiculo otroVehiculo) {
return rendimiento()>otroVehiculo.rendimiento();
}
public String toString() {
return getNombre()+"-> Velocidad máxima = "+getVel()+" km/h, Peso = "+getPeso()+" kg";
}
/**************************************
---------SET And GET Nombre------------
***************************************/
public String getNombre() {
return Nombre;
}
public void setNombre(String nuevoNombre) {
this.Nombre=nuevoNombre;
}
/**************************************
---------SET And GET velocidad_max------------
***************************************/
public double getVel() {
return velocidad_max;
}
public void setVel(double nuevaVel) {
this.velocidad_max=nuevaVel;
}
/**************************************
---------SET And GET peso------------
***************************************/
public double getPeso() {
return peso;
}
public void setPeso(int nuevoPeso) {
this.peso=nuevoPeso;
}
/**************************************
---------SET And GET comb------------
***************************************/
public int getComb() {
return comb;
}
public void setComb(int comb) {
this.comb = comb;
}
boolean esDe2Ruedas() {
return false;
}
}
This is the class of motorcycles, which is in theory the same as the car's class, without sidecar thing
public class Moto extends Vehiculo{
private boolean sidecar;
public Moto(String string, double d, int i, int j) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
setSidecar(false);
}
public Moto(String string, double d, int i, int j, boolean b) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
setSidecar(b);
esDe2Ruedas(false);
}
public String toString() {
String str = null;
if(isSidecar())
str =super.toString()+", Moto, con sidecar";
else
str =super.toString()+", Moto";
return str;
}
public boolean isSidecar() {
return sidecar;
}
public void setSidecar(boolean sidecar) {
this.sidecar = sidecar;
}
I guess what you presented is what is given. If you came up with the design it is ok, but I believe it could be improved. Anyway, I try to respond to what I believe was your question straight away.
Vehiculo is the super type of Moto (which can have a side car and becomes 3 wheeler).
Vehiculo has a method esDe2Ruedas, which returns false.
Moto inherits that method <-- this is wrong, it should override it and, depending on side car, return the expected boolean value.
In the check method you can now distinguish between Moto and "Moto with sidecar" by using that method.

Interface to unite calculate methods with different primitive paramter types

I have two types of objects that can perform a calculate() operation with either an int or a byte:
public class A {
public int calculate(int n) {...}
}
and
public class B {
public byte calculate(byte n) {...}
}
I want to have an ArrayList of objects that I can loop over calling the calculate method.
How do I do that, using an interface?
Considering the difference in the int/byte signature
Would something like this be a good approach?
public interface Calculatable {
int calculate(int number);
default byte calculate(byte number) {
return (byte) calculate((int) number);
}
}
Maybe using a 3-rd class and check based on type could be useful
public class TestCalc {
public static void main(String[] args) {
List<Object> l = new ArrayList<Object>();
l.add(Integer.valueOf(300));
l.add(Byte.valueOf("120"));
l.add(Integer.valueOf(1));
TestCalc tc = new TestCalc();
ComputeAB cab = tc.new ComputeAB();
for (Object o : l) {
System.out.println(cab.calculate(o) + ":" + cab.type);
}
}
class A {
public int calculate(int n) {
return n;
}
}
class B {
public byte calculate(byte n) {
return n;
}
}
class ComputeAB {
String type = "";
public Object calculate(Object o) {
if (o instanceof Integer) {
type = "int";
return new A().calculate((int) o);
}
type = "byte";
return new B().calculate((byte) o);
}
}
}
Output
300:int
120:byte
1:int

Why Can't I Get The Data I Want From This Enum?

I need to know:
Why can't I pass maxSpeed to method as an int rather than Integer?
Why does it work using "getMaxSpeed.equals(speed)" method but can't compare less than/greater than? (I think because of maxSpeed being Integer rather than int, right?). The code doesn't compile with compareTo.
I need to get a list of all cars with maxSpeed greater than 'speed', how do I do this?
How can I return not only the name(BMW, Mercedes) but also the engineCc?
Tried using both normal operators for primitives and methods for objects.
enum CarData {
BMW (230, 3000),
Mercedes (220, 2500);
private int maxSpeed;
private int engineCc;
CarData (int maxSpeed, int engineCc) {
this.maxSpeed = maxSpeed;
this.engineCc = engineCc;
}
Integer getMaxSpeed(){
return maxSpeed;
}
int getEngineCc() {
return engineCc;
}
public static CarData getByMaxSpeed (int speed) {
for (CarData carData : CarData.values()){
if (carData.getMaxSpeed() => speed)
return carData;
}
return null;
}
}
public class VehicleInfo {
public static void main (String [] args){
System.out.println (CarData.getByMaxSpeed(200));
}
}
Expected result is "BMW, Mercedes" or "3000, 2500", whichever one I need.
int is a primitive data type in Java.
Integer is a wrapper class. You can't compare instances of a wrapper class (like Integer) in the same way you do with primitives, with Integer you have to use methods, with primitives it is simpler.
For the output try overriding the toString method in your enum, this toString method is inherited from the Object class.
The complete class would be
enum CarData {
BMW(230, 3000),
Mercedes(220, 2500);
private int maxSpeed;
private int engineCc;
/* This method was added/overwritten */
#Override
public String toString() {
return name() + ", Cc: " + engineCc;
}
CarData(int maxSpeed, int engineCc) {
this.maxSpeed = maxSpeed;
this.engineCc = engineCc;
}
Integer getMaxSpeed() {
return maxSpeed;
}
int getEngineCc() {
return engineCc;
}
public static CarData getByMaxSpeed(int speed) {
for (CarData carData : CarData.values()) {
//Here I replaced the => by >=
if (carData.getMaxSpeed() >= speed) {
return carData;
}
}
return null;
}
}
public class VehicleInfo {
public static void main(String[] args) {
System.out.println(CarData.getByMaxSpeed(200));
}
}
}
And the output:
BMW, Cc: 3000
If you want a different string just customize the return in the toString method, also you have to replace the => by >= to make the comparison.
Hope this helps.

Java: Calling an instanced getter from another class return null

I'm new into Java and want to improve my OOP skills.
Therefore I try to write all my "first programmes" object-oriented.
Anyway... I started a small primitives test programme:
public class Primitives {
byte b;
private void setByte (byte b)
{
this.b = b;
}
public byte getByte()
{
return b;
}
short s;
private void setShort (short s)
{
this.s = s;
}
public short getShort()
{
return s;
}
int i;
private void setInteger (int i)
{
this.i = i;
}
public int getInteger()
{
return i;
}
long l;
private void setLong (long l)
{
this.l = l;
}
public long getLong()
{
return l;
}
float f;
private void setFloat (float f)
{
this.f = f;
}
public float getfloat()
{
return f;
}
double d;
private void setDouble (double d)
{
this.d = d;
}
public double getDouble()
{
return d;
}
boolean bool;
private void setBoolean (boolean bool)
{
this.bool = bool;
}
public boolean getBoolean()
{
return bool;
}
char c;
private void setChar (char c)
{
this.c = c;
}
public char getChar()
{
return c;
}
String str;
private void setString (String str)
{
this.str = str;
}
public String getString()
{
return str;
}
public static void main(String[] args) {
Primitives prim = new Primitives();
prim.setBoolean(true);
//prim.setByte(42);
//prim.setChar("ft");
prim.setDouble(42.42);
//prim.setFloat(42);
prim.setInteger(42);
prim.setLong(424242);
//prim.setShort(0);
prim.setString("fourtytwo");
//System.out.println(integer.getInteger());
}
}
Afterward, I'm trying to call my getters in another class "Main":
public class Main {
public static void main(String[] args)
{
Primitives object = new Primitives();
int objectInt = object.getInteger();
String objectString = object.getString();
System.out.println(objectInt);
System.out.println(objectString);
}
}
My output is
0
null
How does this come?
I mean, I instanced (getInt for example) before, why I received 0?
I know there must 1000 answers here but I couldn't find any proper one.
Another question:
Why do I get "The method setByte(byte) in the type Primitives is not applicable for the arguments (int)" in my Setter? (that's why I comment some of the types out)
You should call the setter methods and set the value before you get them.
The problem with your code is : You are having two main classes and looks like you are running the one in the Main class which doesn`t initiate your variable.
The other main method inside your Primitives class never get executed, so you have not initiated your variables actually!
Each application should have one main class, and only one

A design pattern approach to return both boolean and strings

I want to write a method in java which receives an array of objects, checks for some compatibility and return a boolean value true if all meet, otherwise to return a string containing a message to inform user why some of the compatibilities don't meet.
I came up with simplified version of my question as follows:
Suppose you wanna compare cars and in order that comparison make sense you wanna make sure all are of same class, same color, same make.
So what I am trying to get from this method are two:
1- are all care compatible? (boolean using return)
2- if not, why? so to inform user of the reasons(String using throw)
What is the best design pattern for this?
Below is one way of implementing it:
boolean areCarsCompatible(Car [] cars) throws CarException {
String errorMessage = "";
for(Car car:cars){
if (cars done have same color) errorMessage +="Cars dont have same color";
}
for(Car car:cars){
if (cars done have same make) errorMessage +="Cars dont have same make";
}
for(Car car:cars){
if (cars are not all of same class) errorMessage +="cars are not all of same class";
}
if (errorMessage.equals("")){
return true
} else {
throw new CarException (errorMessage);
}
}
to return both boolean and strings
Although you can do this in other (dynamic) programming languages, it's strongly recommended that you don't design your method like this in Java. In Java, types are statically checked and strict, you simply can't return two different types from the same method, and throwing an exception when you intend to return a string is, well, just an ugly hack.
A different matter would be throwing an exception with a message to indicate an error, that's a very common practice and within the good practices of the language. But notice that you wouldn't be "returning both boolean and strings", an exception is intended for error handling.
There is a lot to address here.
First, you are seeking a design, an approach, an algorithm, etc., but please don't call this a design pattern. That term has a very specific meaning.
OK, nitpicking semantics aside, your approach is a bit awkward for a couple of reasons. First, the boolean is sort of useless because you don't care about "falseness." Either it all works, or you get a message of some kind. The value false has no value for you.
The other reason it is awkward is as #OscarLopez suggests. There is no neat way in Java, as in Ruby for example, to return a multi-type value.
I will say though that if you are going to throw an exception, your CarException is getting close to the right approach--if it is a checked exception as it seems. I strongly disagree with #cherouvim (though I didn't downvote) that it should be a RuntimeException. You want the caller to know about it and to have to deal with it.
As for my own suggestions for solutions, I have two:
1) Maintain some notion of the criteria necessary for a Car to be in the collection. Then simply don't add a Car to the collection if it doesn't meet those criteria. In other words, solve the problem by preventing it from ever happening in the first place.
2) Use Enums.
public enum CarFeedback {
ALL_SAME, DIFFERENT_COLORS, DIFFERENT_MAKES, DIFFERENT_CLASSES
}
public CarFeedback checkCars(List<Car> cars) {
//Do checks
return ALL_SAME; //or whichever enum value is appropriate
}
Your method can be void and throw an exception if there are any problems. There is no need for it to return a boolean. The caller should assume that if no exception was thrown then everything is OK. This is exactly how exceptions were designed to be used.
I would rename the method:
void checkCompatibilityOf(Car... cars) throws IncompatibleCarsException
Alternative approach: Inversion of Control
Rather than returning a value from the method, you can ask the method to callback with its answer(s). E.g.
interface CompatibilityListener {
void onSuccess();
void onFailure(String message);
}
This will avoid the need for a boolean return value, and remove the need for exceptions.
You could go further and extract the logic of building the error message too:
interface DifferenceListener {
void onDifferentColor(Car car1, Car car2);
void onDifferentMake(Car car1, Car car2);
//etc.
}
And this method:
public void checkCompatibilityOf(DifferenceListener listener, Cars... cars) {
for (Car car: cars) {
if (...) {
listener.onDifferentColor(car1, car2);
}
if (...) {
listener.onDifferentMake(car1, car2);
}
// etc.
}
}
Inversion of control can be a powerful approach in some cases, although, as Vidya says (in the comment) it's probably over-engineering in your case!
You can do everything you want with JAVA. You can create your own class to get the object with any included values you prefer. See below :
import java.math.BigInteger;
import java.util.Date;
public class BoolVariable {
private static BoolVariable instance;
public static BoolVariable BOOLVARIABLE = getInstance();
private boolean bool;
private char c;
private String s;
private int i;
private double d;
private float f;
private BigInteger bi;
private Date date;
private static BoolVariable getInstance() {
if (instance == null) {
instance = new BoolVariable();
}
return instance;
}
private BoolVariable() {
}
public BoolVariable(boolean bool, char c) {
this.bool = bool;
this.c = c;
}
public BoolVariable(boolean bool, String s) {
this.bool = bool;
this.s = s;
}
public BoolVariable(boolean bool, int i) {
this.bool = bool;
this.i = i;
}
public BoolVariable(boolean bool, double d) {
this.bool = bool;
this.d = d;
}
public BoolVariable(boolean bool, float f) {
this.bool = bool;
this.f = f;
}
public BoolVariable(boolean bool, BigInteger bi) {
this.bool = bool;
this.bi = bi;
}
public BoolVariable(boolean bool, Date date) {
this.bool = bool;
this.date = date;
}
public boolean getBool() {
return bool;
}
public char getC() {
return c;
}
public String getS() {
return s;
}
public int getI() {
return i;
}
public double getD() {
return d;
}
public float getF() {
return f;
}
public BigInteger getBi() {
return bi;
}
public Date getDate() {
return date;
}
public void setBool(boolean bool) {
this.bool = bool;
}
public void setC(char c) {
this.c = c;
}
public void setS(String s) {
this.s = s;
}
public void setI(int i) {
this.i = i;
}
public void setD(double d) {
this.d = d;
}
public void setF(float f) {
this.f = f;
}
public void setBi(BigInteger bi) {
this.bi = bi;
}
public void setDate(Date date) {
this.date = date;
}
public BoolVariable create(boolean bool, char c){
return new BoolVariable(bool, c);
}
public BoolVariable create(boolean bool, String s){
return new BoolVariable(bool, s);
}
public BoolVariable create(boolean bool, int i){
return new BoolVariable(bool, i);
}
public BoolVariable create(boolean bool, double d){
return new BoolVariable(bool, d);
}
public BoolVariable create(boolean bool, float f){
return new BoolVariable(bool, f);
}
public BoolVariable create(boolean bool, BigInteger bi){
return new BoolVariable(bool, bi);
}
public BoolVariable create(boolean bool, Date date){
return new BoolVariable(bool, date);
}
#Override
public String toString() {
return "BoolVariable{" + "bool=" + bool + ", c=" + c + ", s="
+ s + ", i=" + i + ", d=" + d + ", f=" + f + ", bi="
+ bi + ", date=" + date + '}';
}
}
You can call this class in any routine that you want to get double variable like below:
BoolVariable bv = BOOLVARIABLE.create(true, "HERE IS YOUR VARIABLE LIKE INTEGER, STRING ETC");
So then you can get any value like bv.getBool();
One idea is to always return boolean but if a condition is not met then you throw a flavour of RuntimeException describing the problem. The caller of this method should handle that.
I know this question is pretty old but I still think this method will clear up a lot of things given the nature of the question. Particularly where it says "... a method in java which receives an array of objects, checks for some compatibility and return a boolean value true if all meet, otherwise to return a string containing a message to inform user why some of the compatibilities don't meet ..." Judging from the question incompatible cars are not supposed to be an error, it is actually as per design part of the behavior of the program, meaning that the car can be compatible or not and from what you want to do you want to know why it is not compatible. If all my current assumptions are right I would rather write my method to return Boolean and incase the method returns a false cause the cars do not match I create a local methods and property in my class getCompareErrorMsg() and compare_error_msg before returning the false in this given method I set the compare_error_msg to the exact comparison error msg, which from what I understand from your question was what you wanted to return as string. so the caller of the method check for it's Boolean value, if it is false the caller can call the method getCompareErrorMsg() which actually returns a string and do what ever it wants to do with it.

Categories