how to get enum id using its enum name - java

public enum EnumCountry implements EnumClass<Integer> {
Ethiopia(1),
Tanzania(2),
private Integer id;
EnumCountry(Integer value) {
this.id = value;
}
public Integer getId() {
return id;
}
#Nullable
public static EnumCountry fromId(Integer id) {
for (EnumCountry at : EnumCountry.values()) {
if (at.getId().equals(id)) {
return at;
}
}
return null;
}
}
I have the code like above.
How can I get Enum Id using its Enum Name.

You can simply add a method like below -
public static int getId(String enumCountryName) {
return EnumCountry.valueOf(enumCountryName).getId();
}
So the complete class will be like this -
public enum EnumCountry implements EnumClass<Integer> {
Ethiopia(1),
Tanzania(2);
private Integer id;
EnumCountry(Integer value) {
this.id = value;
}
public Integer getId() {
return id;
}
#Nullable
public static EnumCountry fromId(Integer id) {
for (EnumCountry at : EnumCountry.values()) {
if (at.getId().equals(id)) {
return at;
}
}
return null;
}
public static int getId(String enumCountryName) {
return EnumCountry.valueOf(enumCountryName).getId();
}
}

It is as simple as calling its getId() method:
Ethiopia.getId()
Or:
Tanzania.getId()
Or, assuming you meant you have the string "Ethiopia", then you can also do EnumCountry.valueOf("Ethiopia").getId(). Hope that answers your question!

You can't because their types are incompatible - i.e. String vs Integer. On the other hand, you can add a method that returns a String that combines name and id:
public enum EnumCountry implements EnumClass<Integer> {
Ethiopia(1),
Tanzania(2); // replaced comma with semicolon
private Integer id;
// ...
public String getNameId() {
// returns "Ethiopa 1"
return name() + " " + id;
}
// ...
}

If name is present as String, simply do this,
int getId(String name){
EnumCountry country = EnumCountry.valueOf(name);
return country.getId();
}

Related

Deserializing an object with an array is returning null with GSON, why?

