I have some custom classes, which contain information about different viewtypes in a RecyclerView, like title, description, etc (there are different variables for each class though). I want to add these classes to an ArrayList, but I don't want it to be a generic (Object?) ArrayList, I want to make sure only my custom classes can be put in. Now I could do this by making another class for it with a setter and getter, and do some checks, but I'd rather have something like ArrayList<CustomGroup>, where CustomGroup could be any of CustomClass1, CustomClass2, etc... Is this possible, and if so, how would I do this?
Example:
public class CustomClass1 {
String title, description;
int amount;
// Getter & Setter
}
public class CustomClass2 {
String errorMessage;
int errorCode;
// Getter & Setter
}
public class CustomClass3 {
String warningName;
double amount;
// Getter & Setter
}
ArrayList<CustomGroup> arrayList = new ArrayList<>();
CustomClass3 customClass3 = new CustomClass3();
// Set values for customClass3
arrayList.add(customClass3);
CustomClass1 customClass1 = new CustomClass1();
// Set values for customClass1
arrayList.add(customClass1);
I would recommend using an interface for this. You can use interfaces as "tags", where the interface basically defines nothing but the classes you want to allow in the list implement it. In your case, however, you could have the interface define the String and int properties.
Interface "tag" with nothing specified
public interface ICustomClassInterface {
}
public class CustomClass1 implements ICustomClassInterface {
String title, description;
int amount;
}
ArrayList<ICustomClassInterface> arrayList = new ArrayList<ICustomClassInterface>();
Only classes that implement the interface can be added to the list. However, your issue here is you will be getting to them through this interface which defines nothing, i.e. you will need to figure out what type it is.
Ideally you would refactor your classes to have the common functionality either defined in an abstract class or specified in an interface, then you don't need to care what the actual type is.
Interface with needed properties defined
public interface ICustomClassInterface {
String FieldA;
int FieldB;
}
public CustomClass1 implements ICustomClassInterface {
String FieldA;
int FieldB;
}
ArrayList<ICustomClassInterface> arrayList = new ArrayList<ICustomClassInterface>();
I would agree with the other answer which suggests using an interface. I would add that, since the examples that you show do not have the same types, you'll find yourself doing checks; perhaps like:
if (someClass instanceof CustomClass1) {
...
} else if (someClass instanceof CustomClass2) {
...
} else if (someClass instanceof CustomClassN) {
...
} else { ... }
That's not very extensible or easily maintained.
You could use the interface, whether empty or with common attributes of the same type, but it might get ugly though doing said checks. Maybe what you could do to avoid that is add a CustomClassProcessor class which will have overloaded methods for the various types you have to handle; this is called the visitor pattern.
public class CustomClassProcessor {
public void process(CustomClass1 cc) {
// Do stuff for CustomClass1
}
public void process(CustomClass2 cc) {
// Do stuff for CustomClass2
}
public void process(CustomClass cc) {
// Do stuff for CustomClass3
}
...
}
Your interface would be like so:
public interface CustomClass {
public void getProcessed(CustomClassProcessor cp);
}
One example of a concrete custom class would be:
public class CustomClass1 implements CustomClass {
#Override
public void getProcessed(CustomClassProcessor cp) {
cp.process(this);
}
}
And you'd use it like:
for (CustomClass cc : list)
cc.getProcessed(customClassProcessor);
or with Java 8 features...
list.forEach(cc -> cc.getProcessed(customClassProcessor);
You have several absolutely different objects and requirement to join it with array list to show it in recyclerView by position. So you have to use ArrayList of Object's(or another collection of objects) and you can't avoid it and pospone checking types.
You have to create such list and make connection of concrete class of stored object with item type (in getItemType) via using instanceof. After that you can create viewHolders according to these types and then in onBindViewHolder cast current item to connected viewHolder or encapsulate casting in concrete view holders
Related
Essentially what I'm trying to do is create a generic method that can take many different kinds of enums. I'm looking for a way to do it how I'm going to describe, or any other way a person might think of.
I've got a base class, and many other classes extend off that. In each of those classes, I want to have an enum called Includes like this:
public enum Includes {
VENDOR ("Vendor"),
OFFERS_CODES ("OffersCodes"),
REMAINING_REDEMPTIONS ("RemainingRedemptions");
private String urlParam;
Includes(String urlParam) {
this.urlParam = urlParam;
}
public String getUrlParam() {
return urlParam;
}
}
I've got a method that takes in a generic class that extends from BaseClass, and I want to be able to also pass any of the includes on that class to the method, and be able to access the methods on the enum, like this:
ApiHelper.Response<Offer> offer = apiHelper.post(new Offer(), Offer.Includes.VENDOR);
public <T extends BaseClass> Response<T> post(T inputObject, Includes... includes) {
ArrayList<String> urlParams = new ArrayList<String>();
for (Include include : includes){
urlParams.add(include.getUrlParam());
}
return null;
}
Is there a way to be able to pass in all the different kinds of enums, or is there a better way to do this?
---EDIT---
I've added an interface to my enum, but how can I generify my method? I've got this:
public <T extends BaseClass> Response<T> post(Offer inputObject, BaseClass.Includes includes) {
for (Enum include : includes){
if (include instanceof Offer.Includes){
((Offer.Includes) include).getUrlParam();
}
}
return null;
}
But I get an error on apiHelper.post(new Offer(), Offer.Includes.VENDOR); saying the second param must be BaseClass.Includes.
Enums can implement interfaces, so you can create an interface with these methods that you'd like to be able to call:
interface SomeBaseClass {
String getUrlParam();
void setUrlParam(String urlParam);
}
and then your enum can implement this interface:
public enum Includes implements SomeBaseClass {
VENDOR ("Vendor"),
OFFERS_CODES ("OffersCodes"),
REMAINING_REDEMPTIONS ("RemainingRedemptions");
private String urlParam;
Includes(String urlParam) {
this.urlParam = urlParam;
}
#Override
public String getUrlParam() {
return urlParam;
}
#Override
public void setUrlParam(String urlParam) {
this.urlParam = urlParam;
}
}
If you want to get really fancy, it's possible to restrict subtypes of the interface to enums, but the generic type declaration will be pretty ugly (thus hard to understand and maintain) and probably won't provide any "real" benefits.
Unrelated note regarding this design: it's a pretty strong code smell that the enum instances are mutable. Reconsider why you need that setUrlParam() method in the first place.
I have a code which was initially designed for just a single team where they were passing an enum [which stores list of tasks] to an api. This api then progates the use of this enum to many other classes.
Now i have a task where this code needs to be used by multiple teams and they can pass there own set of tasks in form of enums.
Given the current implementation i dont think it is feasible to support multiple teams which completely overhauling the code because enum's cannot extend other enums.
Is there any way to implement this without massive changes?
But... enums can implement interfaces, for example:
public interface Task {
int getPriority(); // just for example
// plus whatever methods define a task
}
public enum Team1Task implements Task {
Task1(1),
Task2(3);
private final int priority;
private Team1Task(int priority) {
this.priority = priority;
}
public int getPriority() {
return priority;
}
}
Now we can employ java generic kung fu to specify a generic parameter bounded to a suitable enum:
public class TaskProcessor<T extends Enum<T> & Task> {
public void process(T task) {
// do something with task
}
}
To use it:
TaskProcessor<Team1Task> p = new TaskProcessor<Team1Task>();
p.process(Team1Task.Open); // will only accept a Team1Task instance
FYI, as a curiosity of generics, you can alternatively use this bound to achieve the same thing:
public class TaskProcessor<T extends Enum<? extends Task>> {
Although I can find no practical difference in effect, I find it lacks the clarity and familiar pattern of the intersection bound above. For more on this see this question.
It is comparatively easy to make much of the work around enums generic.
Here's a severely cut-down example. It defines a generic database Table class that takes an enum Column as its defining type. The enum defines what columns are in the table. The defining type is an enum that also implements an interface which is a really useful trick.
public class Table<Column extends Enum<Column> & Table.Columns> {
// Name of the table.
protected final String tableName;
// All of the columns in the table. This is actually an EnumSet so very efficient.
protected final Set<Column> columns;
/**
* The base interface for all Column enums.
*/
public interface Columns {
// What type does it have in the database?
public Type getType();
}
// Small list of database types.
public enum Type {
String, Number, Date;
}
public Table(String tableName,
Set<Column> columns) {
this.tableName = tableName;
this.columns = columns;
}
}
You can now create your real table with something like:
public class VersionTable extends Table<VersionTable.Column> {
public enum Column implements Table.Columns {
Version(Table.Type.String),
ReleaseDate(Table.Type.Date);
final Table.Type type;
Column(Table.Type type) {
this.type = type;
}
#Override
public Type getType() {
return type;
}
}
public VersionTable() {
super("Versions", EnumSet.allOf(Column.class));
}
}
Note that this is a truly trivial example but with a little work it is easy to move a lot of your enum work into the parent class.
This technique does retain the type-safety checks you get when using generics.
Enums can implement interfaces. I would recommend coming up with a reasonable interface for the task. make your enum implement the interface and your code will continue to work just fine. other teams can use whatever interface implementation they desire (their own enum or something else). (note, without code it's hard to make very explicit recommendations).
You probably should not use enums for this, but if you want, you can implement logic in helper class, or set of classes that extend each other, and make enums a thin wrappers saround it:
public enum MyTaskEnum {
A, B, C;
private final TaskEnumHelper helper = new TaskEnumHelper();
public void foo (int x, int y)
{
helper.foo (x, y);
}
}
It is more complex than it sounds, but I think I am obliged to try something like it. I want to make an abstract parent class with a prototyping of an enum (I want to declare the enum with only one value probably that will be the default unitialized one and also declaring a couple of methods that I will be using from the subclass), then I want to class that will extend the abstract parent to actually intialize the very same enum (I know that this practically hides the parent enum) so that the kid class will define a set of items inside the enum, but keep the methods probably.
I do not know much about this level of abstraction so I will now describe the nature of my problem, in case there is a more practical solution:
I have a bunch of files that contain classes that implement a lot of commands based on enums. (e.g. class1 implements Observer has an update method that uses an enum-based switch to decide what command was picked, same applies for the other classes) I now want to abstract this whole thing in a way that I have an enum variable with the exact same name in all classes (e.g. CommandSet) so that I can have a generic method inside the parent that will be able to print a help list to my system using the inside methods of the enum. Now I know I can rewrite the exact same method in every class, but I want to abstract it so that others can keep on extending the library I am making!
Hopefully I am not too confusing or too confused and somone can help me! :)
Edit: Here is an idea of the code (Probably not right):
public abstract class Commands{
enum CommandSet{
// empty command, placeholder
null_command ("command name", "command description");
// the Strings used for name and description
private final String name;
private final String description;
// constructor
CommandSet(String name, String description){
this.name=name;
this.description=description;
}
// get parameters
public String getName(){
return name;
}
public String getDescription(){
return description;
}
}
public void showHelp(){
for (CommandSet i : CommandSet.values()) {
printf(i.getName(),":",i.getDescription());
}
}
}
public class StandardCommads extends Commands implements Observer{
// I want to change the enum here, just changing the values so that null_command ("command name", "command description") will get removed and I will add a dozen other values, but keep the methods that the parent had
// update inherited from Observer
#Override
public void update(Observable observable, Object object) {
// I want the commands inside the switch cases defined inside this class's enum
switch(CommandSet.valueOf(String.valueOf(object)){
case command1: doStuff1();break;
case command2: doStuff2();break;
...
case commandN: doStuffN();break;
}
// other methods
void doStuff1(){
...
}
...
void doStuffN(){
...
}
}
public class NonStandardCommads extends Commands implements Observer{
// Another set of commands here for the enum keeping the same methods it had in the parent
// update inherited from Observer
#Override
public void update(Observable observable, Object object) {
// Other set of commands inside this class used in the switch statement
switch(CommandSet.valueOf(String.valueOf(object)){
case Zcommand1: doStuffz1();break;
case Zcommand2: doStuffz2();break;
...
case ZcommandN: doStuffzN();break;
}
// other methods
void doStuffz1(){
...
}
...
void doStuffzN(){
...
}
}
Impossible: Java enums can neither extend another class nor be extended themselves.
They can however implement interfaces. Perhaps you can use that to your advantage.
There is something else about enums that may help you: enums are not immutable. You could change field values of the enums, however that would change them for the whole JVM.
Another approach maybe to pass your subclass instances into a method of the enum and have the enum use your subclass as a call back to get different functionality out of an enum for a different user of the enum.
Nope, you can't do that.
Java Enums run out of gas very quickly & definitely, when you want to add/extend more definitions or instantiate the enum instances, at a later time. (eg load them from database, configure them in an instance method, not just statically.)
Behaviour/ or logic in Java enums is kinda limited too -- you can define & set properties, but only what's statically initializable, and logic seems basic (you end up mainly just comparing references or ordinals, with the other defined enum constants).
What you can do:
You can implement an ancestor Command or AbstractCommand class, with a integer Code, and then subclass it to define concrete values/ additional codes/ load or configure instances, etc.
For further benefit, you get efficient switch & despatch (by Code) plus the ability to define further details/properties, instantiate commands as-needed, etc.
Essentially, this is how you used to define an Enum before Java supported them. Though you may be using them as value objects, rather than strictly static.
My expertise:
I've done extensive compiler & type-system work, tried enums for file-types and associated data/behaviour.. explored the outer limits, and reached the definite boundaries.
I also like being able to instantiate & return a new UnknownFileType("") as an answer, too. Enums can't do that.
Example:
(We'll despatch by String, not int -- since your code appears to be using Java 7. This makes command resolution easier, than requiring both a syntactical "name" and an internal integer "code".)
public static class Command {
protected String code;
protected String desc;
public String getCode() {return code;}
public String getDesc() {return desc;}
public Command (String code, String desc) {
this.code = code;
this.desc = desc;
}
public String toString() {return code;}
}
public class StandardCommands {
public static Command READ = new Command("READ", "read a record");
public static Command CREATE = new Command("WRITE", "create a record");
public static Command EDIT = new Command("WRITE", "modify a record");
}
public class FurtherCommands extends StandardCommands {
public static Command LIST = new Command("LIST", "list all records");
}
public class QueryCommands extends FurtherCommands {
public static class QueryCmd extends Command {
protected String search;
public String getSearch() {return search;}
// constructor..
}
public static QueryCmd QUERY_EXAMPLE = new QueryCmd("QUERY", "example", "query for specified string");
public static QueryCmd createQuery (String search) {
return new QueryCmd( "QUERY", search, "query for specified string");
}
}
I would like to extend a class and then copy the value from an instance of the class which has been extended, so I get all its parameters in my new class. In case this doesn't make sense, a simple example of what I'm trying to do:
public class MyTableModel extends DefaultTableModel {
public MyTableModel(DefaultTableModel model){
this = (MyTableModel) model; /* I realise this is invalid */
}
public newMethod(){
// Some additional code
}
}
Is this possible to achieve?
It looks like you want composition instead of inheritance. In particular, it looks like you're trying to use the decorator pattern. That is, you want to take an existing instance of DefaultTableModel, and create another DefaultTableModel that forwards most of the methods to the underlying delegate, but perhaps adding/modifying/decorating some functionalities.
You can never set this = somethingElse;, but you can have a DefaultTableModel delegate, and forward most/all requests to delegate, perhaps adding/decorating some methods as necessary.
See also
Effective Java 2nd Edition, Item 16: Favor composition over inheritance
Guava Example: ForwardingCollection
An example of this pattern is ForwardingCollection from Guava:
A java.util.Collection which forwards all its method calls to another collection. Subclasses should override one or more methods to modify the behavior of the backing collection as desired per the decorator pattern.
You can see the source code to see how this pattern is typically implemented:
#Override protected abstract Collection<E> delegate();
public int size() {
return delegate().size();
}
public boolean isEmpty() {
return delegate().isEmpty();
}
public boolean removeAll(Collection<?> collection) {
return delegate().removeAll(collection);
}
// many more interface Collection methods implemented like above...
As you can see, all the ForwardingCollection does is it implements Collection simply by forwarding all methods to its delegate(), another Collection. Understandably this is rather repetitive and mundane code to write, but now subclasses can simply extends ForwardingCollection and only decorate what they want to decorate.
You can't not set this in Java to anything, it is just used for expressions like (this == someObject) or accessing some property of the object being currently used like (this.someProperty) or inside a constructor to initialize the current object. See here for more info about the this keyword
This code will likely throw a java.lang.ClassCastException
That is MyTableModel is a DefaultTableModel but DefaultTableModel is not a MyTableModel. See http://java.sun.com/docs/books/jls/third_edition/html/conversions.html for more details about type conversion in java
If there is some state and/or behavior that you want to reuse from your parent class in your subclass you should consider marking those members as protected, or consider other form of composition.
A better way to do this would be to make the fields of the superclass protected instead of private - this will give you access to them in your subclass.
Note that when you defined the subclass constructor, you will need to call a constructor from the superclass as well, so in that respect you'll still be able to pass in all the required variables.
And don't forget that all public methods in the superclass can be called as-is by any code that has an instance of your subclass.
EDIT: A little example might help:
public class DefaultTableModel
{
protected String modelName;
protected int numberOfTables;
private numTimesReinited = 0;
public DefaultTableModel(String name, int numTabs)
{
modelName = name;
numberOfTables = numTabs;
}
public void reinit()
{
numTimesReinited++;
// Other stuff
}
protected int getNumberOfReinits()
{
return numTimesReinited;
}
public String getName()
{
return name;
}
}
public class MyTableModel extends DefaultTableModel
{
private String modelType;
public MyTableModel(String name, int numTables, String modelType)
{
super(name, numTables); // sets up the fields in the superclass
this.modelType = modelType;
}
// purely "local" code
public void getModelType()
{
return modelType;
}
// Accesses several protected data to provide new (public) functionality
public void addTable()
{
if (getNumberOfReinits() < 10)
{
numberOfTables++;
reinit();
}
}
}
Let me know if I've misunderstood your requirements, but it sounds like you want to access fields and behaviour of the superclass - which you'll have automatic access to in your subclass so long as they're not private.
I just found out that Java allows enums to implement an interface. What would be a good use case for that?
Here's one example (a similar/better one is found in Effective Java 2nd Edition):
public interface Operator {
int apply (int a, int b);
}
public enum SimpleOperators implements Operator {
PLUS {
int apply(int a, int b) { return a + b; }
},
MINUS {
int apply(int a, int b) { return a - b; }
};
}
public enum ComplexOperators implements Operator {
// can't think of an example right now :-/
}
Now to get a list of both the Simple + Complex Operators:
List<Operator> operators = new ArrayList<Operator>();
operators.addAll(Arrays.asList(SimpleOperators.values()));
operators.addAll(Arrays.asList(ComplexOperators.values()));
So here you use an interface to simulate extensible enums (which wouldn't be possible without using an interface).
Enums don't just have to represent passive sets (e.g. colours). They can represent more complex objects with functionality, and so you're then likely to want to add further functionality to these - e.g. you may have interfaces such as Printable, Reportable etc. and components that support these.
The Comparable example given by several people here is wrong, since Enum already implements that. You can't even override it.
A better example is having an interface that defines, let's say, a data type. You can have an enum to implement the simple types, and have normal classes to implement complicated types:
interface DataType {
// methods here
}
enum SimpleDataType implements DataType {
INTEGER, STRING;
// implement methods
}
class IdentifierDataType implements DataType {
// implement interface and maybe add more specific methods
}
There is a case I often use. I have a IdUtil class with static methods to work with objects implementing a very simple Identifiable interface:
public interface Identifiable<K> {
K getId();
}
public abstract class IdUtil {
public static <T extends Enum<T> & Identifiable<S>, S> T get(Class<T> type, S id) {
for (T t : type.getEnumConstants()) {
if (Util.equals(t.getId(), id)) {
return t;
}
}
return null;
}
public static <T extends Enum<T> & Identifiable<S>, S extends Comparable<? super S>> List<T> getLower(T en) {
List<T> list = new ArrayList<>();
for (T t : en.getDeclaringClass().getEnumConstants()) {
if (t.getId().compareTo(en.getId()) < 0) {
list.add(t);
}
}
return list;
}
}
If I create an Identifiable enum:
public enum MyEnum implements Identifiable<Integer> {
FIRST(1), SECOND(2);
private int id;
private MyEnum(int id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
Then I can get it by its id this way:
MyEnum e = IdUtil.get(MyEnum.class, 1);
Since Enums can implement interfaces they can be used for strict enforcing of the singleton pattern. Trying to make a standard class a singleton allows...
for the possibility of using reflection techniques to expose private methods as public
for inheriting from your singleton and overriding your singleton's methods with something else
Enums as singletons help to prevent these security issues. This might have been one of the contributing reasons to let Enums act as classes and implement interfaces. Just a guess.
See https://stackoverflow.com/questions/427902/java-enum-singleton and Singleton class in java for more discussion.
It's required for extensibility -- if someone uses an API you've developed, the enums you define are static; they can't be added to or modified. However, if you let it implement an interface, the person using the API can develop their own enum using the same interface. You can then register this enum with an enum manager which conglomerates the enums together with the standard interface.
Edit: #Helper Method has the perfect example of this. Think about having other libraries defining new operators and then telling a manager class that 'hey, this enum exists -- register it'. Otherwise, you'd only be able to define Operators in your own code - there'd be no extensibility.
The post above that mentioned strategies didn't stress enough what a nice lightweight implementation of the strategy pattern using enums gets you:
public enum Strategy {
A {
#Override
void execute() {
System.out.print("Executing strategy A");
}
},
B {
#Override
void execute() {
System.out.print("Executing strategy B");
}
};
abstract void execute();
}
You can have all your strategies in one place without needing a separate compilation unit for each. You get a nice dynamic dispatch with just:
Strategy.valueOf("A").execute();
Makes java read almost like a tasty loosely typed language!
Enums are just classes in disguise, so for the most part, anything you can do with a class you can do with an enum.
I cannot think of a reason that an enum should not be able to implement an interface, at the same time I cannot think of a good reason for them to either.
I would say once you start adding thing like interfaces, or method to an enum you should really consider making it a class instead. Of course I am sure there are valid cases for doing non-traditional enum things, and since the limit would be an artificial one, I am in favour of letting people do what they want there.
Most common usage for this would be to merge the values of two enums into one group and treat them similarly. For example, see how to join Fruits and Vegatables.
For example if you have a Logger enum. Then you should have the logger methods such as debug, info, warning and error in the interface. It makes your code loosely coupled.
One of the best use case for me to use enum's with interface is Predicate filters. It's very elegant way to remedy lack of typness of apache collections (If other libraries mayn't be used).
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
public class Test {
public final static String DEFAULT_COMPONENT = "Default";
enum FilterTest implements Predicate {
Active(false) {
#Override
boolean eval(Test test) {
return test.active;
}
},
DefaultComponent(true) {
#Override
boolean eval(Test test) {
return DEFAULT_COMPONENT.equals(test.component);
}
}
;
private boolean defaultValue;
private FilterTest(boolean defautValue) {
this.defaultValue = defautValue;
}
abstract boolean eval(Test test);
public boolean evaluate(Object o) {
if (o instanceof Test) {
return eval((Test)o);
}
return defaultValue;
}
}
private boolean active = true;
private String component = DEFAULT_COMPONENT;
public static void main(String[] args) {
Collection<Test> tests = new ArrayList<Test>();
tests.add(new Test());
CollectionUtils.filter(tests, FilterTest.Active);
}
}
When creating constants in a jar file, it is often helpful to let users extend enum values. We used enums for PropertyFile keys and got stuck because nobody could add any new ones! Below would have worked much better.
Given:
public interface Color {
String fetchName();
}
and:
public class MarkTest {
public static void main(String[] args) {
MarkTest.showColor(Colors.BLUE);
MarkTest.showColor(MyColors.BROWN);
}
private static void showColor(Color c) {
System.out.println(c.fetchName());
}
}
one could have one enum in the jar:
public enum Colors implements Color {
BLUE, RED, GREEN;
#Override
public String fetchName() {
return this.name();
}
}
and a user could extend it to add his own colors:
public enum MyColors implements Color {
BROWN, GREEN, YELLOW;
#Override
public String fetchName() {
return this.name();
}
}
Another posibility:
public enum ConditionsToBeSatisfied implements Predicate<Number> {
IS_NOT_NULL(Objects::nonNull, "Item is null"),
IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"),
IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative");
private final Predicate<Number> predicate;
private final String notSatisfiedLogMessage;
ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) {
this.predicate = predicate;
this.notSatisfiedLogMessage = notSatisfiedLogMessage;
}
#Override
public boolean test(final Number item) {
final boolean isNotValid = predicate.negate().test(item);
if (isNotValid) {
log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage);
}
return predicate.test(item);
}
}
and using:
Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);
Enums are like Java Classes, they can have Constructors, Methods, etc. The only thing that you can't do with them is new EnumName(). The instances are predefined in your enum declaration.
Here's my reason why ...
I have populated a JavaFX ComboBox with the values of an Enum. I have an interface, Identifiable (specifying one method: identify), that allows me to specify how any object identifies itself to my application for searching purposes. This interface enables me to scan lists of any type of objects (whichever field the object may use for identity) for an identity match.
I'd like to find a match for an identity value in my ComboBox list. In order to use this capability on my ComboBox containing the Enum values, I must be able to implement the Identifiable interface in my Enum (which, as it happens, is trivial to implement in the case of an Enum).
I used an inner enum in an interface describing a strategy to keep instance control (each strategy is a Singleton) from there.
public interface VectorizeStrategy {
/**
* Keep instance control from here.
*
* Concrete classes constructors should be package private.
*/
enum ConcreteStrategy implements VectorizeStrategy {
DEFAULT (new VectorizeImpl());
private final VectorizeStrategy INSTANCE;
ConcreteStrategy(VectorizeStrategy concreteStrategy) {
INSTANCE = concreteStrategy;
}
#Override
public VectorImageGridIntersections processImage(MarvinImage img) {
return INSTANCE.processImage(img);
}
}
/**
* Should perform edge Detection in order to have lines, that can be vectorized.
*
* #param img An Image suitable for edge detection.
*
* #return the VectorImageGridIntersections representing img's vectors
* intersections with the grids.
*/
VectorImageGridIntersections processImage(MarvinImage img);
}
The fact that the enum implements the strategy is convenient to allow the enum class to act as proxy for its enclosed Instance. which also implements the interface.
it's a sort of strategyEnumProxy :P the clent code looks like this:
VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
If it didn't implement the interface it'd had been:
VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);