0

I have a class:

public class Something{
    public static final int SOMETHING_0 = 0;
    public static final int SOMETHING_1 = 1;
    public static final int SOMETHING_2 = 2;
    // ... etc
}

values are unique, How can i get the name of a property by its value?

via reflection, for example:

// intValue = 1
String getNameByValue(int intValue){
    ...
    // returns "SOMETHING_1"
    return nameOfProperty;
} 
Ninja Coding
  • 1,357
  • 1
  • 16
  • 26
  • 1
    what happens if there is more than one property with `intValue` of 1? – Tom Mac Dec 17 '15 at 17:10
  • 6
    You may consider using Enumeration for such a case. – Arnaud Dec 17 '15 at 17:11
  • This might get you going in the correct direction if you have to use reflection : http://stackoverflow.com/questions/15112590/get-the-class-instance-variables-and-print-their-values-using-reflection – Tom Mac Dec 17 '15 at 17:12
  • 1
    Berger is right, you probably shouldn't be using class constants for this, and definitely not reflection. – Sam McCreery Dec 17 '15 at 17:13
  • 1
    Can you describe the more general aim of what you're trying to do? You might find that people are able to help you better. @Berger's suggestion of an Enumeration is probably what you want. – DaveyDaveDave Dec 17 '15 at 17:16
  • @DaveyDaveDave i just want to print the choosen option in a switch(intChoosen) I'm ussing constants to choose an option and i want to print: `selected: SOMETHING_1` instead of `selected: 1` – Ninja Coding Dec 17 '15 at 17:20
  • there are two ways, you could do some nasty tricks with reflection, or implement them as enum – user902383 Dec 17 '15 at 17:20
  • I cant change to Enums because its a remote service where the only value sent is an int value i cant change type of parameter sent to Enum. – Ninja Coding Dec 17 '15 at 17:28
  • 2
    You can get an enum constant based on its ordinal (which is an int), and then display the enum's name. – JB Nizet Dec 17 '15 at 17:31

2 Answers2

3

you could do this in hard way:

 public class Something {
        public static final int SOMETHING_0 = 0;
        public static final int SOMETHING_1 = 1;
        public static final int SOMETHING_2 = 2;

    }

 String getNameByValue(int intValue) throws IllegalArgumentException,
        IllegalAccessException {
    for (Field field : Something.class.getFields()) {
        if (field.getInt(null) == intValue) {
            return field.getName();
        }
    }
    return "";
}

and if you do this, Santa will go postal and slaughter dozen of innocent kittens.

Our you could do this in correct way an implement your values as enum

public enum Something {
        SOMETHING_0(0),
        SOMETHING_1(1),
        SOMETHING_2(2);
        final int val;
        Something(int val){
            this.val = val;
        }
        static public  Something byNumber(int number){
            for (Something somthing : Something.values()){
                if (number==somthing.val){
                    return somthing;
                }
            }
            throw new RuntimeException("Value not found");
        }

    }
user902383
  • 8,420
  • 8
  • 43
  • 63
1

One option is this:

public class Something {
    public static final int SOMETHING_0 = 0;
    public static final int SOMETHING_1 = 1;
    public static final int SOMETHING_2 = 2;
    public String toString(int value) {
        switch (value) {
            case SOMETHING_0: return "SOMETHING_0";
            case SOMETHING_1: return "SOMETHING_1";
            case SOMETHING_2: return "SOMETHING_2";
        }
        throw new IllegalArgumentException("Unknown value: " + value);
    }
}
// Use:
int value = Something.SOMETHING_1;
String name = Something.toString(value);

If int values are consecutive, starting at 0, then you can use an enum and it's ordinal() position:

public enum Something {
    SOMETHING_0, SOMETHING_1, SOMETHING_2
}
// Use:
int value = Something.SOMETHING_1.ordinal();
String name = Something.values()[value].name(); // or toString()

If int values are not consecutive, you can still use enum:

enum Something {
    SOMETHING_0(0),
    SOMETHING_10(10),
    SOMETHING_20(20);
    private final int value;
    private Something(int value) {
        this.value = value;
    }
    public int getValue() {
        return this.value;
    }
    public static Something from(int value) {
        for (Something something : values())
            if (something.value == value)
                return something;
        throw new IllegalArgumentException("Unknown value: " + value);
    }
}
// Use:
int value = Something.SOMETHING_10.getValue();
String name = Something.from(value).name(); // or toString()

Alternatively, if you want display text to be different from constant name, and you don't like exceptions, you can do this:

enum Something {
    SOMETHING_0 ( 0, "Something 0"),
    SOMETHING_10(10, "Something 10"),
    SOMETHING_20(20, "Something 20");
    private final int    value;
    private final String description;
    private Something(int value, String description) {
        this.value = value;
        this.description = description;
    }
    public int getValue() {
        return this.value;
    }
    public String getDescription() {
        return this.description;
    }
    public static Optional<Something> from(int value) {
        for (Something something : values())
            if (something.value == value)
                return Optional.of(something);
        return Optional.empty();
    }
    public static String toString(int value) {
        for (Something something : values())
            if (something.value == value)
                return something.description;
        return "Unknown value (" + value + ")";
    }
}
// Use:
String desc = Something.toString(value);
// Or:
String desc = Something.from(value).map(Something::getDescription).orElse("Oops");
Andreas
  • 154,647
  • 11
  • 152
  • 247