I have this result from server:
{"product_option_values":[{"id":43}, {"id":45}]}
And, I Have these classes to parse the above string for the class below
public class MyClass {
#Key("product_option_values")
private List<ProductOptionValueResult> values;
public List<ProductOptionValueResult> getValues() {
return values;
}
public void setValues(List<ProductOptionValueResult> values) {
this.values = values;
}
}
public class ProductOptionValueResult {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
I'm trying to convert the string above to an instance of MyClass like this:
MyClass myclass = gson.fromJson(stringAbove, MyClass.class);
However I get null in the object's values property, why?
Instead of this annotation:
#Key("product_option_values")
You can use this one:
#SerializedName("product_option_values")
This is from com.google.gson.annotations.SerializedName.

Creating an object and calling it

this is my current code to store rooms(it compiles fine) but in the UML there is a variable called addEquipment and there is also another class called Equipment to be defined. I'm having trouble wrapping my head around what I'm supposed to do with this. Am I supposed to create and call an object called Equipment? what goes in addEquipment?
public class Room {
//begin variable listing
private String name;
private int id;
private int capacity;
private String equipmentList;
//begins get methods for variables
public String getName(){
return name;
}
public int getID(){
return id;
}
public int getCapacity(){
return capacity;
}
public String getEquipmentList(){
return equipmentList;
}
// Set the variables
public void setName(String aName){
name=aName;
}
public void setID(int anID){
id=anID;
}
public void setCapacity(int aCapacity){
capacity=aCapacity;
}
public void setEquipmentList(String anEquipmentList){
equipmentList=anEquipmentList;
}
public String addEquipment(String newEquipment, String currentEquipment){
}
//Create room object
public Room(int capacity, String equipmentList) {
setCapacity(capacity);
setEquipmentList(equipmentList);
}
//Convert variables to string version of room
public String toString(){
return "Room "+name+", capacity: "+capacity+", equipment: "+getEquipmentList();
}
}
You can create a new class Equipment and modify your attribute equipmentList to be a List:
public class Equipment {
private String name;
public Equipment(String name) {
this.name = name;
}
}
public class Room {
//begin variable listing
private String name;
private int id;
private int capacity;
private List<Equipment> equipmentList = new ArrayList<Equipment>();
//begins get methods for variables
public String getName(){
return name;
}
public int getID(){
return id;
}
public int getCapacity(){
return capacity;
}
public List<Equipment> getEquipmentList(){
return equipmentList;
}
// Set the variables
public void setName(String aName){
name=aName;
}
public void setID(int anID){
id=anID;
}
public void setCapacity(int aCapacity){
capacity=aCapacity;
}
public void setEquipmentList(List<Equipment> anEquipmentList){
equipmentList=anEquipmentList;
}
public String addEquipment(String newEquipment, String currentEquipment){
Equipment oneEquipment = new Equipment(newEquipment);
equipmentList.add(oneEquipment);
}
//Create room object
public Room() {
setCapacity(capacity);
setEquipmentList(equipmentList);
}
//Convert variables to string version of room
public String toString(){
String capacity=String.valueOf(getCapacity());
String room = "Room "+name+", capacity: "+capacity+", equipment: "+getEquipmentList();
return room;
}
}
In the method addEquipment, you can create a new Equipment and add it to equipmentList, like code above.
An Equipment class could be anything. Lets assume the "Equipment"-class has a String called "name" as it's attribute
public class Equipment {
String name;
public Equipment( String name) {
this.name = name;
}
public String getName() {
return this.name
}
}
When you extend your Room class by the requested "addEquipment" method, you can do something like this.
public class Room {
... // Your code
private int equipmentIndex = 0;
private Equipment[] equipment = new Equipment[10]; // hold 10 Equipment objects
public void addEquipment( Equipment eq ) {
if ( equipmentIndex < 10 ) {
equipment[ equipmentIndex ] = eq;
equipmentIndex++;
System.out.println("Added new equipment: " + eq.getName());
} else {
System.out.println("The equipment " + eq.getName() + " was not added (array is full)");
}
}
}
Now when you call
room.addEquipment( new Equipment("Chair") );
on your previously initialized object of the Room-class, you will get
"Added new equipment: Chair"
Hope this helps a bit.
PS: The code is untestet (maybe there hides a syntax error somewhere)

Jackson Setting Values During Deserialization

I have a object structure like the following:
public class Product {
int id;
String name;
Size[] sizes;
boolean organic;
}
public class Size {
int id;
String value;
#JsonIgnore String info;
}
While parsing the JSON for the Product class, I want to set the info for each of the sizes to the String "Organic". In the setter for the organic property I check the value and iterate over the sizes, setting the info for each.
#JsonProperty("organic")
public void setOrganic(boolean organic) {
this.organic = organic;
if (organic)
for(Size size : sizes) size.info = "Organic";
}
First, this approach seems to be brittle as it depends on the order of properties in the JSON and secondly, it doesn't always seem to work. For a production environment, where JSON has a lot more properties, I seem to be able to set the properties on the sub-object (Size here) and read and log them during parsing but when I read it from the final deserialized object, those values are always null. Again, this behavior seems to be different for the smaller test cases I set up to test.
Does anyone know of a better way to do this ?
The appropriate place to do this would be outside of these classes and some place where this type of business logic is more appropriate.
You could create a Builder class that allows you to set all of the properties for the resulting object and when the build() method that constructs the final object is called, set any additional values as appropriate. You would apply the Jackson annotations to the Builder class then, and apply any validation to it instead of the class that it creates. This way, you guarantee that any instance of a Product would be complete and valid.
If you take my original suggestion and move the logic into a business layer of your application then you would simply pass the Builders to the appropriate method, check the value of organic on the Product.Builder, and then iterate over the Size.Builder list and change their info values appropriately.
Using the Builders to hold the logic might look something like this (the logic you're looking for is all the way at the bottom):
public class Size {
private final int id;
private final String value;
private final String info;
public Size(int id, String value, String info) {
this.id = id;
this.value = value;
this.info = info;
}
public int getId() {
return id;
}
public String getValue() {
return value;
}
public String getInfo() {
return info;
}
public static class Builder {
private int id;
private String value;
private String info;
public Builder setId(int id) {
this.id = id;
return this;
}
public Builder setValue(String value) {
this.value = value;
return this;
}
#JsonIgnore
public Builder setInfo(String info) {
this.info = info;
return this;
}
public Size build() {
return new Size(id, value, info);
}
}
}
public class Product {
private final int id;
private final String name;
private final Size[] sizes;
private final boolean organic;
public Product(int id, String name, Size[] sizes, boolean organic) {
this.id = id;
this.name = name;
this.sizes = sizes;
this.organic = organic;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public Size[] getSizes() {
return sizes;
}
public boolean isOrganic() {
return organic;
}
public static class Builder {
private int id;
private String name;
private List<Size.Builder> sizeBuilders;
private boolean organic;
public Builder setId(int id) {
this.id = id;
return this;
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setSizeBuilders(List<Size.Builder> sizeBuilders) {
this.sizeBuilders = sizeBuilders;
return this;
}
public Builder setOrganic(boolean organic) {
this.organic = organic;
return this;
}
public Product build() {
if (organic) {
for (Size.Builder sizeBuilder : sizeBuilders) {
sizeBuilder.setInfo("Organic");
}
}
Size[] sizes = new Size[sizeBuilders.size()];
for (int i = 0; i < sizeBuilders.size(); i++) {
sizes[i] = sizeBuilders.get(i).build();
}
return new Product(id, name, sizes, organic);
}
}
}

Refactoring Java class with multiple responsibilities

public class MyObject
{
public static enum Type {A, B, C, D;}
public static final int ID_MAIN = 1;
public static final int ID_MAIN_UK = 2;
public static final int ID_MAIN_US = 3;
public static final int ID_SUB = 4;
// lots more constants here
public static final String DESCRIPTION_1 = "Desc Full Name";
public static final String DESCRIPTION_2 = "Desc2 Full Name";
// lots more constants here
private int id;
public MyObject(final int id)
{
this.id = id;
}
//simple getter
public int getID() { return this.id;}
// real responsibility of the class is in the following two methods
public static String getDescription()
{
switch(id)
{
case MyObject.ID_MAIN:
case MyObject.ID_MAIN_UK:
return MyObject.DESCRIPTION_1;
case MyObject.ID_SUB:
return MyObject_Description_2;
default:
// throw IllegalArgException
}
}
public static Type getType(int id)
{
switch(id)
{
case MyObject.ID_MAIN:
case MyObject.ID_SUB:
return Type.A;
case MyObject.ID_MAIN_UK:
case MyObject.ID_MAIN_US:
return Type.B;
default:
return Type.Undefined;
}
}
}
Basically, there is an ID that maps to both a description and a type. This ID is passed in during construction of the class and it should map to a set of constants already contained in the class. If the id is not part of the list of constants, an error is thrown when trying to get the description that maps to the id and an 'Unknown' type is return if the type is queried. The ID maps a description to a set of constants. The same ID maps to a certain Type (defined as an enum).
This code is pretty ugly because there are tons of constants defined at the top, which makes the switch statements pretty bloated. Is there a simple way to refactor this without changing the public interface? It seems trivially simple, but it seems pretty ugly no matter how you slice it. How can I simplify these mappings to make the code more concise?
I was thinking about representing the mappings in a text file and having a manager class that held simple containers in a hashmap. When the manager class is constructed, it would create the objects by reading the text file and map them to an ID. When the manager is queried with the ID, it would just call the corresponding get method, for instance:
class Manager
{
private HashMap<int, MyObject> objectMap;
public Manager() {} //construct the object map
public String getDescription(int id) { return objectMap.get(id).getDescription();}
public Type getType(int id) { return objectMap.get(id).getType();}
}
class DataContainer
{
private String description;
private Type type;
public DataContainer(String desc, Type type) {//set mem vars}
public String getDescription() //simple getter
public Type getType() //simple getter
}
But this solution seems too complicated. Is there a better solution, preferably one that would keep everything in one class?
You can do something like following. This would be much cleaner and manageable.
public enum Type
{
MAIN(1, "Main Description"),
MAIN_UK(2, "Main UK Description"),
//....
//Define all the types
//....
UNKNOWN(-1, "Unknown Type");
private int id;
private String description;
private Type(int id, String description)
{
this.id = id;
this.description = description;
}
public static Type getById(int id)
{
for (Type type : Type.values())
{
if (id == type.getId())
{
return type;
}
}
return Type.UNKNOWN;
}
public final int getId()
{
return id;
}
public final String getDescription()
{
return description;
}
}
public class MyObject
{
private int id;
private Type type;
public MyObject(int id)
{
this.id = id;
this.type = Type.getById(id);
}
public int getId()
{
return id;
}
public Type getType()
{
return type;
}
public String getDescription()
{
return type.getDescription();
}
}
In Java enums can have methods. For example following one accepts ID and description and provides some accessors.
public enum Type {
MAIN(1, "desc1"),
UK(2, "desc2"),
SUB(4, "desc4");
private int id;
private String desc;
Type(int id, String desc) {
this.id = id;
this.desc = desc;
}
public String getDescription() {
return desc;
}
public int getType() {
//return id;
return 1+2 + 3+ id;
}
}
You could use that to improve design.

How to assign value to this function in java incompatible types

How to assign value to this function in Java incompatible types?
public class CustomerInfo implements Serializable {
private static final long serialVersionUID = 9083257536541L;
protected String id;
protected String searchkey;
protected String taxid;
protected String name;
protected String postal;
/** Creates a new instance of UserInfoBasic */
public CustomerInfo(String id) {
this.id = id;
this.searchkey = null;
this.taxid = null;
this.name = null;
this.postal = null;
}
public String getId() {
return id;
}
public String getTaxid() {
return taxid;
}
public void setTaxid(String taxid) {
this.taxid = taxid;
}
public String getSearchkey() {
return searchkey;
}
public void setSearchkey(String searchkey) {
this.searchkey = searchkey;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPostal() {
return postal;
}
public void setPostal(String postal) {
this.postal = postal;
}
public String printTaxid() {
return StringUtils.encodeXML(taxid);
}
public String printName() {
return StringUtils.encodeXML(name);
}
#Override
public String toString() {
return getName();
}
}
private CustomerInfo selectedCustomer;
public CustomerInfo getSelectedCustomer() {
// construct a CustomerInfo from the data in your String
return selectedCustomer;
}
private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {
selectedCustomer = (CustomerInfo) jListCustomers.getSelectedValue();
//test code
String testing = m_jtxtName.getText();
System.out.println("Now the selectedCustomer is dispayed!");
System.out.println(selectedCustomer);
System.out.println(testing);
//test code
dispose();
}
In the above shown code, I need the string testing value to be assigned to selectedCustomer. How can I assign the value? This is the error I get:
selectedCustomer = m_jtxtName.getText();
incompatible types
required: CustomerInfo
found: String
You can't!!!
selectedCustomer is an object of type CustomerInfo.
m_jtxtName.getText() returns a String
You can't assign a String to a CustomerInfo.
Probably you need to do something like:
int id = 1; //Or whatever new id you have.
String name = m_jtxtName.getText();
selectedCustomer = new CustomerInfo(name); //or whatever id you have.
selectedCustomer.setName(name); //or whatever name you have.
EDIT:
Something is missing from your class. Either it needs setter methods (it has only getters now, so you can't set other properties as name etc) or it needs a constructor with four arguments like:
public CustomerInfo(String id, String searchKey, String taxid, String name, String postal) {
this.id = id;
this.searchKey = searchKey;
// etc
In this case, you might have six jtextfields in your screen, so te user can fill all fields and the create the Customerinfo object by passing all parameters to the constructor.
you cannot do it by simply casting a String to a CustomerInfo object, but you could extend your CustomerInfo but you could try something like this:
public class CustomerInfo {
[...]
public static CustomerInfo createCustomerInfo(String data) {
// construct a CustomerInfo from the data in your String
return createdCustomerInfo;
}
}
I don't know what data you have in that String so i can not give you an advice how to implement this. e.g. If it is the ID you could use this to retrieve the CustomerInfo from database or something like that.

Categories

Resources