Android Java cast long to enum problem - java

I have an issue with Java cast long type to Enum's type.
I'm using this code :
public enum RPCPacketDataType {
PT_JSON(1),
PT_BINARY(2);
private int value;
RPCPacketDataType(int i){
this.value=i;
}
public int getNumericType(){
return value;
}
}
static RPCPacketDataType tmpPacket_packetType;
And I need to do something like this :
case 2:
{
long intVal = Long.parseLong(thisPart);
if(intVal == 0){
isBad = true; break;
}
tmpPacket_packetType=intVal;
break;
}
where thisPart is just a string : String thisPart;
And the error says : Type mismatch: cannot convert from long to RPCCommucatorDefines.RPCPacketDataType
Any suggestions how to fix that?

You need to write a method, probably in RPCPacketDataType:
public static RPCPacketDataType valueOf(int value) {
...
}
Then call that from your case statement. Given that the value can only be an integer, you should almost certainly be using Integer.parseInt instead of Long.parseLong.
How you implement the valueOf method is up to you - you could iterate through the EnumSet of all values trying to find a match, or create a HashMap from Integer to RPCPacketDataType, or potentially just an array (with validation). It will depend on what's in your enum, and how many values there are to look through.
Note that you should also consider what to do if valueOf is passed a value which doesn't correspond to any enum value - one option is to return null (and probably test for that explicitly in the calling code); another is to throw an exception.

Related

Constructing a Java method that returns a primitive data type that is decided by the input?

I would like a method to read a string, and return it's value in the implied (best fitting) data type. I would like to avoid doing the string to data type conversion in "main", as the code is likely to create clutter. Is this possible? Can I create a method that returns different types? What does the constructor look like?
It's not possible to return different primitive types. What you can do is declare the method as returning Object, and at runtime return boxed primitives: instances of Integer, Double, Boolean, etc.
You could explore an enum type as a way to classify the type you end up with. You don't say what you want to use it for, so this may not be best, but it could be done in a way that handles the requirements you do give.
public class ClassifiedType
{
public enum ClassifiedTypeType { INTEGER, FLOAT, STRING, BOOLEAN };
ClassifiedTypeType typeType = null;
int integerValue;
float floatValue;
String stringValue;
boolean booleanValue;
public ClassifiedType(int i) { integerValue = i; typeType = ClassifiedTypeType.INTEGER; }
public ClassifiedType(float f) { floatValue = f; typeType = ClassifiedTypeType.FLOAT; }
// etc.
public int getIntegerValue()
{
if (typeType != ClassifiedTypeType.INTEGER)
{
throw new IllegalArgumentException("Attempting getInteger on type of " + this.toString());
}
else
{
return integerValue;
}
}
// do gets for other types similarly.
public static ClassifiedType getClassifiedType(String string)
{
// parse the string, determine which type you want,
// instantiate a ClassifiedType with its value and
// and type, and return it.
}
}
Other classes can use the ClassifiedTypeType (hopefully with a better name) to determine what kind of value to get from it, to the extent they need that.
Anyway, it beats returning Object and then having to use instanceof all over the place to figure out what you're dealing with, and this extends to non-primitives if you ever need that.
A single Java method cannot return multiple types. This is because Java is a strongly typed language.
There are a few different ways to accomplish this. If you'd like to go the constructor route as mentioned in the OP, it would look something like this:
public class Demo(){
Demo(String str){
// Do something...
}
Demo(int newInt){
// Do something...
}
// Other constructors for other types here
}

How to implement a dynamic generic type return method without casting at runtime in C#?

