I am using an imported class with has constant field values set using:
public static final int BLUE = 1;
public static final int GREEN = 2;
etc.
Is there any way of getting a string representation of the constant field value from the int value?
i.e. given the value 2 I want to get a string of GREEN.
P.S. This isn't my class so I can't use ENUMs
I think your friend here would be enums
public enum Color {
BLUE(1), GREEN(2);
}
Now if you try to get Color.BLUE.ordinalValue() it will return 1 and if you say Color.BLUE.name() it will return BLUE.
You can also declare private variables in the enum just like a pojo class and initialize them un the constructor. You can write getter methods to return those variables.
If you can change the class which contains these constants, it would be better to make it an enum with a value() method.
Otherwise, I would suggest building a Map<Integer, String> once using reflection, and then just doing map lookups:
Map<Integer, String> valueToStringMap = new HashMap<>();
for (Field field : Foo.class.getFields()) {
int modifiers = field.getModifiers();
if (field.getType() == Integer.class && Modifier.isPublic(modifiers)
&& Modifier.isStatic(modifiers)) {
valueToStringMap.put((Integer) field.get(null), field.getName());
}
}
Related
How to retrieve the enum name using value. By passing JOHN I need to retrieve the value as single
public enum Status {
JOHN("single"),
ALEX("married"),
MARTHA("not known");
}
Is it possible to have default value as well in-case value does not match?
To do this you need to define a constructor and a String variable. Then you could create a getter method to return the String variable:
public enum Status {
JOHN("single"),
ALEX("married"),
MARTHA("not known");
private String value;
private Status(String str) {
value = str;
}
public String getValue() {
return this.value;
}
}
And then to get the value you can do:
Status.JOHN.getValue()
To get the enum from a String you can use the valueOf() method:
Status.valueOf("JOHN").getValue();
However this will throw an error if the inputted String does not correspond to an enum. You could either wrap it in a try-catch to assign a default to it:
try {
Status.valueOf("JOHN").getValue();
} catch(IllegalArgumentException e) {
//Assign default
}
However a better design might be to put the possibilities into a HashMap and see if the inputted String is in the HashMap:
Map<String, Status> status = new HashMap<>();
status.put("JOHN", Y.JOHN);
if(status.containsKey(input)) {
//Do stuff
} else {
//Assign default
}
Define your enum like
enum Status {
JOHN("single"), ALEX("married"), MARTHA("not known");
private String value;
private Status(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
Now to fetch the value :
System.out.println(Status.JOHN.getValue());
Here define a parameterized constructor for each enum and store this value in a member variable.
A Java enum is an object, just like other objects in most ways. You can give it fields, methods, and constructors.
In this case, you can provide a marriage field and set it in a constructor just like you would for any other object.
Check out the official page on Java enums to see official examples, specifically the example with planets for your case. The Java Tutorials: Enum Types
Note also that you might not want to represent this specific data as an enum. You will be limited to only those 3 specific people by doing so. This is only appropriate if you know that you definitely will have only this specific list of people for the entire lifetime of this code. Otherwise you should just use a normal object.
A better idea might be to have a marriage enum and give your people a field of that type.
public enum MarriageStatus
{
Married,
NotMarried,
Unknown;
}
public class Person
{
String name = "Unknown";
MarriageStatus marriageStatus = MarriageStatus.Unknown;
}
I have java class which has all constants as given below:
public final class CategoryIDs {
public static final String Extraction_of_natural_gas = "1111";
public static final String Mining_of_hard_coal = "2222";
public static final String Mining_of_iron_ores = "3333";
public static final String Mining_of_lignite = "4444";
}
Now I want to access these constants in some other class through a variable which holds name of the variable.
For example:
String temp = "Extraction_of_natural_gas";
Using this temp variable I want to access constants from above class. But I can't do CategoryIDs.temp as it isn't allowed. So what is the best way to achieve this?
You can use reflection to extract it:
String value = (String) CategoryIDs.class.getField(temp).get(null);
The null argument passed to get signifies this is a static field, and no instance is required in order to get its value.
Note that this technique is very error prone. The code above doesn't contain any error checking or exception handling in order to make it easier to read, but a real application should probably contain them.
If you really, really need to do this with your current structure, you could use reflection.
However, you may well find that an enum would be a better fit. Something like:
public enum CategoryID {
EXTRACTION_OF_NATURAL_GAS("Extraction_of_natural_gas", 1111),
MINING_OF_HARD_COAL("Mining_of_hard_coal", 2222),
MINING_OF_IRON_ORES("Mining_of_iron_ores", 3333),
MINING_OF_LIGNITE("Mining_of_lignite", 4444);
private static final Map<String, CategoryID> keyMap;
static {
keyMap = new HashMap<>();
for (CategoryID category : CategoryID.values()) {
keyMap.put(category.getKey(), category);
}
}
private final String key;
private final int value;
public int getValue() {
return value;
}
public String getKey() {
return key;
}
private CategoryID(String key, int value) {
this.key = key;
this.value = value;
}
public static CategoryID fromKey(String key) {
return keyMap.get(key);
}
}
Benefits of this approach:
You separate the name in the code (which is now more conventional for Java) from the key you'd provide in the data. That means you can use whatever keys you'd like in the data, including ones with spaces in etc. They no longer need to be valid identifiers.
You still get compile-time safety when you refer to the enum values from code.
You get better safety as you'll never accidentally use a string instead of a category ID, which you could easily have done using your constants.
I think you are looking for introspection. This is the "read only" part of reflection, in which you can retrieve the value of an object.
The code would be as follows, pieced for ease of understanding:
Object value = null;
String constName = "Bar";
Field constant = Foo.class.getField( constName );
if ( constant != null ) {
value = constant.get( null );
}
if ( value != null ) {
System.out.println( value );
} else {
System.out.println( "Constant " + constName + " was not found." );
}
Interestingly, you can access the value from the Field object calling get(), and you pass null because the constant is static, and thus you don't have an instance to extract the value from.
You can find the whole code here: http://ideone.com/v4fcvH
Hope this helps.
I have an enum and I have an integer value associated to each. One of my function accepts that enum. In the function body, I want to fetch the associated int value. How I am doing it right now is it to create a map (with enum as key, and integer code as value) in the static block and use this map to get code corresponding to an enum. Is this the right way of doing it ? Or is there any better established way to achieve the same ?
public enum TAXSLAB {
SLAB_A(1),
SLAB_B(2),
SLAB_C(5);
private static final Map<TAXSLAB, Integer> lookup = new HashMap<TAXSLAB, Integer>();
static {
for(TAXSLAB w : EnumSet.allOf(TAXSLAB.class)) {
lookup.put(w, w.getCode());
}
}
private int code;
private TAXSLAB(int code) {
this.code = code;
}
public int getCode() {
return code;
}
public static int getCode(TAXSLAB tSlab) {
return lookup.get(tSlab);
}
}
Here is the related SO post. But here answer is suggesting to create the map with int value as key as enum as value. So this can not be used to fetch numeric value using enum without iterating through the map
How to get enum's numeric value?
You do not need the map to retrieve code from an enum object, because the call of TAXSLAB.getCode(s) produces the same value as s.getCode():
TAXSLAB s = ...
int c1 = TAXSLAB.getCode(s);
int c2 = s.getCode();
// c1 == c2 here
int code is a field of enum TAXSLAB object, so you can get it directly.
This works for values associated with an enum from within the enum. If you need to associate a value with an enum outside the enum, the most performant way of doing it is by using EnumMap class designed specifically for this purpose.
I have a class like the following:
public class Prefs {
public static final int PREF_NAME = 0;
public static final int PREF_SURNAME = 1;
public static final int PREF_LOCATION = 2;
String[] defaults = { "unknown", "unknown", "nowhere" }
String[] prefs;
public String getPref(int id) {
return prefs[id];
}
}
So I can use the following syntax:
Prefs p = new Prefs();
p.setDefaults() // irrelevant code not included
p.getPref(Prefs.PREF_LOCATION); // much more readable than getPref(2);
Is this approach correct? Are there any better options to do accomplish this?
EDIT: Please provide a simple example.
I think enum would be exactly what you need and perfect.
Either use enum or ValuedEnum (org.appache.commons), when values do not change.
In ValuedEnum you can provide custom texts, for a value, the standard enum uses the enum field name as text.
if you are using the java enum, consider using the approach where you explicitly assign a value to the enum (by providing an enum constrcutor with paramater "value").
From javarevisited :
public enum Currency {
PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
private int value;
private Currency(int value) {
this.value = value;
}
};
This Valied enum approach is neccessary when you want to make sure that the values never changes (e.g for persitence). java ordinal() can not provide that.
If your list of elements in 'prefs' is going to be dynamic, you may want to consider using a hashtable: -
http://docs.oracle.com/javase/6/docs/api/java/util/Hashtable.html
This would allow you to have a key that would refer to the specific element.
(From the javadoc) This example creates a hashtable of numbers. It uses the names of the numbers as keys:
Hashtable numbers = new Hashtable();
numbers.put("one", new Integer(1));
numbers.put("two", new Integer(2));
numbers.put("three", new Integer(3));
To retrieve a number, use the following code:
Integer n = (Integer)numbers.get("two");
if (n != null) {
System.out.println("two = " + n);
}
Alternatively, you can use an ArrayList if you want random access.
http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html
Ok my problem isnt really a serious one, im just trying to find a clever way of access/modification of class member variables. Here is the code:
public class Storage{
private int cookies= 0;
private int rolls= 0;
private int candies= 0;
private int lolipops= 0;
private int iceCreams= 0;
public void addCookies(int howMuch){ //this is the dirty way of creating method for
this.cookies = cookies+howMuch; //every member variable
}
public void addValue(String stat, int howMuch){ //i would like to do it only
//by passing the name
//of variable and then cast it as integer
//so that it would relate to my class members
int value = this.(Integer.parseInt(stat)); // <- YES i know its ridiculous
//im just trying to explain what is my aim
value = value + howMuch;
this.(Integer.parseInt(stat)) = value;
}
}
Generally i would like to access a field by passing its name to a method, read value of that member, add to it some value, and then store it. Yes i know that it easily can be done with separate methods, or even with one by using some arraylist and comparisons of member names with parameter passed to method. But i would like to do it "fast" without redundant code writing.
Now i have like 5 members, but what about 15000? My aim is to simplify the whole processing and code writing. So generally is it possible to do such redundant code writing bypass? Since i know that i will always pass appropriate name to method... Unless the rule of thumb is to create method for each variable?
Normally you would use a collection like a Map.
public class Storage{
private final Map<String, Integer> inventory = ...
public void addCount(String key, int count) {
Integer i = inventory.get(key);
if (i == null) i = 0;
inventory.put(key, i + count);
}
I guess that by using reflection you can iterate through the fields/methods of your object and do your computation.
For one specific field:
Field member = myObject.getClass().getField(fieldName);
// If you know the class: Field member = MyClass.class.getField(fieldName);
System.out.println(member.getInt(myObject)); // Get the value
member.setInt(myObject, 4); // Set the value
If you want to something for all the public members:
for(Field member: myObject.getClass().getFields())
// Or you can do: for(Field member: myClass.class.getFields())
{
member.getInt(myObject)); // Get the value
member.setInt(myObject, 4); // Set the value
}
Basically, what you do is that you find the Field object that represents the members of you object, then you can manipulate it.
Most IDEs will generate setters and getters for you. This will do what you want with no bother or effort. If this is insufficient, write a method which uses reflection to set the values.
If you have a class with 15000 members, and by this I assume you mean variables private to a class, then you have other issues to resolve.