How can I return enums like this?
Before I was returing an int with 0 if no, 1 if yes and 2 if other. But this wasn't good way to do. So how should it be done. My code:
class SomeClass{
public enum decizion{
YES, NO, OTHER
}
public static enum yourDecizion(){
//scanner etc
if(x.equals('Y')){
return YES;
}
else if (x.equals('N')){
return NO;
}
else{
return OTHER;
}
}
}
I don't what the "//scanner etc." does, but the methods return type should be decizion:
public static decizion yourDecizion() { ... }
Furthermore, you can add the Y, N, etc. values to the enum constants:
public enum decizion{
YES("Y"), NO("N"), OTHER;
String key;
decizion(String key) { this.key = key; }
//default constructor, used only for the OTHER case,
//because OTHER doesn't need a key to be associated with.
decizion() { }
static decizion getValue(String x) {
if ("Y".equals(x)) { return YES; }
else if ("N".equals(x)) { return NO; }
else if (x == null) { return OTHER; }
else throw new IllegalArgumentException();
}
}
Then, in the method, you can just do:
public static decizion yourDecizion() {
...
String key = ...
return decizion.getValue(key);
}
I think you should do something like these, an enum class. Then you can add as many types you want and the method yourDecizion() will return the enum type depending on the given parameter.
public enum SomeClass {
YES(0),
NO(1),
OTHER(2);
private int code;
private SomeClass(int code) {
this.code = code;
}
public int getCode() {
return code;
}
public static SomeClass yourDecizion(int x) {
SomeClass ret = null;
for (SomeClass type : SomeClass.values()) {
if (type.getCode() == x)
ret = type;
}
return ret;
}
}
Change your code to:
class SomeClass{
public enum decizion {
YES, NO, OTHER
}
public static decizion yourDecizion(){
//scanner etc
if(x.equals('Y')){
return decizion.YES;
}
else if (x.equals('N')){
return decizion.NO;
}
else{
return decizion.OTHER;
}
}
}
Note: The method return type must be decizion instead of enum and decizion should have an upper case name (as all classes should).
You can get the value in below way. Here you have private constructor which will initialize the value you want to set and when the instance method value gets invoked simply return this.key.
public class Application {
enum Day {
MONDAY("Monday"), TUESDAY("Tuesday");
String key;
Day(String str) {
key = str;
}
public String value() {
return this.key;
}
}
public static void main(String[] args) {
System.out.println(Day.MONDAY.value());
}
}
Related
I would like to create a Java class that besides having integer types allows to have also some Enums, that is special values, a bit like Double.
Consider the case where you want to memorize an integer 0,1,100, 1000 or a special value like "0000" or "/" or "VAR";
I suppose your class has to contain those types? as in :
public class ExampleClass
{
// Instance Variables
int intTypeVar;
String stringTypeVar;
double doubleTypeVar;
// Constructor Declaration of Class
public ExampleClass (int intTypeVar, String stringTypeVar,
double doubleTypeVar)
{
this.intTypeVar= intTypeVar;
this.stringTypeVar= stringTypeVar;
this.doubleTypeVar= doubleTypeVar;
}
You can make your own exclusive type like this:
public class State {
JUST_AN_INTEGER,
CHEESE,
SOMETHING_ELSE;
}
public final class MyInteger {
private final int value;
private final State state;
private MyInteger(int value) {
this.value = value;
this.state = State.JUST_AN_INTEGER;
}
private MyInteger(State state) {
if (state == null) {
throw new IllegalArgumentException("State must be non-null");
} else if (state == State.JUST_AN_INTEGER) {
throw new IllegalArgumentException(State.JUST_AN_INTEGER + " requires a value!");
}
this.state = state;
}
public int getValue() {
if (state != State.JUST_AN_INTEGER) {
throw new IllegalStateException("MyValue has no value, it is of state " + state");
}
return value;
}
public int getState() {
return this.state;
}
#Override
public int hashCode() {
return this.value ^ this.state.hashCode();
}
#Override
public int equals(Object o) {
if (!(o instanceof MyInteger)) {
return false;
}
MyInteger other = (MyInteger) o;
return other.state == this.state && other.value == this.value;
}
#Override
public String toString() {
if (this.state == State.JUST_AN_INTEGER) {
return String.valueOf(this.value);
}
return this.state.name();
}
}
This MyInteger can either have a normal integer value or be of one of the other states. The constructors ensure that it's only ever constructed in a consistent way (for example you wouldn't want a JUST_AN_INTEGER constructed without an explicit value and equally you wouldn't want a CHEESE state to also contain a value).
You could also implement the Number class, but that would lead to all kinds of confusing behaviour, since it doesn't act like a normal Number in many cases.
I have this code in Modula-2,
PROCEDURE Prune(typeExp: TypeExp): TypeExp;
BEGIN
CASE typeExp.^class OF
| VarType:
IF typeExp^.instance = NIL THEN
RETURN typeExp;
ELSE
typeExp^.instance = Prune(typeExp^.instance);
RETURN typeExp^.instance;
END;
| OperType: RETURN typeExp;
END;
END Prune;
I have several problems when I try to convert this code into java. I can create an instance and judge if its instance is null and then choose what to return. But I don't really know what to do with the case 2, which is the instance might be a new Opentype(); because only one value can be returned in this case.
public TypeExp Prune(TypeExp typeExp){
TypeExp r = new VarType();
if (r.instance == null) {
return r;
}
else {
r.instance = Prune(r.instance);
return r.instance;
}
}
The second issue is I don't think I can call the function Prune() inside itself, so what can I do? Thanks in advance.
I dont really know Modula-2, but it might be something like this:
public TypeExp Prune(TypeExp typeExp) {
if (typeExp instanceof VarType) {
if (typeExp.instance == null) {
return typeExp;
}
else {
typeExp.instance = Prune(typeExp.instance);
return typeExp.instance;
}
} else if (typeExp instanceof OperType) {
return typeExp;
}
//if typeExp is not an instance of VarType or OperType
return null;
}
The Modula code does not return in all code paths. Thats not possible in Java. I inserted return null in those cases. Thats probably wrong for your application though.
Below example not same as your func, but I think you can modify to your needs. It hides your return types behind Type class => you can return objects of two classes.
Main
package com.type;
public class Main {
public static void main(String[] args) {
Type first = new FirstType();
Type second = new SecondType();
System.out.println(func(first).getTypeName());
System.out.println(func(first).getTypeName());
System.out.println(func(second).getTypeName());
}
public static Type func(Type type) {
if(type instanceof FirstType) {
type.setTypeName("First");
} else {
type.setTypeName("Second");
// something here
}
return type;
}
}
Type
package com.type;
public class Type {
private String typeName;
public Type() {}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
}
FirstType
package com.type;
public class FirstType extends Type {
}
SecondType
package com.type;
public class SecondType extends Type {
}
I'm trying to get the best way to implement a file with all my static enums, without using any getters and setters, just static info, I achieve this in PHP like in the example below, do you really need getters and setters in java?
final class EnumTrade {
const buy = 1;
const sell = 2;
}
final class EnumGender {
const male = 1;
const female = 2;
}
final class EnumHttpMethod {
const get = 1;
const post = 2;
}
public enum EnumTrade {
BUY, SELL
}
and so on.
Edit: If the number matters, do:
public enum EnumTrade {
BUY(1), SELL(2)
}
in java enum not necessary to have getter and setter these are used for normal POJO or beans
sample enum can be:
public enum EventRecurringType {
YEARLY("1"),
QUARTERLY("2"),
MONTHLY("3"),
WEEKLY("4"),
DAILY("5"),
NONE("0");
private String value;
EventRecurringType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
#Override
public String toString() {
return this.getValue();
}
public static EventRecurringType getEnum(String value) {
if(value == null)
throw new IllegalArgumentException();
for(EventRecurringType v : values())
if(value.equalsIgnoreCase(v.getValue())) return v;
throw new IllegalArgumentException();
}
}
public enum EnumTrade
{
BUY,
SELL,
}
If all you need is the ordinal values of the enums, you can access those directly via EnumTrade.BUY.ordinal
If you want to store other data in the enum, do something like this (expanding as needed):
public enum EnumGender
{
MALE(1),
FEMALE(2);
private final int value;
private EnumGender(String value)
{
this.value = value;
}
public int getValue()
{
return this.value;
}
//In case you need to grab an enum by the value constant
public getEnumGender(int value)
{
switch(value)
{
case 1:
return EnumGender.MALE;
case 2:
default:
return EnumGender.FEMALE;
}
}
}
For sake of completeness and the fact answers pop in while writing i changed my original answer to mention you could store all your enums in one java class.
=> It is way better to have them stored in own files like user Tichodroma suggests
However translating your exmaple code you could build this in Java:
public class MyEnums {
public enum EnumTrade{
BUY, SELL
}
public enum EnumGender{
MALE, FEMALE
}
public enum EnumHttpMethod{
GET, POST
}
}
And then use the different enums from outside like this:
MyEnums.EnumTrade.BUY
public enum MyConst{ BUY(1), SELL(2), MALE(3), FEMALE(4), GET(5), POST(6);
public final int value;
MyConst(int value) {
this.value = value;
}
public int getValue() {
return value;
}
};
or Just go with
public enum MyConst{ BUY(1), SELL(2) }; and same for MALE, FEMALE ....
In this method I get string as input and according to the string name I need to return value sometimes its string sometime int ,double,int64 ,bool etc
Since its dynamic type i don't know how to define it in the method return type
and how to add to it the value and how to call to this method that the return type is dynamic ,any idea?
public static ? SwitchInput(String TypeName) {
if (TypeName == "java.lang.String" ) {
Return = "A";
}
else if (TypeName == "int" ) {
Return = 1;
}
else if (TypeName == "double") {
Return = 1.00
}
etc for bool and all the other types
}
Object will be your best bet, unless returned type shares an Ancestor
Example :
public static Object switchInput(String typeName) {
if ("java.lang.String".equals(typeName)) {
return "A";
}
else if ("int".equals(typeName)) {
return 1i;
}
else if ("double".equals(typeName)) {
return 1.0d
}
}
Another example with generics
static <T> T switchInput(String typeName){
if ("java.lang.String".equals(typeName)) {
return "A";
}
else if ("int".equals(typeName)) {
return 1i;
}
else if ("double".equals(typeName)) {
return 1.0d
}
}
String str = MyClass.switchInput("java.lang.String")
I have not tested that, this is a simpler version of my first thought about generics
To know what the return type is, you have to find a container where all these types fit in. Obviously, this is Object. You'd have to convert the primitive types to the corresponding object (like int to Integer).
A better approach would be to create a new container class, which holds a generic type <T>. Like
public class SwitchDemo {
public static SwitchInputType<?> switchInput(String typeName) {
if (typeName.equals("java.lang.String")) {
return new SwitchInputType<String>(new String("A"));
} else if (typeName.equals("int")) {
return new SwitchInputType<Integer>(new Integer(312));
}
return null;
}
public static class SwitchInputType<T> {
private T type;
public SwitchInputType(T type) {
super();
this.type = type;
}
public T getType() {
return type;
}
public void setType(T type) {
this.type = type;
}
}
public static void main(String[] args) {
SwitchInputType<?> sit1 = SwitchDemo.switchInput("java.lang.String");
System.out.println(sit1.getType());
SwitchInputType<?> sit2 = SwitchDemo.switchInput("int");
System.out.println(sit2.getType());
}
}
As an ugly solution to your problem, you could set your method to run the type Object. (as Boolean, Integer, Double are all subtypes)
You would have to ensure though that you then inferred the correct type afterwards when using the returned value (using instanceof) and recast it to the correct type.
Can I ask though why you need such a method? This is abusing the notion of a method definition slightly.
public static Object SwitchInput(String TypeName) {
if (TypeName.equals("java.lang.String") ) {
Return = new String("A");
}
else if (TypeName.equals("int") ) {
Return = new Integer(1);
}
else if (TypeName.equals("double")) {
Return = new Double(1.00) ;
}
etc for bool and all the other types
}
And using this code snippet to infer what type it is further on down in your code
if(returned_value instanceof Double)
etc.
Given the following java enum:
public enum AgeRange {
A18TO23 {
public String toString() {
return "18 - 23";
}
},
A24TO29 {
public String toString() {
return "24 - 29";
}
},
A30TO35 {
public String toString() {
return "30 - 35";
}
},
}
Is there any way to convert a string value of "18 - 23" to the corresponding enum value i.e. AgeRange.A18TO23 ?
Thanks!
The best and simplest way to do it is like this:
public enum AgeRange {
A18TO23 ("18-23"),
A24TO29 ("24-29"),
A30TO35("30-35");
private String value;
AgeRange(String value){
this.value = value;
}
public String toString(){
return value;
}
public static AgeRange getByValue(String value){
for (final AgeRange element : EnumSet.allOf(AgeRange.class)) {
if (element.toString().equals(value)) {
return element;
}
}
return null;
}
}
Then you just need to invoke the getByValue() method with the String input in it.
You could always create a map from string to value - do so statically so you only need to map it once, assuming that the returned string remains the same over time. There's nothing built-in as far as I'm aware.
According to effective java (2nd ed) item 30, it can be (it is much faster than the loop)
public enum AgeRange {
A18TO23("18-23"),
A24TO29("24-29"),
A30TO35("30-35");
private final String value;
AgeRange(String value){
this.value = value;
}
#Override public String toString(){
return value;
}
private static final Map<String, AgeRange> stringToEnum =
new HashMap<String, AgeRange>();
static {
for (AgeRange r : values()) {
stringToEnum.put(r.toString(), r);
}
}
public static AgeRange getByValue(String value){
return stringToEnum.get(value);
}
}
for (AgeRange ar: EnumSet.allOf(AgeRange)) {
if (ar.toString().equals(inString)) {
myAnswer = ar;
break;
}
}
Or something like that? Just typed in, haven't run through a compiler. Forgive (comment on) typos...
Or use logic like this to build a map once. Avoid iteration at runtime. Good idea, Jon.
The class overrides "toString()" - so, to get the reverse operation, you need to override valueOf() to translate the output of toString() back to the Enum values.
public enum AgeRange {
A18TO23 {
public String toString() {
return "18 - 23";
}
public AgeRange valueOf (Class enumClass, String name) {
return A18T023
}
},
.
.
.
}
Buyer beware - uncompiled and untested...
The mechanism for toString() and valueOf() is a documented part of the API
You could try something like the following?
static AgeRange fromString(String range) {
for (AgeRange ageRange : values()) {
if (range.equals(ageRange.toString())) {
return ageRange;
}
}
return null;
}
Or, as others suggested, using a caching approach:
private static Map<String, AgeRange> map;
private static synchronized void registerAgeRange(AgeRange ageRange) {
if (map == null) {
map = new HashMap<String, AgeRange>();
}
map.put(ageRange.toString(), ageRange);
}
AgeRange() {
registerAgeRange(this);
}
static AgeRange fromString(String range) {
return map.get(range);
}