Say I want to convert the below implementation in Java to C#, so that I don't have to cast the returned value at runtime, where the casting should already be handled in the get method.
why not create setters and getters, if you ask? simply because I plan to have 50-100+ attributes and I don't want to create setters and getters for every attributes.
[c#] - what i want to end up doing in c#
string name = playerA.getAttribute(Attribute.NAME);
int age = playerA.getAttribute(Attribute.AGE);
Currently I can't unless I cast the returned value to the correct type. But can I do that casting in side the get method before returning?
[Java] - anyhow, this is the current java implementation that works without casting
//setting attributes
playerA.setAttribute(Attribute.NAME, "Tom");
entityB.setAttribute(Attribute.AGE, 4);
...
//getting the attribute without casting
string name = playerA.getAttribute(PlayerAttribute.NAME);
int age = playerB.getAttribute(PlayerAttribute.AGE);
The method inside a Player/Entity is setup like this to get attributes
[Java]
public <E> E getAttribute(Attribute attr){
//atrributeRepository is EnumMap<Attribute, Object>
//how I will get my attribute value type at runtime
Object result = attributeRepositoryMap.get(attr);
//the enumMap will only ever hold these three type for this example
if(result instanceof Boolean){ return (E) (Boolean) result; }
if(result instanceof String){ return (E) (String) result; }
if(result instanceof Integer){ return (E) (Integer) result; }
return null;
//say all checks are in place and null will never be reach
}
The closest I was able to get in c# is this.
[c#] - though I can deal with it, i would like to prevent casting
string name = (string) getAttribute<string>(Attribute.NAME);
int age = (int) getAttribute<int>(Attribute.AGE);
the method
public T getAttribute<T>(Attribute attribute){
{
Object result = attributeRepositoryDictionary[attribute];
return (T)result;
}
is this as closest as I can get with c#, where casting is needed for getting attributes?
I'm not sure I really like it as an idea - but you could do this by making Attribute generic:
public static class Attributes
{
public static Attribute<int> Age = new Attribute<int>("age");
public static Attribute<string> Name = new Attribute<string>("name");
}
public class Attribute<T>
{
public string Key { get; }
public Attribute(string key)
{
Key = key;
}
...
}
Then you can implement your method as:
public T GetAttribute<T>(Attribute<T> attribute)
{
// attributeDictionary would be a Dictionary<string, object>
return (T) attributeDictionary[attribute.Key];
}
At that point, type inference will be your friend, so you can just write:
int a = player1.GetAttribute(Attributes.Age);
and it'll be equivalent to:
int a = player1.GetAttribute<int>(Attributes.Age);
I was able to find an alternative solution along with #Jon Skeet, which this was more of what I was looking for (not sure if it is an ideal design though). Anyhow, little did I know there was a keyword called "dynamic" in cSharp.
It allowed my method getAttribute() to return any type at runtime, The only requirement is that you must know the return type.
So I do not recommend using this approach if you plan to work with many return types that are in the 5+. That's why I would recommend using something like an enum to give clues on what type will be returned.
In my case, I will only deal with the basic common return types (int, string, float, bool), so its rather easy to know what type will be returned base on the attribute that is called.
class Entity
{
Dictionary<Attribute, Object> attributeRepositoryEnumMap;
...
public dynamic getAttribute(Attribute attribute){
Object result = attributeRepositoryEnumMap[attribute];
return result;
}
}
now I can get return attributes like in the example below without casting
class MyApp
{
Entity e = new Entity();
e.setAttribute(Attribute.NAME, "Bob");
e.setAttribute(Attribute.AGE, 55);
e.setAttribute(Attrbute.HEIGHT, 5.5f);
string name = e.getAttribute(Attribute.NAME);
int age = e.getAttribute(Attribute.AGE);
float height = e.setAttribute(Attribute.HEIGHT);
}
Not sure how this will all work out for me, but a part of this attempt was to also find an easier work around saving and hydrating my json objects without creating tons of setters and getters.

How can I make a method return a "variable" (not value)?

I have a set of global double variables called softPrice0 (and 1, 2, 3)
The thing is I had the idea to use a method like this:
SOMEWORD getOPrice() //I tried double, String, Object, variable, etc
{return softPrice0;}
So I can use it later like this:
getOPrice()=5.8;
I know that using an array would do the trick but I would like to know if I can make methods throw variable names to use it as I explained.
thanks ortang
This is how I made it, the approach changed though.
setOPrice(Double.parseDouble(txtPriceDolar.getText())); //thats the call
void setOPrice(double value) { //this is the setter, no need of getter
switch(combobox.getSelectedIndex())
{case 1: this.softPrice0 = value; break;
case 2: this.softPrice1 = value; break;
case 3: this.softPrice2 = value; break;
default: this.softPrice3 = value; break;}}
now looks more simple, Thanks to everybody. Asking the wrong questions teaches a lot.
For setting you can not use the getter as you want to. getOPrecio()=5.8; will not work. You have to use a setter method. Take a look at the following sample, to access the value you have to use the getter(read) or setter(write).
You would want to use something like setOPrecio(5.8).
public class DoubleHolder {
private double vaule;
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value
}
}
Java passes by value, so this isn't possible without a separate getter and setter.
Examples:
void setOPrecio(double softPrecio0) {
this.softPrecio0 = softPrecio0;
}
double getOPrecio() {
return softPrecio0;
}
However, if the value is a class, you may be looking for something along the lines of the singleton pattern.
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
Singleton example code from Wikipedia's article.
Java has no way of passing or returning a "variable".
The closest you are going to get are:
passing or returning an object whose fields are the "variables", or
passing or returning an array whose elements could be viewed as "variables".
And to be clear, neither of the contrivances are close to passing or returning a bare variable.
You need to rethink your problem / solution in terms of the constructs that Java does provide.

value of what the enum is currently set to

This should be total obvious, but it isn't. Is there a way to get the value of a enum as in the example below?
example:
public enum Numbers
{
zero, one, two
}
//later on
Numbers numbers = Numbers.zero;
// this is the part that I can not figure out the java equivalent of?
int number = numbers.value();
Does this make sense what I am trying to do?
It is generally considered bad practice to rely on ordinal since it is based on the order of the enum constants. A better solution would be to pass information to each instance. Just write a constructor and method like this:
public enum Number {
ZERO(0), ONE(1), TWO(2);
private int value;
private Number(int value) {
this.value = value;
}
public int value() {
return value;
}
};
Then you use it like you want
Number numbers = Number.ZERO;
int number = numbers.value();
and you won't have to worry about the actual order of the code if you add Numbers later.
Note: It is idiomatic in Java for enum names to be singular and for constants to be uppercase.
Based on your comments it appears you need to map an integer value to your enum to integrate it into another part of your code.
Rather than relying on the ordering you really want to do this yourself:
public enum MyEnum {
ZERO(0), ONE(1), TWO(2);
private int mapping;
MyEnum(int mapping) {
this.mapping = mapping;
}
public int getMapping() {
return mapping;
}
}
You could then compare via:
MyEnum e = MyEnum.ZERO;
if (someInt == e.getMapping()) { ... }
(Or even just MyEnum.ZERO.getMapping() )
You can use the ordinal() method. However, this is discouraged / risky, since if you ever change the order or arrangements of your enums, it will fail. e.g., you change to powers of two
public enum Numbers {
zero, one, two, four
}
then four.ordinal() will be 3.
If you really want a number associated with the enum, you should define your own method, e.g. order() or whatever. In the initial implementation it could return ordinal(), but, when you add four in the future, you can update that method.
p.s. Standard style is to capitalize the enums, e.g. ZERO, ONE, etc...
It depends on what you need. Here are 2 use cases:
1) You will probably need to test the value of an incoming "Numbers". For this use case, a switch case is the best solution.
void myMethod(Numbers n){
switch(n){
case zero:
//do something
break;
case one:
//do something
break;
//etc.
}
}
2) You can calso need to assign a value to each Numbers and be able to retrieve it. For this use case, you can define a constructor for your enum
public enum Numbers
{
zero(0), one(1), two(2);
private int value;
private Numbers(int value){
this.value=value;
}
}
Then, in your code, you can get this value:
void myMethod(Numbers n){
int value = n.getValue();
//do something with this value...
}
Last remark : Your enum names don't follow the java convention. They should be named with uppercase letters and eventually character '_'. ex: ONE, TWO, THREE, ANOTHER_VALUE

