I have a enum with some links. In those links is the same version number (1.1.1), for now as a String, which I would like to replace with constant. How to do this?
I could edit link while returning it (replace some string with my constant), but it does not seems like clean solution. Thank you for any help!
package test.intro;
import test.version;
public enum LinkType
{
LINK1("test/1.1.1/doc/test1.pdf"),
LINK2("test/1.1.1/doc/test2.pdf"),
LINK3("test/1.1.1/doc/test3.pdf");
public final String href;
//my constant I want to use:
private final String versionName = version.getVersionName();
private LinkType(String href)
{
this.href = href;
}
public String getHref()
{
return href;
}
}
You could do something like this:
package test.intro;
import test.version;
public enum LinkType {
LINK1("test/%s/doc/test1.pdf"),
LINK2("test/%s/doc/test2.pdf"),
LINK3("test/%s/doc/test3.pdf");
public final String hrefTemplate;
private LinkType(String hrefTemplate) {
this.hrefTemplate = hrefTemplate;
}
public String getHrefTemplate() {
return this.hrefTemplate;
}
public String getHref() {
return String.format(this.hrefTemplate, version.getVersionName());
// or return this.hrefTemplate.formatted(version.getVersionName()); if you have Java >= 13
}
}
I guess version.getVersionName() is a static method?
Then you could just write LINK1("test/" + version.getVersionName() + "/doc/test1.pdf") etc.
I put my enum into new class and created an attribute. Because my enum is called only in one method, it was easy to change. The solution from #David Mališ might be cleaner.
package test.intro;
import test.version;
public class TestLinks {
private final static String versionName = version.getVersionName();
public enum LinkType {
LINK1("test/"+versionName+"/doc/test1.pdf"),
//another code
}
}
Related
public static class One {
#Override
public String interact(String... values) {
String actualTextOne = "test";
return actualTextOne;
}
}
public static class Two {
#Override
public String interact(String... values) {
String actualTextTwo = "test";
/* Here I need to compare actualTextOne and actualTextTwo, but the problem is that I can't find solluction how to use actualTextOne in Two class*/
return actualTextTwo;
}
}
You cannot do that.
Please check variable scope in java.
https://www.codecademy.com/articles/variable-scope-in-java
A possible solution here is to call the method interact from the class One. Something like this
public static class Two {
#Override
public String interact(String... values) {
String actualTextTwo = "test";
One one = new One();
String actualTextOne = one.interact(values);
// compare values here
return actualTextTwo;
}
}
Why in your classes functions have parameters if you dont use it?
You can mark your class with static only if he is nested, else you need do like this:
class Two {
static public String interact(String... values) {
String actualTextTwo = "test";
return actualTextTwo;
}
}
String textOne = One.interact("");
String textTwo = Two.interact("");
System.out.println(textOne==textTwo);
public class TableContent {
public static String EXCEL_SHEET_NAME = Nit.THEAD.getName();
public static String FILENAME= Nit.FILENAME.getName();
public enum Nit {
FILENAME("Nit-workorder-list"),
THEAD("NIT WORKORDER"),
TENDERSPECNO("TENDER SPECFICATION NO."),
FEE("TENDER FEE"),
SDAMOUNT("SD AMOUNT"),
TYPE("NIT TYPE"),
PRE_BID("PRE BIDDING DATE"),
OPEN_DATE("OPENING DATE"),
STATUS("CONTRACTOR STATUS");
private final String name;
public String getName() {
return name;
}
private Nit(String name) {
this.name = name;
}
public static Nit getNitHeadByName(String name)
{
Nit[] nit=Nit.values();
if(nit==null)
{
return null;
}
for(Nit nitHead:nit)
{
if(nitHead.getName().equals(name))
return nitHead;
}
return null;
}
public enum NitWorkOrder {
}
public enum NitList {
}
My objective is:
I want to export excel sheet from my application, every time I need to hardcode the table headings, which was not good programming practice.
So I use enum to overcome the hardcode problem. Now there are different table heading according to the list, then I enclosed all the required ENUMS in single class.
I used to write getXXXByName() and getXXXByValue() to access the enum, by name or by value.
But he problem is I need to write getXXXByName() and getXXXByValue() everytime inside each enum. I want to write these methods inside the class and outside the enums, and access those methods with the help of class name.
I just want to declare my constants inside enum.
Please kindly suggest me an idea or a way so I can make this method universal which will work for each and every enum. I want to write these methods in such a way so it can be accessed for all enums enclosed in my class. I thought about generics but I have little knowledge.
You can use generics to push functionality up to a parent class by telling the parent class that the type is an enum that implements an interface.
// Use an interface to inform the super class what the enums can do.
public interface Named {
public String getName();
}
// Super class of all Tables.
public static class Table<E extends Enum<E> & Named> {
private final Class<E> itsClass;
private final String sheetName;
private final String fileName;
public Table(Class<E> itsClass) {
this.itsClass = itsClass;
// Walk the enum to get filename and sheet name.
String sheetName = null;
String fileName = null;
for ( E e: itsClass.getEnumConstants() ){
if ( e.name().equals("FILENAME")) {
fileName = e.getName();
}
if ( e.name().equals("THEAD")) {
sheetName = e.getName();
}
}
this.sheetName = sheetName;
this.fileName = fileName;
}
// Use the interface and the enum details to do your stuff.
public E getByName (String name) {
for ( E e: itsClass.getEnumConstants() ){
if ( e.getName().equals(name)) {
return e;
}
}
return null;
}
}
// Extend Table and tell it about your enum using the super constructor.
public static class TableContent extends Table<TableContent.Nit> {
public TableContent() {
super(TableContent.Nit.class);
}
public enum Nit implements Named{
FILENAME("Nit-workorder-list"),
THEAD("NIT WORKORDER"),
TENDERSPECNO("TENDER SPECFICATION NO."),
FEE("TENDER FEE"),
SDAMOUNT("SD AMOUNT"),
TYPE("NIT TYPE"),
PRE_BID("PRE BIDDING DATE"),
OPEN_DATE("OPENING DATE"),
STATUS("CONTRACTOR STATUS");
private final String name;
Nit(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
This is my enmun class
public enum CSSFont {
RezeptName("-fx-font: 22 calibri;"),
RezeptNameClicked("-fx-font: 22 calibri; -fx-underline: true; -fx-text-fill: purple"),
RezeptTab("-fx-font: 15 calibri;");
private String font;
private CSSFont(String s) {
this.font = s;
}
public String getFont() {
return this.font;
}
}
As you can see I created a getFont() function to get the String of each CSSFont object. Is there a way to directly make String objects in an enum class(I need the String for setStyle() methods in JavaFX), so that I don't have to always write CSSFont.object.getFont() but rather CSSFont.object? I tried to let CSSFont extend String, but obviously enums can only implement interfaces. Or is the only solution to create a class with static (final) String attributes?
EDIT: Thanks everybody, it seems I wasn't really sure when to use enums and when not to, since I have only one attribute(String) and I don't even need enumaration or comparison of these enum objects, I will use a class with static final string attributes ;).
You can use something like this:
public enum MyType {
ONE {
public String toString() {
return "this is one";
}
},
TWO {
public String toString() {
return "this is two";
}
}
}
Test it using:
public class EnumTest {
public static void main(String[] args) {
System.out.println(MyType.ONE);
System.out.println(MyType.TWO);
}
}
Originally taken from here
You can override toString method:
public enum CSSFont {
RezeptName("-fx-font: 22 calibri;"),
RezeptNameClicked("-fx-font: 22 calibri; -fx-underline: true; -fx-text-fill: purple"),
RezeptTab("-fx-font: 15 calibri;");
private String font;
private CSSFont(String s) {
this.font = s;
}
public String getFont() {
return this.font;
}
public String toString(){
return this.font;
}
}
Then you can get font as follows:
CSSFont.RezeptName.toString()
I'm writing a library, which has a predefined set of values for an enum.
Let say, my enum looks as below.
public enum EnumClass {
FIRST("first"),
SECOND("second"),
THIRD("third");
private String httpMethodType;
}
Now the client, who is using this library may need to add few more values. Let say, the client needs to add CUSTOM_FIRST and CUSTOM_SECOND. This is not overwriting any existing values, but makes the enum having 5 values.
After this, I should be able to use something like <? extends EnumClass> to have 5 constant possibilities.
What would be the best approach to achieve this?
You cannot have an enum extend another enum, and you cannot "add" values to an existing enum through inheritance.
However, enums can implement interfaces.
What I would do is have the original enum implement a marker interface (i.e. no method declarations), then your client could create their own enum implementing the same interface.
Then your enum values would be referred to by their common interface.
In order to strenghten the requirements, you could have your interface declare relevant methods, e.g. in your case, something in the lines of public String getHTTPMethodType();.
That would force implementing enums to provide an implementation for that method.
This setting coupled with adequate API documentation should help adding functionality in a relatively controlled way.
Self-contained example (don't mind the lazy names here)
package test;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<HTTPMethodConvertible> blah = new ArrayList<>();
blah.add(LibraryEnum.FIRST);
blah.add(ClientEnum.BLABLABLA);
for (HTTPMethodConvertible element: blah) {
System.out.println(element.getHTTPMethodType());
}
}
static interface HTTPMethodConvertible {
public String getHTTPMethodType();
}
static enum LibraryEnum implements HTTPMethodConvertible {
FIRST("first"),
SECOND("second"),
THIRD("third");
String httpMethodType;
LibraryEnum(String s) {
httpMethodType = s;
}
public String getHTTPMethodType() {
return httpMethodType;
}
}
static enum ClientEnum implements HTTPMethodConvertible {
FOO("GET"),BAR("PUT"),BLAH("OPTIONS"),MEH("DELETE"),BLABLABLA("POST");
String httpMethodType;
ClientEnum(String s){
httpMethodType = s;
}
public String getHTTPMethodType() {
return httpMethodType;
}
}
}
Output
first
POST
Enums are not extensible. To solve your problem simply
turn the enum in a class
create constants for the predefined types
if you want a replacement for Enum.valueOf: track all instances of the class in a static map
For example:
public class MyType {
private static final HashMap<String,MyType> map = new HashMap<>();
private String name;
private String httpMethodType;
// replacement for Enum.valueOf
public static MyType valueOf(String name) {
return map.get(name);
}
public MyType(String name, String httpMethodType) {
this.name = name;
this.httpMethodType = httpMethodType;
map.put(name, this);
}
// accessors
public String name() { return name; }
public String httpMethodType() { return httpMethodType; }
// predefined constants
public static final MyType FIRST = new MyType("FIRST", "first");
public static final MyType SECOND = new MyType("SECOND", "second");
...
}
Think about Enum like a final class with static final instances of itself. Of course you cannot extend final class, but you can use non-final class with static final instances in your library. You can see example of this kind of definition in JDK. Class java.util.logging.Level can be extended with class containing additional set of logging levels.
If you accept this way of implementation, your library code example can be like:
public class EnumClass {
public static final EnumClass FIRST = new EnumClass("first");
public static final EnumClass SECOND = new EnumClass("second");
public static final EnumClass THIRD = new EnumClass("third");
private String httpMethodType;
protected EnumClass(String name){
this.httpMethodType = name;
}
}
Client application can extend list of static members with inheritance:
public final class ClientEnum extends EnumClass{
public static final ClientEnum CUSTOM_FIRST = new ClientEnum("custom_first");
public static final ClientEnum CUSTOM_SECOND = new ClientEnum("custom_second");
private ClientEnum(String name){
super(name);
}
}
I think that this solution is close to what you have asked, because all static instances are visible from client class, and all of them will satisfy your generic wildcard.
We Fixed enum inheritance issue this way, hope it helps
Our App has few classes and each has few child views(nested views), in order to be able to navigate between childViews and save the currentChildview we saved them as enum inside each Class.
but we had to copy paste, some common functionality like next, previous and etc inside each enum.
To avoid that we needed a BaseEnum, we used interface as our base enum:
public interface IBaseEnum {
IBaseEnum[] getList();
int getIndex();
class Utils{
public IBaseEnum next(IBaseEnum enumItem, boolean isCycling){
int index = enumItem.getIndex();
IBaseEnum[] list = enumItem.getList();
if (index + 1 < list.length) {
return list[index + 1];
} else if(isCycling)
return list[0];
else
return null;
}
public IBaseEnum previous(IBaseEnum enumItem, boolean isCycling) {
int index = enumItem.getIndex();
IBaseEnum[] list = enumItem.getList();
IBaseEnum previous;
if (index - 1 >= 0) {
previous = list[index - 1];
}
else {
if (isCycling)
previous = list[list.length - 1];
else
previous = null;
}
return previous;
}
}
}
and this is how we used it
enum ColorEnum implements IBaseEnum {
RED,
YELLOW,
BLUE;
#Override
public IBaseEnum[] getList() {
return values();
}
#Override
public int getIndex() {
return ordinal();
}
public ColorEnum getNext(){
return (ColorEnum) new Utils().next(this,false);
}
public ColorEnum getPrevious(){
return (ColorEnum) new Utils().previous(this,false);
}
}
you could add getNext /getPrevious to the interface too
#wero's answer is very good but has some problems:
the new MyType("FIRST", "first"); will be called before map = new HashMap<>();. in other words, the map will be null when map.add() is called. unfortunately, the occurring error will be NoClassDefFound and it doesn't help to find the problem. check this:
public class Subject {
// predefined constants
public static final Subject FIRST;
public static final Subject SECOND;
private static final HashMap<String, Subject> map;
static {
map = new HashMap<>();
FIRST = new Subject("FIRST");
SECOND = new Subject("SECOND");
}
private final String name;
public Subject(String name) {
this.name = name;
map.put(name, this);
}
// replacement for Enum.valueOf
public static Subject valueOf(String name) {
return map.get(name);
}
// accessors
public String name() {
return name;
}
I have a couple of objects from which selected members should be combined to create an output object. All these are POJOs. I am seeing that all object mappers work on a single POJO to another POJO level. Is there any mapper that supports what I am looking for? Of course, I understand that there is some mapping stuff that I need to specify.
Edit:
I know how to get this done by writings own Java class. I am just looking for a way to do it with one of the mapping libraries.
You aren't limited in what you require to be passed to your mapper. You can define it to accept several items and build the object based on the multiple inputs. Here is an example:
public class ClassOne {
private final String someProperty;
public ClassOne(String someProperty) {
this.someProperty = someProperty;
}
public String getSomeProperty() {
return someProperty;
}
}
public class ClassTwo {
private final String someOtherProperty;
public ClassTwo(String someOtherProperty) {
this.someOtherProperty = someOtherProperty;
}
public String getSomeOtherProperty() {
return someOtherProperty;
}
}
public class CombinedClass {
public static CombinedClass mapper(ClassOne one, ClassTwo two){
return new CombinedClass(one.getSomeProperty(), two.getSomeOtherProperty());
}
private final String someProperty;
private final String someOtherProperty;
private CombinedClass(String someProperty, String someOtherProperty) {
this.someProperty = someProperty;
this.someOtherProperty = someOtherProperty;
}
public String getSomeProperty() {
return someProperty;
}
public String getSomeOtherProperty() {
return someOtherProperty;
}
}