I need to let a user of my program name an attribute of annotation, so I created fields in that class which could be managed by a user in main(), these fields should initialize a name attribute in the annotation of a getter, but Intellij IDEA tells that "Attribute value must be constant". Do you have any ideas how to do another way?
There is the code:
public class Model {
private String a;
private String b;
String nameA;
public User(String a) {
this.a = a;
}
public User(String a, String b) {
this.a = a;
this.b = b;
}
#XmlElement(name = nameA)
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
You can only use constant expressions in annotations.
It appears you want to map your property using a dynamic element name. For this change the type of JAXBElement<String> and use the #XmlElementRef annotation instead of #XmlElement. You can then construct your value as:
new JAXBElement(new QName(nameA), String.class, "myValue");
In python we can compare object by attributes by this method:
def __eq__(self, other):
return self.__dict__ == other.__dict__
It allows us to compare objects by their attributes no matter how many attributes they have.
Is something like this possible in Java?
I tried to compare objects in this way, but you have to compare them by every attribute. Is it possible to do it similarly to Python eq method above?
public class MyClass {
public MyClass(attr1, attr2, attr3, attr4) {
this.attr1 = attr1;
this.attr2 = attr2;
this.attr3 = attr3;
this.attr4 = attr4;
}
public boolean equals(Object object2) {
return object2 instanceof MyClass &&
attr1.equals(((MyClass)object2).attr1)&&......;
}
}
If you want to write general method that handles every type, you need to use reflection. If you just want to do this with a type or two, then I suggest you override the equals method for each individual type i.e. hardcoding it.
Here's how you write a generic method that accepts every single type and compares the fields for equality:
private static <T> boolean allFieldsEqual(T a, T b) throws IllegalAccessException {
Class<?> clazz = a.getClass();
Field[] fields = clazz.getFields();
for (Field field : fields) {
if (!field.get(a).equals(field.get(b))) {
return false;
}
}
return true;
}
The logic is pretty self-explanatory. Here is the usage:
Student s1 = new Student("Tom", 1);
Student s2 = new Student("Tom", 1);
try {
System.out.println(allFieldsEqual(s1, s2));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Student is defined as:
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
What is the best way to use the values stored in an Enum as String literals?
For example:
public enum Modes {
some-really-long-string,
mode1,
mode2,
mode3
}
Then later I could use Mode.mode1 to return its string representation as mode1. Without having to keep calling Mode.mode1.toString().
You can't. I think you have FOUR options here. All four offer a solution but with a slightly different approach...
Option One: use the built-in name() on an enum. This is perfectly fine if you don't need any special naming format.
String name = Modes.mode1.name(); // Returns the name of this enum constant, exactly as declared in its enum declaration.
Option Two: add overriding properties to your enums if you want more control
public enum Modes {
mode1 ("Fancy Mode 1"),
mode2 ("Fancy Mode 2"),
mode3 ("Fancy Mode 3");
private final String name;
private Modes(String s) {
name = s;
}
public boolean equalsName(String otherName) {
// (otherName == null) check is not needed because name.equals(null) returns false
return name.equals(otherName);
}
public String toString() {
return this.name;
}
}
Option Three: use static finals instead of enums:
public final class Modes {
public static final String MODE_1 = "Fancy Mode 1";
public static final String MODE_2 = "Fancy Mode 2";
public static final String MODE_3 = "Fancy Mode 3";
private Modes() { }
}
Option Four: interfaces have every field public, static and final:
public interface Modes {
String MODE_1 = "Fancy Mode 1";
String MODE_2 = "Fancy Mode 2";
String MODE_3 = "Fancy Mode 3";
}
Every enum has both a name() and a valueOf(String) method. The former returns the string name of the enum, and the latter gives the enum value whose name is the string. Is this like what you're looking for?
String name = Modes.mode1.name();
Modes mode = Modes.valueOf(name);
There's also a static valueOf(Class, String) on Enum itself, so you could also use:
Modes mode = Enum.valueOf(Modes.class, name);
You could override the toString() method for each enum value.
Example:
public enum Country {
DE {
#Override
public String toString() {
return "Germany";
}
},
IT {
#Override
public String toString() {
return "Italy";
}
},
US {
#Override
public String toString() {
return "United States";
}
}
}
Usage:
public static void main(String[] args) {
System.out.println(Country.DE); // Germany
System.out.println(Country.IT); // Italy
System.out.println(Country.US); // United States
}
As Benny Neugebauer mentions, you could overwrite the toString(). However instead overwriting the toString for each enum field I like more something like this:
public enum Country{
SPAIN("EspaƱa"),
ITALY("Italia"),
PORTUGAL("Portugal");
private String value;
Country(final String value) {
this.value = value;
}
public String getValue() {
return value;
}
#Override
public String toString() {
return this.getValue();
}
}
You could also add a static method to retrieve all the fields, to print them all, etc.
Simply call getValue to obtain the string associated to each Enum item
mode1.name() or String.valueOf(mode1). It doesn't get better than that, I'm afraid
public enum Modes {
MODE1("Mode1"),
MODE2("Mode2"),
MODE3("Mode3");
private String value;
public String getValue() {
return value;
}
private Modes(String value) {
this.value = value;
}
}
you can make a call like below wherever you want to get the value as a string from the enum.
Modes.MODE1.getvalue();
This will return "Mode1" as a String.
For my enums I don't really like to think of them being allocated with 1 String each. This is how I implement a toString() method on enums.
enum Animal
{
DOG, CAT, BIRD;
public String toString(){
switch (this) {
case DOG: return "Dog";
case CAT: return "Cat";
case BIRD: return "Bird";
}
return null;
}
}
You can use Mode.mode1.name() however you often don't need to do this.
Mode mode =
System.out.println("The mode is "+mode);
As far as I know, the only way to get the name would be
Mode.mode1.name();
If you really need it this way, however, you could do:
public enum Modes {
mode1 ("Mode1"),
mode2 ("Mode2"),
mode3 ("Mode3");
private String name;
private Modes(String s) {
name = s;
}
}
my solution for your problem!
import java.util.HashMap;
import java.util.Map;
public enum MapEnumSample {
Mustang("One of the fastest cars in the world!"),
Mercedes("One of the most beautiful cars in the world!"),
Ferrari("Ferrari or Mercedes, which one is the best?");
private final String description;
private static Map<String, String> enumMap;
private MapEnumSample(String description) {
this.description = description;
}
public String getEnumValue() {
return description;
}
public static String getEnumKey(String name) {
if (enumMap == null) {
initializeMap();
}
return enumMap.get(name);
}
private static Map<String, String> initializeMap() {
enumMap = new HashMap<String, String>();
for (MapEnumSample access : MapEnumSample.values()) {
enumMap.put(access.getEnumValue(), access.toString());
}
return enumMap;
}
public static void main(String[] args) {
// getting value from Description
System.out.println(MapEnumSample.getEnumKey("One of the fastest cars in the world!"));
// getting value from Constant
System.out.println(MapEnumSample.Mustang.getEnumValue());
System.out.println(MapEnumSample.getEnumKey("One of the most beautiful cars in the world!"));
System.out.println(MapEnumSample.Mercedes.getEnumValue());
// doesnt exist in Enum
System.out.println("Mustang or Mercedes, which one is the best?");
System.out.println(MapEnumSample.getEnumKey("Mustang or Mercedes, which one is the best?") == null ? "I don't know!" : "I believe that "
+ MapEnumSample.getEnumKey("Ferrari or Mustang, which one is the best?") + " is the best!.");
// exists in Enum
System.out.println("Ferrari or Mercedes, wich one is the best?");
System.out.println(MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") == null ? "I don't know!" : "I believe that "
+ MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") + " is the best!");
}
}
You can simply use:
""+ Modes.mode1
public enum Environment
{
PROD("https://prod.domain.com:1088/"),
SIT("https://sit.domain.com:2019/"),
CIT("https://cit.domain.com:8080/"),
DEV("https://dev.domain.com:21323/");
private String url;
Environment(String envUrl) {
this.url = envUrl;
}
public String getUrl() {
return url;
}
}
String prodUrl = Environment.PROD.getUrl();
It will print:
https://prod.domain.com:1088/
This design for enum string constants works in most of the cases.
Enum is just a little bit special class. Enums can store additional fields, implement methods etc. For example
public enum Modes {
mode1('a'),
mode2('b'),
mode3('c'),
;
char c;
private Modes(char c) {
this.c = c;
}
public char character() {
return c;
}
}
Now you can say:
System.out.println(Modes.mode1.character())
and see output:
a
package com.common.test;
public enum Days {
monday(1,"Monday"),tuesday(2,"Tuesday"),wednesday(3,"Wednesday"),
thrusday(4,"Thrusday"),friday(5,"Friday"),saturday(6,"Saturday"),sunday(7,"Sunday");
private int id;
private String desc;
Days(int id,String desc){
this.id=id;
this.desc=desc;
}
public static String getDay(int id){
for (Days day : Days.values()) {
if (day.getId() == id) {
return day.getDesc();
}
}
return null;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
};
This method should work with any enum:
public enum MyEnum {
VALUE1,
VALUE2,
VALUE3;
public int getValue() {
return this.ordinal();
}
public static DataType forValue(int value) {
return values()[value];
}
public String toString() {
return forValue(getValue()).name();
}
}
i found this one is more easy for preventing type error:
public enum Modes {
some-really-long-string,
mode1,
mode2,
mode3;
String str;
Modes(){
this.str = super.name();
}
#Override
#NonNull
public String toString() {
return str;
}
however - this may work when you need to use a String on a log/println or whenever java compiles the toString() method automatically, but on a code line like this ->
// sample method that require (string,value)
intent.putExtra(Modes.mode1 ,shareElement.getMode()); // java error
// first argument enum does not return value
instead as mentioned above you will still have to extend the enum and use .name() in those cases like this:
intent.putExtra(Modes.mode1.name() ,shareElement.getMode());
after many tries I have come with this solution
public static enum Operation {
Addition, Subtraction, Multiplication, Division,;
public String getUserFriendlyString() {
if (this==Addition) {
return " + ";
} else if (this==Subtraction) {
return " - ";
} else if (this==Multiplication) {
return " * ";
} else if (this==Division) {
return " / ";
}
return "undefined";
}
}
You can try this:
public enum Modes {
some-really-long-string,
mode1,
mode2,
mode3;
public String toString(){
switch(this) {
case some-really-long-string:
return "some-really-long-string";
case mode2:
return "mode2";
default: return "undefined";
}
}
}
use mode1.name() or String.valueOf(Modes.mode1)
Is there any way to set a variable held in an enums parent/superclass from within an enum itself? (The following doesn't compile, but illustrates what I'm attempting to achieve)....
class MyClass{
ObjectType type;
String someValue;
public void setType(ObjectType thisType){
type = thisType;
}
enum ObjectType {
ball{
#Override
public void setValue(){
someValue = "This is a ball"; //Some value isn't accessible from here
}
},
bat{
#Override
public void setValue(){
someValue = "This is a bat"; //Some value isn't accessible from here
}
},
net{
#Override
public void setValue(){
someValue = "This is a net"; //Some value isn't accessible from here
}
};
public abstract void setValue();
}
}
Then, something like so:
MyClass myObject = new MyClass();
myObject.setType(ObjectType.ball);
After doing the above, the 'someValue' string of the myObject should now be set to 'This is a ball'.
Is there any way to do this?
A nested enum type is implicitly static (see Are java enum variables static?). That includes enum types declared as inner classes, so they can't access instance fields of the outer class.
You can't do what you're trying to do with an enum, you'll have to model that as a normal class.
You could do the following, if you want MyClass.someValue to equal the someValue of the enum, but as someValue can be retrieved from the enum I'd not bother having someValue on MyClass at all, and just retrieve it from the enum when required
public class MyClass {
ObjectType type;
String someValue;
public void setType(ObjectType thisType) {
this.type = thisType;
this.someValue = thisType.getSomeValue();
}
enum ObjectType {
ball ("This is a ball"),
bat ("This is a bat"),
net ("This is a net");
private final String someValue;
ObjectType(String someValue) {
this.someValue = someValue;
}
public String getSomeValue() {
return someValue;
}
}
}
here is my problem.
I have a class A that has a string of names and int of numbers which is placed into an ArrayList of another class.
Task:- what i need to do is get the first name from index(0) from the arraylist and return it as a string.
public class A
{
private String name;
private int num;
public A(String aName, int bNum)
{
name = aName;
num = bNum;
public String getName()
{return name; }
public int getNum()
{return num;}
}
}
//class b inserts elements of class a into arraylist
public class b
{
private ArrayList<A> myList;
}
public b()
myList = new ArrayList<A>;
public void addAll(A all)
{ myList.add(all);}
//get method required for issue above.
Check if the the your list has any item present or no. If present, retrieve the first element and get the name for it to return otherwise return null or empty string as desired.
public String getFirstElementName(){
String name = null;//or ""
if(myList.size() >0){
name = myList.get(0).getName);
}
return name;
}
EDIT:
public A getFirstElement(){
A a = null;//or ""
if(myList.size() >0){
a= myList.get(0);
}
return a;
}
Where you are calling this method, you may write as:
A a = getFirstElement();
String name = a.getName();
int number= a.getNum();
Hope this helps.
List.get(int index) returns the element at position index.
May be what you are looking for is
A firstA = myList.get(0);
String name = firstA.getName();
Also, instead of declaring your list as
private ArrayList<A> myList;
you should declare it as
private List<A> myList;
Code against the interface wherever possible.
You need to override equals() and hashcode() in class A based on object equality requirements.
When you want to do lookup create object for A and set values and do lookup with this object.
Example:
A tempObj = new A("name", 5);
In Class B
myList.get(tempObj);