Java, generate selected list of enum values - java

I have a project where I use enum class with 128 values in it and I want to allow end user to select only few of values for his usage (say 20 out of 128) For that I created javafx tableview with checkbotablecell which works nicely but then I would need to make boolean field in enum to define visibility of each value but all enum fields are final and I will not be able to change it dynamically. So, the question is how to dynamically define visibility of each enum value?

You can create a Map of Enum to Boolean inside Enum class.
Eg : static final EnumMap<EnumType , Boolean> visibilityMap.
And add getter and setter methods to access visibility.

You want an EnumSet to be stored.
The enum class of yours defines 128 singleton objects, one cannot have several objects "being" the same enum object. The solution would be to have a class containing the enum object. Or having an EnumSet of several enum constants.
EnumSet is a Set implementation havily optimized for enums, and providing building methods.
In the constructor on passes the actual enum class itself so with type erasure the class can still function.
EnumSet<Weekday> weekend = EnumSet.of(Weekday.SATURDAY, Weekday.SUNDAY);

Related

Way to save type of each item

I am reading records from Excel to a POJO
I have created an enum to hold the order of each column
My question is Is it possible to save the column type as well?
so later I will pass this enum to some method it will know how to process the value based on its type...
for example:
public enum StudentInfo{
name(0,String),
age(1,Integer),
height(2,Float),
eyeColor(5,Color);
You can save the class of the expected type as a field in the enum instances. You would construct them similarly to what you have now but like:
name(0, String.class),
Then you can have a
private Class<?> columnType;
as a field and use that.
As an aside, by convention (see here and here), enum values are usually named in all upper case.

How to use different Enum types to an object for building GUI scrollist with unique values

Looked at a lot of postings associated with passing different Enum types to a method but do not believe my specific situation/issue was resolved.
Following is my established Enum Type class (modified to hide classified information):
public class ProjectA_Enums{
private ProjectA_Enums(){
}
public enum TableA_Filter_Sort_Options{
TIMESTAMP ("TIMESTAMP", "tbla_timestamp"),
USER ("USER", "tbla_user"),
SHARE ("SHARE", "tbla_share"),
CONDITION ("CONDITION", "tbla_condition",
TERMINAL ("TERMINAL", "tbla_terminal");
private final String filter_name;
private final String database_column_name;
private TableA_Filter_Sort_Options(String filter_name,
String database_column_name){
this.filter_name = filter_name;
this.database_column_name = database_column_name;
}
public String getFilter_name(){
return filter_name;
}
public String getDatabase_column_name(){
return database_column_name;
}
}
public enum TableB_Filter_Sort_Options{
TIMESTAMP ("TIMESTAMP", "tblb_timestamp"),
ERROR_CODE ("ERROR CODE", "tblb_errcode"),
ERROR_MESSAGE ("ERROR MESSAGE", "tblb_errmsg");
private final String filter_name;
private final String database_column_name;
private TableA_Filter_Sort_Options(String filter_name,
String database_column_name){
this.filter_name = filter_name;
this.database_column_name = database_column_name;
}
public String getFilter_name(){
return filter_name;
}
public String getDatabase_column_name(){
return database_column_name;
}
}
}
Now here is the situation :
I want to call the class FilterSortDialogDisplay and pass either Enum type TableA_Filter_Sort_Options or TableB_Filter_Sort_Options to build and display a dialog GUI showing the applicable filters in a scroll pane.
This class would allow the user to select the applicable filters to perform a database query on and the desired sort order.
For Enum type TableA_Filter_Sort_Options the displayed filters would be TIMESTAMP, USER, SHARE, CONDITION, TERMINAL and for TableB_Filter_Sort_Options the displayed filters would be TIMESTAMP, ERROR CODE, ERROR MESSAGE.
The second attribute associated with each Enum type value is associated database table column to use in the resulting database query SQL. I saw in another post that one must define the input parameter of the receiving method as Class. Due to a lack of Java knowledge I am not sure how to write the code to use the passed in Enum type.
Since I have set up both Enum types with the same exact attributes and methods, I was hoping to be able to cast an attribute in the FilterSortDialogDisplay class to the appropriate Enum type and just call these methods.
Hopefully Enum types are the correct construct to be used to perform the defined functionality, because there will be additional Enum types with different number and filter values for which the Filter Sort Dialog needs to be generated and displayed without the need for redundant code based on the Enum type.
Thanks ahead of time for any assistance you can provide.
I would recommend you not use enums for this. From your description it sounds as though you want to pass an object that contains enough information for the dialog to display filter information and generate the query. I would suggest you define an interface and then create implementations for your various tables.
A solution might look something like:
public interface FilterSortOption {
Stream<Criteria> getFilterCriteria();
String generateQuery(Map<Criteria, Value> values);
}
void showDialogAndRunQuery(FilterSortOption option) {
....
}
Then you can define several implementations of this. If they share code (as they are likely to) then that code could go into a separate class that each of the implementation delegate to. It's possible that that delegate class might use an enum to contain column and criteria information. I can provide pointers on how to do that if you need it.
Your problem is not articulated very concisely. I admit that after all that, I'm not certain what help it is that you need. I would say that if your filter options are a fixed set of constants that are known at compile time, then using enums is a good practice.
Since I have set up both Enum types with the same exact attributes and
methods, I was hoping to be able to cast an attribute in the
FilterSortDialogDisplay class to the appropriate Enum type and just
call these methods.
I am going to assume that what you want to do is call a method that takes, as an argument, a parameter that can be the member of a family of enum types. Is this accurate?
There is a pattern that can be used to address this situation, the extensible enum pattern. In this pattern, each enum class in your family of enums implements a common interface. For example:
public enum TableA_FilterSortOptions implements FilterOptions {
:
:
}
public enum TableB_FilterSortOptions implements FilterOptions {
:
:
}
public interface FilterOptions { ... }
Here, all of the enum classes in your family share a common type, FilterOptions. If you define your filtering methods to accept a parameter of type FilterOptions, you can pass any constant from any of your implementing enum classes to those methods.
The restriction here is that the interface must describe all the functionality of your enum classes and each enum class must implement that functionality. When you pass an enum constant using its interface type, inside the method to which the constant was passed, the constant will "lose" its status as an enum constant, so only the interface methods will be available.
So what can you do if you need your enum constants to function as enums within the method bodies to which they are passed using the FilterOptions type (for example, you wanted to be able to add the constants to an EnumSet in your filtering method)? There is a solution. You can define generic methods that employ an intersection type. For example:
public static <E extends Enum<E> & FilterOptions> void applyFilter(E option) {
:
:
}
This method is defined to accept a single argument that must be an enum constant and which must come from an enum class that implements the FilterOptions type. Inside the body of this method, the E type can be added to an instance of EnumSet<E> and all the methods of FilterOptions will also be available.

When to use static fields and when to use enumerations? [duplicate]

I am very familiar with C# but starting to work more in Java. I expected to learn that enums in Java were basically equivalent to those in C# but apparently this is not the case. Initially I was excited to learn that Java enums could contain multiple pieces of data which seems very advantageous (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html). However, since then I have found a lot of features missing that are trivial in C#, such as the ability to easily assign an enum element a certain value, and consequently the ability to convert an integer to an enum without a decent amount of effort (i.e. Convert integer value to matching Java Enum).
So my question is this: is there any benefit to Java enums over a class with a bunch of public static final fields? Or does it just provide more compact syntax?
EDIT: Let me be more clear. What is the benefit of Java enums over a class with a bunch of public static final fields of the same type? For example, in the planets example at the first link, what is the advantage of an enum over a class with these public constants:
public static final Planet MERCURY = new Planet(3.303e+23, 2.4397e6);
public static final Planet VENUS = new Planet(4.869e+24, 6.0518e6);
public static final Planet EARTH = new Planet(5.976e+24, 6.37814e6);
public static final Planet MARS = new Planet(6.421e+23, 3.3972e6);
public static final Planet JUPITER = new Planet(1.9e+27, 7.1492e7);
public static final Planet SATURN = new Planet(5.688e+26, 6.0268e7);
public static final Planet URANUS = new Planet(8.686e+25, 2.5559e7);
public static final Planet NEPTUNE = new Planet(1.024e+26, 2.4746e7);
As far as I can tell, casablanca's answer is the only one that satisfies this.
Type safety and value safety.
Guaranteed singleton.
Ability to define and override methods.
Ability to use values in switch statement case statements without qualification.
Built-in sequentialization of values via ordinal().
Serialization by name not by value, which offers a degree of future-proofing.
EnumSet and EnumMap classes.
Technically one could indeed view enums as a class with a bunch of typed constants, and this is in fact how enum constants are implemented internally. Using an enum however gives you useful methods (Enum javadoc) that you would otherwise have to implement yourself, such as Enum.valueOf.
Nobody mentioned the ability to use them in switch statements; I'll throw that in as well.
This allows arbitrarily complex enums to be used in a clean way without using instanceof, potentially confusing if sequences, or non-string/int switching values. The canonical example is a state machine.
The primary advantage is type safety. With a set of constants, any value of the same intrinsic type could be used, introducing errors. With an enum only the applicable values can be used.
For example
public static final int SIZE_SMALL = 1;
public static final int SIZE_MEDIUM = 2;
public static final int SIZE_LARGE = 3;
public void setSize(int newSize) { ... }
obj.setSize(15); // Compiles but likely to fail later
vs
public enum Size { SMALL, MEDIUM, LARGE };
public void setSize(Size s) { ... }
obj.setSize( ? ); // Can't even express the above example with an enum
There is less confusion. Take Font for instance. It has a constructor that takes the name of the Font you want, its size and its style (new Font(String, int, int)). To this day I cannot remember if style or size goes first. If Font had used an enum for all of its different styles (PLAIN, BOLD, ITALIC, BOLD_ITALIC), its constructor would look like Font(String, Style, int), preventing any confusion. Unfortunately, enums weren't around when the Font class was created, and since Java has to maintain reverse compatibility, we will always be plagued by this ambiguity.
Of course, this is just an argument for using an enum instead of public static final constants. Enums are also perfect for singletons and implementing default behavior while allowing for later customization (I.E. the strategy pattern). An example of the latter is java.nio.file's OpenOption and StandardOpenOption: if a developer wanted to create his own non-standard OpenOption, he could.
There are many good answers here, but none mentiones that there are highly optimized implementations of the Collection API classes/interfaces specifically for enums:
EnumSet
EnumMap
These enum specific classes only accept Enum instances (the EnumMap only accept Enums only as keys), and whenever possible, they revert to compact representation and bit manipulation in their implementation.
What does this mean?
If our Enum type has no more that 64 elements (most of real-life Enum examples will qualify for this), the implementations store the elements in a single long value, each Enum instance in question will be associated with a bit of this 64-bit long long. Adding an element to an EnumSet is simply just setting the proper bit to 1, removing it is just setting that bit to 0. Testing if an element is in the Set is just one bitmask test! Now you gotta love Enums for this!
example:
public class CurrencyDenom {
public static final int PENNY = 1;
public static final int NICKLE = 5;
public static final int DIME = 10;
public static final int QUARTER = 25;}
Limitation of java Constants
1) No Type-Safety: First of all it’s not type-safe; you can assign any valid int value to int e.g. 99 though there is no coin to represent that value.
2) No Meaningful Printing: printing value of any of these constant will print its numeric value instead of meaningful name of coin e.g. when you print NICKLE it will print "5" instead of "NICKLE"
3) No namespace: to access the currencyDenom constant we need to prefix class name e.g. CurrencyDenom.PENNY instead of just using PENNY though this can also be achieved by using static import in JDK 1.5
Advantage of enum
1) Enums in Java are type-safe and has there own name-space. It means your enum will have a type for example "Currency" in below example and you can not assign any value other than specified in Enum Constants.
public enum Currency {PENNY, NICKLE, DIME, QUARTER};
Currency coin = Currency.PENNY;
coin = 1; //compilation error
2) Enum in Java are reference type like class or interface and you can define constructor, methods and variables inside java Enum which makes it more powerful than Enum in C and C++ as shown in next example of Java Enum type.
3) You can specify values of enum constants at the creation time as shown in below example:
public enum Currency {PENNY(1), NICKLE(5), DIME(10), QUARTER(25)};
But for this to work you need to define a member variable and a constructor because PENNY (1) is actually calling a constructor which accepts int value , see below example.
public enum Currency {
PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
private int value;
private Currency(int value) {
this.value = value;
}
};
Reference: https://javarevisited.blogspot.com/2011/08/enum-in-java-example-tutorial.html
The first benefit of enums, as you have already noticed, is syntax simplicity. But the main point of enums is to provide a well-known set of constants which, by default, form a range and help to perform more comprehensive code analysis through type & value safety checks.
Those attributes of enums help both a programmer and a compiler. For example, let's say you see a function that accepts an integer. What that integer could mean? What kind of values can you pass in? You don't really know right away. But if you see a function that accepts enum, you know very well all possible values you can pass in.
For the compiler, enums help to determine a range of values and unless you assign special values to enum members, they are well ranges from 0 and up. This helps to automatically track down errors in the code through type safety checks and more. For example, compiler may warn you that you don't handle all possible enum values in your switch statement (i.e. when you don't have default case and handle only one out of N enum values). It also warns you when you convert an arbitrary integer into enum because enum's range of values is less than integer's and that in turn may trigger errors in the function that doesn't really accept an integer. Also, generating a jump table for the switch becomes easier when values are from 0 and up.
This is not only true for Java, but for other languages with a strict type-checking as well. C, C++, D, C# are good examples.
An enum is implictly final, with a private constructors, all its values are of the same type or a sub-type, you can obtain all its values using values(), gets its name() or ordinal() value or you can look up an enum by number or name.
You can also define subclasses (even though notionally final, something you can't do any other way)
enum Runner implements Runnable {
HI {
public void run() {
System.out.println("Hello");
}
}, BYE {
public void run() {
System.out.println("Sayonara");
}
public String toString() {
return "good-bye";
}
}
}
class MYRunner extends Runner // won't compile.
enum Benefits:
Enums are type-safe, static fields are not
There is a finite number of values (it is not possible to pass non-existing enum value. If you have static class fields, you can make that mistake)
Each enum can have multiple properties (fields/getters) assigned - encapsulation. Also some simple methods: YEAR.toSeconds() or similar. Compare: Colors.RED.getHex() with Colors.toHex(Colors.RED)
"such as the ability to easily assign an enum element a certain value"
enum EnumX{
VAL_1(1),
VAL_200(200);
public final int certainValue;
private X(int certainValue){this.certainValue = certainValue;}
}
"and consequently the ability to convert an integer to an enum without a decent amount of effort"
Add a method converting int to enum which does that. Just add static HashMap<Integer, EnumX> containing the mapping.
If you really want to convert ord=VAL_200.ordinal() back to val_200 just use: EnumX.values()[ord]
You get compile time checking of valid values when you use an enum. Look at this question.
The biggest advantage is enum Singletons are easy to write and thread-safe :
public enum EasySingleton{
INSTANCE;
}
and
/**
* Singleton pattern example with Double checked Locking
*/
public class DoubleCheckedLockingSingleton{
private volatile DoubleCheckedLockingSingleton INSTANCE;
private DoubleCheckedLockingSingleton(){}
public DoubleCheckedLockingSingleton getInstance(){
if(INSTANCE == null){
synchronized(DoubleCheckedLockingSingleton.class){
//double checking Singleton instance
if(INSTANCE == null){
INSTANCE = new DoubleCheckedLockingSingleton();
}
}
}
return INSTANCE;
}
}
both are similar and it handled Serialization by themselves by implementing
//readResolve to prevent another instance of Singleton
private Object readResolve(){
return INSTANCE;
}
more
Another important difference is that java compiler treats static final fields of primitive types and String as literals. It means these constants become inline. It's similar to C/C++ #define preprocessor. See this SO question. This is not the case with enums.
Enums can be local
As of Java 16, an enum can be defined locally (within a method). This scope is in addition to being able to define an enum as nested or as separate class.
This new local definition scope came along with the new records feature. See JEP 395: Records for details. Enums, interfaces, and records can all be defined locally in Java 16+.
In contrast, public static final fields always have global scope.
I think an enum can't be final, because under the hood compiler generates subclasses for each enum entry.
More information From source
There are many advantages of enums that are posted here, and I am creating such enums right now as asked in the question.
But I have an enum with 5-6 fields.
enum Planet{
EARTH(1000000, 312312321,31232131, "some text", "", 12),
....
other planets
....
In these kinds of cases, when you have multiple fields in enums, it is much difficult to understand which value belongs to which field as you need to see constructor and eye-ball.
Class with static final constants and using Builder pattern to create such objects makes it more readable. But, you would lose all other advantages of using an enum, if you need them.
One disadvantage of such classes is, you need to add the Planet objects manually to the list/set of Planets.
I still prefer enum over such class, as values() comes in handy and you never know if you need them to use in switch or EnumSet or EnumMap in future :)
Main reason: Enums help you to write well-structured code where the semantic meaning of parameters is clear and strongly-typed at compile time - for all the reasons other answers have given.
Quid pro quo: in Java out of the box, an Enum's array of members is final. That's normally good as it helps value safety and testing, but in some situations it could be a drawback, for example if you are extending existing base code perhaps from a library. In contrast, if the same data is in a class with static fields you can easily add new instances of that class at runtime (you might also need to write code to add these to any Iterable you have for that class). But this behaviour of Enums can be changed: using reflection you can add new members at runtime or replace existing members, though this should probably only be done in specialised situations where there is no alternative: i.e. it's a hacky solution and may produce unexpected issues, see my answer on Can I add and remove elements of enumeration at runtime in Java.
You can do :
public enum Size { SMALL(1), MEDIUM(2), LARGE(3) };
private int sizeValue;
Size(sizeValue) {this.sizeValue = value; }
So with this you can get size value like this SMALL.getSizeValue();
If you want to set sizes Enums are not for you, if you will be only define constants and fixed values are fine.
Check this link maybe can help you

Initializing Fields Value in Constructor Versus in Fields Declaration [duplicate]

This question already has answers here:
Initialize class fields in constructor or at declaration?
(16 answers)
Closed 9 years ago.
As we know, in java and some other object-oriented programming languages, fields value can be set in constructor or be initialized in fields declaration statements. I want to know the essential differences between the two ways above. And what conditions I should initialze fields by constructor and what condtions I should't.
Thanks for your help.
The advantage with an argumented constructors is that you can set the field values as per the inputs but you cant do the same with initialized fields.
So if you want to create different objects with different attribute values then go for constructors with arguements. And assign the values of instance variables in your constructor.
If you simply want all the instance variables to have some default value, then assign the values at declaration.
The convention is to initalize a field in the constructor. A constructor is there to essentially build the object. It only follows that building implies the instanciation, or assignment, of it's members. It also means that all your logic for creating the object is in one place, which is desirable. For example..
public NewObj(String something, int somethingElse)
{
this.something = something;
this.somethingElse = somethingElse;
// All the logic is in one place. This is especially useful
// when dealing with huge classes.
}
We follow the conventions like this so when another programmer looks at our work, they will know instantly where to look for the logic that creates the class. By placing it in the field declarations (or worse, in both the field declarations and the constructor) you are confusing that convention.
Exceptions I've seen
When creating static final variables in a class, I've found that they are usually created in the field declaration. For example..
public class NewObj
{
public static final int EMPTY_OBJ = 1;
public static final int SPECIAL_OBJ = 2;
}
final fields are preferred as they are easier to reason about and final fields can only be set in the constructor. I suggest fields which mandatory should be in the constructor.
If you have fields which you want to be able to change later, use setters.
If you have to set the fields by name, there is no easy way to this with a constructor. There is the #ConstructorProperties but few class have implemented this. Java 8 wills support access to argument names via reflection, but for now setters are easier.
Note: there are two alternatives.
You can use static factory methods. This can not only have meaningful names but can return sub-classes
You can use a builder class. This gives you more options for how you define and constructor your object. This is particularly useful if you have lots of mandatory fields.
Using Constructors with Arguments , you can initialize the fields during the object creation with the input custom values provided.
This is often helpful when you want fields to have different values .
For Example:
class Employee{
String mName;
Employee(String name)
{
mName=name;
}
This can help you to initialize Employee names easily while creating Employee Object.

Custom fields on java enum not getting serialized

I have a Java Enum as shown below:
public enum ExecutionMode {
TYPE_A,
TYPE_B,
TYPE_C;
private ExecutionMode(){} //no args constr- no really required
private boolean incremental; //has get/set
private String someStr; //has get/set
}
I see that after deserialization, the custom fields on the enum are lost.
On reading more about it, I got the impression that enum gets deserialized into a string and hence its custom fields are ignored.
If its true, am I abusing Enum here & should just use POJO istead?
Or is there a way to serialize the custom fields (that are not part of the constructor)?
Thanks!
If the values are constant, this is better and you don't need to serialize anything
public enum ExecutionMode {
TYPE_A(x,t),
TYPE_B(y,z),
TYPE_C(b,s)
private boolean incremental; //has get/set
private String someStr; //has get/set
ExecutionMode(boolean incremental,String someStr){
///... set things appropriately
}
}
If you're setting these values at runtime, my inclination would be that this shouldn't be an enum in the first place - there should be a separate POJO that perhaps contains the values as well as a reference to an enum value.
From the Java language specification:
The final clone method in Enum ensures that enum constants can never
be cloned, and the special treatment by the serialization mechanism
ensures that duplicate instances are never created as a result of
deserialization. Reflective instantiation of enum types is prohibited.
Together, these four things ensure that no instances of an enum type
exist beyond those defined by the enum constants.
What you are asking for would create more than one instance of, say, TYPE_A. This would break enums. Enums should be immutable.

Categories

Resources