Get index of enum from string?

I have a string value, I also have an array of strings and an enum containing the range also.
To get the index of the string in the array, from the value supplied I write this:
Arrays.asList(myClass.BAUD_RATES).indexOf(username)
How do I do this for an enum? Can I use ordinal? Or do i have to make my own method?
The method might go like:
public enum Fruit {
...
static public boolean isMember(String aName) {
Fruit[] aFruits = Fruit.values();
for (Fruit aFruit : aFruits)
if (aFruit.fruitname.equals(aName))
return aFruit;
return false;
}
...
}
Not sure if I understand you correctly but based on question title you may be looking for
YourEnum.valueOf("VALUE").ordinal();
//like Directions.valueOf("NORTH").ordinal();
YourEnum.valueOf("VALUE") returns enum value with name "VALUE"
each enum value knows its position (indexed from zero) which we can get by calling ordinal() method on it.
I might not understand you question, but the same code works for enums too:
int index = Arrays.asList(YourEnum.values()).indexOf(YourEnum.ENUM_ITEM);
Or you can get:
int index = YourEnum.valueOf("ENUM_ITEM").ordinal();
Try this simple solution:
Fruit.values()[index]
If you want to retrieve the index, you can use ordinal. If you want to assign some specific value to String, you may define your own method to retrieve it.
enum DAY
{
MONDAY(10),
TUESDAY(20);
int value;
DAY(int x)
{
this.value = x;
}
public int getValue()
{
return value;
}
Now value and ordinal can be retrieved as :
for(DAY s : DAY.values() )
{
System.out.println(s.ordinal());
System.out.println(s.getValue());
}
The following logic will also work.
If you want to check and you know the fruitname already don't use for loop go with the approach mentioned by Pshemo
for (Fruit aFruit : aFruits)
if (aFruit.name().equals(aName))
return aFruit.ordinal();
Adding here the solution that worked for me:
YourEnum.values.indexOf("VALUE");

Categories