This could sound strange but actually is quite simple.
Short description: I have a class variable called
public static final String ACCELEROMETER_X = "AccX";
In one function I do this, which get me "ACCELEROMETER_X" from a enum (sensors is an arrayList of my enum).
for i...
columns = columns + sensors.get(i).name()
The point is I want to introduce in columns not "ACCELEROMETER_X", but "AccX". Any idea? I know I could do it using switch and cases but my enum has more than 30 values so Id rather prefer other "cleaner" way to do it.
If you want your enum constant to be replaced with that string value, a better way would be keep that string as a field in the enum itself:
enum Sensor {
ACCELEROMETER_X("AccX"),
// Other constants
;
private final String abbreviation;
private Sensor(final String abbreviation) {
this.abbreviation = abbreviation;
}
#Override
public String toString() {
return abbreviation;
}
}
And instead of:
sensors.get(i).name()
use this:
sensors.get(i).toString()
Solution 1 : If you keep the value in class
Create a Map with key as the id (ACCELEROMETER_X) and value as "AccX" and when you get the value from the Enum use that to find the value from the map using name() as the key.
Map<String, String> map = new HashMap<String,String>();
map.put("ACCELEROMETER_X","AccX");
//some place where you want value from name
map.get(enumInstance.name());
Solution 2: Change the enum (more preferable)
enum Some{
ACCELEROMETER_X("AccX");
}
In your enum add this
public String getAccelerometerX (){
return ACCELEROMETER_X ;
}
and then:
for i... columns = columns + sensors.get(i).getAccelerometerX ()
I think what you're trying to do is to get the value of a field from its name which you have in a String, if that's the case, you could do something like this:
public static final String ACCELEROMETER_X = "AccX";
// ...
Field field = MyClassName.class.getField("ACCELEROMETER_X");
String value = (String)field.get(new MyClassName());
System.out.println(value); // prints "AccX"
Of course you'll have to catch some Exceptions.
Related
I'm having a following problem: I have to sort entities by enum parameter. The thing is, that enum name is not equivalent to its translated name, for example, the enum values can be:
enum Sample {
Bus, Car, Train
}
However, let's say in my language, Bus corresponds to pks, Car to auto, and Train to ciuchcia, co their order should be:
Car, Train, Bus and not Bus, Car, Train. It's just an example, my problem involves something like 10 different values.
The problem is, I can't get all the data, then perform a sort in Java, because the data is paginated. I tried to solve this problem by doing this in SQL (the data is from database view):
(CASE sample WHEN 'Car' THEN 1 WHEN 'Train' THEN 2 WHEN 'Bus' THEN 3 ELSE 0 END)
I'm sorting by number, and this solution works. However, I feel like this can be done better, and doesn't need to be modified each time I want to add something. Any help would be very appreciated.
If you can hard-code or populate the translation in the enum you can make the enum generate the query.
enum Sample {
Bus("pks"), Car("auto"), Train("ciuchcia");
private final String localName;
Sample(String localName) {
this.localName = localName;
}
private static final List<Sample> inLocalOrder = Arrays.stream(values())
.sorted((a,b) -> a.localName.compareTo(b.localName))
.collect(Collectors.toList());
public static CharSequence inLocalOrder() {
StringBuilder sb = new StringBuilder("(CASE");
int i = 1;
inLocalOrder.stream().forEach(a -> sb.append(" WHEN '"+a.name()+"' THEN "+i));
sb.append(" ELSE 0 END)");
return sb;
}
}
public void test(String[] args) {
System.out.println(Sample.inLocalOrder());
}
prints:
(CASE WHEN 'Car' THEN 1 WHEN 'Train' THEN 2 WHEN 'Bus' THEN 3 ELSE 0 END)
If the translations happen later then a minor adjustment should suffice.
First things first. Why you're using an Enum to sort stuff? I can't agree with this feature, but it's ok if you really need it.
I really appreciate #OldCurmudgeon's answer, but I would have done something different.
Instead of using the property value as the column name, I would use a method to request the correct column name (obviously I'm supposing that you don't have the entities mapped inside your code, so you're using an Enum to sort them). This way:
enum Sample {
Bus, Car, Train;
public String getColumnName() {
// GET IT FROM SOME RESOURCE OR REQUEST IT FROM ANOTHER CONTEXT OR JUST RETURN IT THE WAY IT IS
// YOU CAN USE A RESOURCE FILE TO MAP YOUR COLUMN NAME, SO IF THE ENTITY CHANGES, YOU DON'T NEED
// TO UPDATE YOUR CODE...
return "";
}
public static String getSortSQL(Map<Sample, Integer> samples) {
StringBuilder sb = new StringBuilder("(CASE");
samples.forEach((sample, number) -> addSampleNumberSQL(sb, sample, number));
return sb.append(" ELSE 0 END)").toString();
}
private static StringBuilder addSampleNumberSQL(StringBuilder sb, Sample sample, Integer number) {
return sb.append(" WHEN '").append(sample.getColumnName()).append("' THEN ").append(number);
}
}
As you can see, you can request your column name from any resource you want. But this implementation still weak because if you need to sort by any new column, you will need to add another Enum value. So I would implement something more powerfull, like a properties reader that read each property from the resource and a method that receive an String (mean the property itself) and a number (to sort by the number) so I would do something like this:
public static String getSortSQL(Map<String, Integer> properties) {
StringBuilder sb = new StringBuilder("(CASE");
properties.forEach((prop, number) -> addSampleNumberSQL(sb, prop, number));
return sb.append(" ELSE 0 END)").toString();
}
private static StringBuilder addSampleNumberSQL(StringBuilder sb, String property, Integer number) {
return sb.append(" WHEN '").append(property).append("' THEN ").append(number);
}
Hope it helps you...
I have a enum class like this -
public enum FeedbackStatus {
#JsonProperty("unprocessed")
UNPROCESSED("unprocessed"),
#JsonProperty("arrived")
ARRIVED("arrived"),
#JsonProperty("performed")
PERFORMED("performed"),
#JsonProperty("cancelled")
CANCELLED("cancelled"),
#JsonProperty("removed")
REMOVED("removed"),
#JsonProperty("no-show")
NO_SHOW("no-show"),
#JsonProperty("cancel-at-door")
CANCEL_AT_DOOR("cancel-at-door");
private static final FeedbackStatus[] myEnumValues = FeedbackStatus.values();
private final String fieldDescription;
private FeedbackStatus(String value) {
this.fieldDescription = value;
}
public static FeedbackStatus fromString(String string) {
if (!TextUtils.isEmpty(string)) {
for (FeedbackStatus feedbackStatus : myEnumValues) {
if (feedbackStatus.getString().equalsIgnoreCase(string)) {
return feedbackStatus;
}
}
}
throw new IllegalArgumentException("No constant with text " + string + " found");
}
public String getString() {
return this.fieldDescription;
}
}
I need to store an object feedback in SQLITE database using GreneDAO but the object is a enum and hence I am unable to store it . The object is like -
private FeedbackStatus feedback;
How can I store it as String?
Use for ex. CANCELLED.value? When storing the data? There is also ENUM.toString(). You can store it as String and then wrap recovering data with String to Enum method.
You can not store enums in database as enumns are Java entity, so for enums you need to store their equivalent values either String or int etc.
You can get value of enum as below and than store it in database as Strings:
String PERFORMED = PERFORMED.value;
String CANCELLED= CANCELLED.value;
String REMOVED= REMOVED.value;
String NO_SHOW= NO_SHOW.value;
String CANCEL_AT_DOOR= CANCEL_AT_DOOR.value;
For more details of Enums see Java Docs here
So here actually your data model is ok but while saving enum in the database you just need one column with enum value, and while inserting you need to convert from enum to its string value and while reading from db, you need to build enum from that string.
Hope it helps!!
You can just serialize/deserialize it. Enums are serializable by default.
Our team have a shared Java class only for Constant values
When any developer need to add a constant
He will add a record in this class
public class Constants_Class {
public static final String Constant1 = "value1";
public static final String Constant2 = "value2";
public static final String Constant3 = "value3";
// Need to prevent that in Development time - NOT Run time
public static final String Constant4 = "value1"; // value inserted before
}
The problem is that
We need in Development time prevent any developer
To add a new constant its value inserted before
// Need Unique Constants Value(s)
Any suggestions ??
You really should be using enums. This will solve the problem you're seeing.
You can also associate String values with enums:
public enum MyEnums {
Constant1("value1"),
Constant2("value2"),
Constant3("value3");
private String value;
MyEnum(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
Then you can do MyEnum.Constant1.getValue().
To do what you're asking at development time would require parsing the code, essentially duplicating compilation. So it makes sense to let it be compiled and create a unit test to perform your check, then set up the project so that unit test is run each time the code base is compiled. I'm pretty sure the most common unit test library in use is JUnit.
To easily check uniqueness of values, you can use the Set.add method, which returns false if the item being added already exists in the set:
#Test
public class TestConstantUniqueness() {
Set<String> stringValues = new HashSet<String>();
for (MyConstantEnum value : MyConstantEnum.values()) {
String s = value.stringValue();
Assert.assertTrue(
"More than one constant in " + MyConstantEnum.class
+ " has the string value \"" + s + "\"",
stringValues.add(s));
}
}
I have an array of type Records[], which contains fields such as name, age, and score.
I have a method which will be will need to access one of these fields, but I won't know which.
I want to, for example, do the following:
String fieldToUse = "name";
System.out.println(myRecords[0].fieldToUse);
In this case I could switch fieldToUse to whichever field I wanted to find. This doesn't work, however - how do I do this?
Thanks in advance.
Edit: myRecords is of type Records.
This could be done using refection:
Field field = Record.class.getField(fieldToUse);
Object fieldValue = field.get(record);
Full exeample:
static class Record {
public String name;
public int age;
public Record(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) throws Exception {
Record[] records = new Record[2];
records[0] = new Record("David", 29);
records[1] = new Record("Andreas", 28);
System.out.println("Davids name: " + getField("name", records[0]));
System.out.println("Andreas age: " + getField("age", records[1]));
}
private static Object getField(String field, Record record) throws Exception {
return record.getClass().getField(field).get(record);
}
prints:
Davids name: David
Andreas age: 28
I think that what you need to do is impossible with Java.
With your structure, you should iterate over your Records[] and select the right one.
You may try using a HashMap<String, Record> where the String is fieldToUse.
This way you can just use something like hashmap.get(fieldToUse) to get the right Record
A possibility would be to change the interface of Records to have a getProperty() style method:
System.out.println(Records[0].getProperty(fieldToUse));
Internally, Records could use a Map implementation to store the values. Assuming name is a String, and age and score are Integers the Map would be Map<String, String>, keyed by the attribute name. Additionally, Records could provide methods for each attribute for use elsewhere that returned the appropriate type.
You can make a Map representation of type Record. With each field name as key.
Record
name: "YXZ"
age: 12
score: 657
Now store this in an array.
You can now access
Records[0].get("name");
This is the best I can think of in terms of Java.
Can Any help me and Check my answer
(a) Declare a private instance variable (Attribute) called HouseMap which should hold an unsorted map with integer keys and string values.
Private Map< Integer, String> HouseMap = new HashMap<Integer, String>();
(b) Write a zero-argument constructor of HouseCatalogue that initializes HouseMap to an empty map.
houseMap = new HashMap<Integer, String>();
(c) Write an instance method called addHouse() for the HouseCatalogue class that takes no arguments, and returns no value. This method should simply enter the four entries shown above into the HouseMap.
Public void addHouse()
{
HouseMap.put(101," adison Sas") ;
HouseMap.put(103," FourSeasons") ;
HouseMap.put(105," Hayat Regency ");
HouseMap.put(107," Concord al-Salam ") ;
}
(d) Write an instance method called printHouse() for the HouseCatalogue class that takes an integer argument, and return a string value. This method should print the value (House name) of the area code that is equal to integer argument and return it. Otherwise it will return null.
Public string printHouse( int area)
{
for(Integer eachcode : HouseMap.keySet())
{
if ( HouseMap.keySet()== area)
{
System.out.println("House name is"+ HouseMap.get(eachcode));
}
}
}
or
public static void printHouse( int area)
{
for(Map.Entry<Integer,String> entry : houseMap.entrySet())
{
if (entry.getKey().equals(area))
{
System.out.println("House name is"+ entry.getValue());
//return entry.getValue(); // return it
}
}
}
(a) Lower case letter for private and no new HashMap() needed when declaring. Normally when useing java convensions you use camelcase when declaring your variasbles (houseMap) but it's fine.
private Map<Integer, String> HouseMap;
(b) You have declared your variable with HouseMap not houseMap (see (a) camelcase) so initializing it needs the same variable:
HouseMap = new HashMap<Integer, String>();
(c) Seems fine
(d) Hum, don't see the point in the method, it should both print the value and return it.. well.. first off public lower case letters again, String with a big letter (name of the class` and then the implementation:
public String printHouse(int area) {
if (HouseMap.containsKey(area)) {
String name = HouseMap.get(area);
System.out.println("The house with the area code " + area +
" is " + name));
return name;
}
return null;
}
a) only declare the variable - do not initialize it
b) ok
c) ok
d) in a map you have random access. look at Map#get(Integer) API. you don't need to iterate over the entry set
Since the key of a map is unique, you can simplify the last method as follows:
public static void printHouse( int area)
{
String name = houseMap.get(area); // May return null
System.out.println("House name is " + name);
return name;
}
public and private must be written with a lowercase p everywhere.
You should show the entire constructor, not just the code that goes in it.
Fix your indentation. Use the same amount of indentation for every level, and make sure that everything lines up neatly.
When you use a foreach loop like for (Integer eachcode: HouseMap.keySet()), the iteration variable is eachcode. This is the value that you should compare to area, because that's what the integer is. You don't want to compare the supplied to all of the area codes taken as a single unit (those aren't the same kind of thing); you want to compare it to each area code in turn.
But you don't want to write that loop at all. The point of a HashMap is to let you look up the value, given the key. That is what .get() does. You have the key: it is area. So all you need to do is look it up: System.out.println("House name is " + HouseMap.get(area)).
You also need to return the name that you looked up, not just print it, and you need to check that the name is there (use .contains()) before printing.
It looks like somebody else commented your code to say "you also forgot to return it". Did you try talking to this person, or reading the comments?
Just a hint for the last one:
(d) Write an instance method called
An instance method is not a static method, you have to remove the static keyword in your second (d) method...
Thanks alot for every body
public static String printHouse(int
code) {
if (houseMap.containsKey(code))
{
String name = houseMap.get(coe);
System.out.println(code+ " : " + name);
return name;
} else{
System.out.println("null");
return null; }