I know there are several similar topics with similar title but I have actually slightly different questions than other topics.
I have designed such a solution which abstract class implements and interface, and in the constructor it calls default method of interface to initialize a map.
Here is my interface:
public interface ICalculator{
int VALUE_OF_X= 10;
int VALUE_OF_Y= 50;
int VALUE_OF_Z = 70;
Map<String, Integer> CHAR_VAL_MAP = new HashMap<String, Integer>(7);
default void initValueMap(){
CHAR_VAL_MAP.put("X", VALUE_OF_X);
CHAR_VAL_MAP.put("Y", VALUE_OF_Y);
CHAR_VAL_MAP.put("Z", VALUE_OF_Z);
}
public int calculate(final String inStr);
}
And created an abstract class:
public abstract class AbstractCalculator implements ICalculator{
protected AbstractCalculator(){
initValueMap();
}
}
My idea was here to ensure that initValueMap method is called implicitly by the abstract class.
And the concreate class which extend abstract class is:
public class MyCalculator extends AbstractCalculator{
public int calculate(final String romanNumberStr){
// some logic code
}
}
I have basically two question:
1) Is there any design problem or wrong usage of OOP concepts ?
2) In C++. using const for the parameter is good programming behaviour. But in java word, it is not so common. Is it bad to use final in method parameters?
You are over complicating things. Java 9 added some nice of() methods to the Collections utility class. You can use those to create a map filled with values without the need to call an extra init method. Then you pass that map instance to new HashMap() to get that data into a modifiable map instance. And with older java, you can always write a method that creates and returns a prefilled map. There is no need to do creation and filling like you do (in separate pieces of code).
For the record: you understand that all fields of an interface are static by default and thus shared between all code using them?!
Regarding final, there are quite some differences to const from C++. The only thing that a final parameter gives you is checking that prevents you from inadvertently writing to a parameter. It can be useful to have that, but most people simply don't use it because they add such little gain, but make code quite harder to read.
There are a few ways to ensure that calculate is only called after the map is fully initialized. One way is to declare and initialize it in the interface directly:
public interface ICalculator {
int VALUE_OF_X = 10;
int VALUE_OF_Y = 50;
int VALUE_OF_Z = 70;
Map<String, Integer> CHAR_VAL_MAP = initValueMap();
static Map<String, Integer> initValueMap() {
Map<String, Integer> map = new HashMap<String, Integer>(7);
map.put("X", VALUE_OF_X);
map.put("Y", VALUE_OF_Y);
map.put("Z", VALUE_OF_Z);
return map;
}
public int calculate(final String inStr);
}
This may be preferred because static data is being initialized statically, where it is declared (though most of us don't particularly like stuffing interfaces with this kind of code).
If you want to call this initialization code in the abstract class, you can still use a static block:
public abstract class AbstractCalculator implements ICalculator {
static {
ICalculator.initValueMap();
}
}
But the simplest is perhaps to go with Map.of as suggested in GhostCat's answer, unless your Java runtime is older than 9.
Related
While working on a project, I came across the following code segment which appears to provide code, entirely contained inside a new variable declaration, which appears to override a method. I've, come across code of this form before but admittedly, I do not fully understand it. If anyone could explain the programming mechanisms upon which this code is based, I'd be very truly grateful. Particularly, when are overridden methods of this sort permitted inside of variable declarations. What other sorts of data structures allow such behavior? When is it advantageous to write code of such nature? Why not override the method outside of a variable declaration?
tempRequests.sort(new Comparator<Integer>()
{
#Override
public int compare(Integer integer1, Integer integer2)
{
return integer1.compareTo(integer2);
}
});
What other sorts of data structures allow such behavior?
-> You can sort objects by implements interface Comparable.
For example:
public class Car implements Comparable<Car> {
private String name;
#Override
public int compareTo(Car b) {
return name.compareTo(b.name);
}
}
->You can also use Comparator without override method compare inside the inner class.
public class Car implements Comparator<Car> {
private String name;
private double price;
#Override
public int compare(Car b1, Car b2) {
return b1.price - b2.price;
}
}
When is it advantageous to write code of such nature? Why not override the method outside of a variable declaration?
-> Image that after use sort object Car by name, you want to sort by something else (like by price, by weight).How to do this when you want to sort objects in different ways at different times? We use Comparator with define inside the inner class to do this.
*Additionally, Comparator is a functional interface since an only abstract method to implement. You can rewrite using a funky syntax in one line of code:
Ex:
Compareator<Car> byPrice = (b1,b2) -> b1.price - b2.price;
This mechanism has been explained well in the comments.
As an aside: ever since Java 8, this usage of anonymous classes is considered somewhat old fashioned, as it can be replaced with a simple Lambda expression:
tempRequests.sort((l, r) -> l.compareTo(r));
This applies to all "Functional Interfaces", which is defined as an interface with exactly one non-static and non-default method.
I had a question about reusability of lambda expression without code duplication. For example if I have a helper method I can easily code it as a static method and can refer to it from other classes without code duplication. How would this work in lambda expression ?
Example: I have the following static method written
public class MyUtil {
public static int doubleMe(int x) {
return x * 2;
}
}
I can reuse the same method without code duplication in multiple places across the project
public class A {
public void someOtherCalculation() {
MyUtil.doubleMe(5);
}
}
public class B {
public void myCalculation() {
MyUtil.doubleMe(3);
}
}
How would it work when it comes to a lambda function, write the function once and use the same at multiple class.
Function<Integer, Integer> doubleFunction = x -> x * 2;
In my example, where would I write the above lambda function and how would I reuse the same in class A and B ?
Where would I write the above lambda function
Since your function does not reference any fields, it is appropriate to put it in a static final field:
class Utility {
public static final Function<Integer,Integer> doubleFunction = x -> x * 2;
}
how would I reuse the same in class A and B?
You would refer to it as Utility.doubleFunction, and pass it in the context where it is required:
callMethodWithLambda(Utility.doubleFunction);
Note that method references let you define a function, and use it as if it were lambda:
class Utility {
public static Integer doubleFunction(Integer x) {
return x*2;
}
}
...
callMethodWithLambda(Utility::doubleFunction);
This approach is very flexible, because it lets you reuse the same code in multiple contexts as you find appropriate.
Really, anonymous functions are for cases where code reuse isn't necessary.
Dumb example, but say you're using map to add two to every number in a list. If this is a common action that you may need all over the place, a static function that adds two to a number makes more sense than writing the same lambda everywhere.
If, however you have a single function that adds two to a list, it makes more sense to define the "add two" function locally as a lambda so you dont plug up your class with code that isn't needed anywhere else.
When writing Clojure, which makes extensive use of higher-order functions, it's pretty common for me to create local anonymous functions that tidy up the code in the "full" function that I'm writing. The vast majority of these anonymous functions would be non-sensical in the "global" scope (or class-scope); especially since they usually have closures over local variables, so they couldn't be global anyways.
With lambda expressions, you don't need to worry about reusability (in fact, most of the lambdas are not being re-used at all). If you want a Function pointer to point to this method the you can declare one like below:
Function<Integer, Integer> doubleFunction = MyUtil::doubleMe;
And pass it to any method or stream to apply/map, e.g.:
public static void consume(Function<Integer, Integer> consumer, int value){
System.out.println(consumer.apply(value));
}
public static void main(String[] args) throws Exception{
Function<Integer, Integer> doubleFunction = MyUtil::doubleMe;
consume(doubleFunction, 5);
}
Different from other answers. I'd like to answer your question in TDD way.
IF your doubleMe is so simple as you have wrote, that is clrealy you should stop abusing method expression reference and just call it directly as a common method invocation.
IF your doubleMe is so complicated that you want to test doubleMe independent , you need to make implicit dependencies explicity by dependency injection to testing whether they can working together by their cummunication protocols. But java can't refer a method dierctly except you using reflection api Method/using a anonymous class that implements SAM interface which delegates request to a method before in jdk-8. What the happy thing is you can refer a method expression reference to a functional interface in jdk-8. so you can make implicit dependencies explicit by using functional interface, then I would like write some communication protocol test as below:
#Test
void applyingMultiplicationWhenCalculating???(){
IntUnaryOperator multiplication = mock(IntUnaryOperator.class);
B it = new B(multiplication);
it.myCalculation();
verify(multiplication).applyAsInt(3);
}
AND then your classes like as B applied dependency injection is more like as below:
public class B {
IntUnaryOperator multiplication;
public B(IntUnaryOperator multiplication){
this.multiplication = multiplication;
}
public void myCalculation() {
multiplication.applyAsInt(3);
}
}
THEN you can reuse a method by refer a method expression reference to a functional interface as below:
A a = new A(MyUtil::doubleMe);
B b = new B(MyUtil::doubleMe);
You can do something like below.
class Fn {
public static final Function<Integer, Integer> X2TIMES = x -> x *2;
}
class Test {
public static void main (String[] args) {
System.out.println(Fn.X2TIMES.apply(5));
}
}
I've few common constants which are used by multiple classes.
What's the most effective way to design in this case:
Should I redefine the constants in each class?
Or should I separate such constants in a public class, and use the constants (in separate class) within each class?
Or is there any other better approach?
Note:- I'm looking for best OO technique which would be applicable for this.
Constants should be strictly related to some type, they shouldn't just "exist". A Constants class may seem convenient, but it will soon become unmaintainable, not to mention many consider it an antipattern.
It's hard to suggest improvements without seeing your code, but it seems like you need to rethink your design if you find yourself needing the same constants defined in a few different classes outside of the scope of a type.
Providing a Constant Util class is the cleanest way.
class ConstantUtil {
public static final int MAX_SIZE = 1<<10;
}
The typical folder heirarchy is like this
com.example.util.ConstantUtil
If the contants are dedicated to an api define them there. E.g.
public interface TaskService {
public static final int PRIORITY_LOW = -1;
public static final int PRIORITY_NORMAL = 0;
public static final int PRIORITY_HIGH = 1;
public void schedule(Task task, int priority);
}
If constants are not releated to a single api define a constants interface. E.g. javax.swing.WindowConstants.
Or is there any other better approach? Note:- I'm looking for best OO technique which would be applicable for this.
java
This brings us back to the question how constants are used. Most times they are used to write conditional code. E.g.
public class TaskServiceImpl implements TaskService {
private List<Task> lowPriority = new ArrayList<Task>();
private List<Task> normalPriority = new ArrayList<Task>();
private List<Task> highPriority = new ArrayList<Task>();
public void schedule(Task task, int priority){
if(priority == PRIORITY_HIGH ){
highPriority.add(task);
} else if(priority == PRIORITY_LOW ){
lowPriority.add(task);
} else if(priority == PRIORITY_NORMAL){
normalPriority.add(task);
} else {
....
}
}
}
In this case find out what the purpose of the constants is. In the example above the purpose is to group the tasks or if you think further to order them for execution. Move that logic to an own class. E.g. Introduce a Priority class that might implement Compareable ;)
You can also take a look at my blog about type-switches https://www.link-intersystems.com/blog/2015/12/03/enums-as-type-discriminator-anti-pattern/.
It is about enum misuse, but it also applies to constants.
You can try to create a class which contains all the constants(i.e, the second approach).
For example:
classname : MyConstantsClass.java
public static final String SOME_CONSTANT="value";
and then use it like
MyConstantsClass.SOME_CONSTANT
As some have suggested to use interface to create constants then I don't think that it would be a good choice. As using interface to create constants have certain disadvantages as well:
The usage of an interface does not allow to implement a mechanism for converting the constants to a visible/human readable
representation.
If the constants are an "implementation detail", an interface might not be the natural place for the value (CodeSmells, ListenToTheCode).
Due to Java compiler optimization, complete code recompilation of all classes using the constants is necessary if a constant changes.
Just changing the interface and recompiling it does not work (this
is, however the case with all constants defined as 'static final')
Please refer:
Interfaces For Defining Constants
Interface for constants
Class for constants
Constant class :
interface Constants {
int CONSTANT_ONE = 0;
int CONSTANT_TWO = 1;
int CONSTANT_THREE = 2;
String BASE_PATH = "YourPath";
}
And usage:
if (someValue == Constants.CONSTANT_ONE) {
}
Edit:
In most cases use interface instead of class if there is no need to implement this interface by some class, then it is no need to add this public static final, because by default it is public static final so your code looks more clean.
Design a class like AppUtil.java and and define your constants public static final like below:
public class AppUtil
{
public static final String IMAGE_STATUS="0";
}
and when you want to use variable use . like below:
AppUtil.IMAGE_STATUS
I am currently making a library which is an utility for me to handle something which is not associated with the question (I am implicitly not saying the subject because it is not really important), however it does use reflection.
I am retrieving all declared and inherited methods from a class, which currently works fine and is not the issue. But the thing is, I need to do this as well for sub-classes since those inherit over like methods do (however you cannot override those like methods).
The problem that I am facing that it will use the same algorithm but there will be on difference, instead of calling clazz.getDeclaredMethods() I need to call clazz.getMethods. What is the best way too approach this, and I kind of need to return Class[] and Method[] in the method signature as well.
Normally I would look for a shared superclass, but in this case I prefer to the have Class[] and Method[] accordingly. For starters, I did some research and found some shared superclasses:
GenericDeclaration
AnnotatedElement
Since I need both Class[] and Method[] arrays I am thinking something
like generics, so the method would look like:
public static <T extends GenericDecleration> T[] getT () {
}
As mentioned by dasblinkenlight this will not work since the method doesn't take any arguments and cannot check whether to retrieve Class or Method objects.
But how would I detect whether I need to call getDeclaredMethods or getDeclaredClasses?
What is the best approach on how to do this without duplicating a lot of code? I really tried to explain myself here, but if it is still unclear what I am doing please feel free to ask away!
Thank you very much in advance!
After messing around with this, I have found a solution that totally fits my needs. This is a combination of generics and #dasblinkenlight's solution, like so:
public interface DeclExtractor<T extends GenericDecleration> {
public T[] extract (Class clazz);
public Class<? extends T[]) getGenericClass ();
DeclExtractor<Method> methodExtractor = new DeclExtractor<Method>() {
#Override
public Method[] extract (Class clazz) {
return clazz.getDeclaredMethods();
}
#Override
public Class<? extends Method[]> getGenericClass () {
return Method[].class;
}
}
// Same for Class
}
Now the method which also will return the correct type so you dont have to manually cast all GenericDeclaration to your original object type. My issue was that I used a collection for it and not the correct array:
public <T> T[] getAll (final DeclExtractor<T> extractor, Class<?> clazz) {
T[] declaration = extractor.extract (clazz);
//.. The algorithm..
// Return an instance of a collection as array (I use a set in my implementation)
final Object[] objects = myCollection.toArray();
return Arrays.copyOf(objects, objects.length, extractor.getGenericClass());
}
Technically you do not need the getGenericClass method in the interface, but I am using extract directly in a loop so I cannot pull the class of that, however, you can.
Hopefully this helps someone in the future :) Thanks again to #dasblinkenlight for the inspiration!
Your getT needs to get some input in order to decide what to do.
What about a method which can takes an enum as argument to determine whether it needs to get classes or methods? (from a comment)
There is a better approach: define an interface that performs the appropriate extraction, and make two instances of it - one for extracting classes, and one for extracting methods:
public interface DeclExtractor {
GenericDecleration[] extract(Class cl);
final DeclExtractor forClasses = new DeclExtractor() {
public GenericDecleration[] extract(Class cl) {
// make an array of GenericDecleration from extracted classes
}
};
final DeclExtractor forMethods = new DeclExtractor() {
public GenericDecleration[] extract(Class cl) {
// make an array of GenericDecleration from extracted methods
}
};
}
Now you can rewrite your getT to take an "extractor", like this:
public static GenericDecleration[] getT (DeclExtractor extractor, Class cl) {
...
// When it's time to get components of the class, make this call:
GenericDecleration[] components = extractor.extract(cl);
...
}
To initiate a call to getT, pass DeclExtractor.forClasses or DeclExtractor.forMethods:
GenericDecleration[] c = getT(DeclExtractor.forClasses);
GenericDecleration[] m = getT(DeclExtractor.forMethods);
I'd be extremely grateful if anyone could point out what I'm doing wrong.
I have an interface IDoubleSource, which I implement in a Person class. There is a LinearRegression class with a method that takes an IDoubleSource argument, but I will pass in the Person class.
As part of the IDoubleSource interface, an enum called Variables and a method called getDoubleValue(Enum) must be defined. Below, I show how I have done this in Person, and that the enum types are used to specify switch cases in the getDoubleValue() method.
The problems:
1) In LinearRegression, there is a method computeScore((MultiKeyCoefficient)Map, IDoubleSource), where the last argument is an interface. I cannot seem to access the Variables enum of the instance of the implementation of IDoubleSource within the computeScore method, despite having the interface imported into the LinearRegression class. It just doesn't register that an IDoubleSource has an enum called Variables (though I can call the getDoubleValue() method fine). Is there anything I'm obviously doing wrong, that prevents me accessing the enum Variables?
2) The getDoubleValue(Enum) method in Person class is designed to return a double value that depends on the value of the enum Variable passed to it. By looping through the keys (which are of String type) of a (MultiKeyCoefficient)Map in the LinearRegression class, I would like to use the keys to specify the enum values that I want as an argument to getDoubleValue(Enum) in the LinearRegression class (I would like getDoubleValue() to return several different values based on the Enum values it receives in the loop). However, I cannot use the (String) key in place of the expected enum as I get a ClassCastException java.lang.String cannot be cast to java.lang.Enum. How can I use the keys of the map to specify the Enums?
I'm not very familiar with using Enum types in Java, which may be a large part of my problem.
Now the code details:
I implement the following interface:
IDOUBLESOURCE INTERFACE
public interface IDoubleSource {
public enum Variables {
Default;
}
/**
* Return the double value corresponding to the given variableID
* #param variableID A unique identifier for a variable.
* #return The current double value of the required variable.
*/
public double getDoubleValue(Enum<?> variableID);
}
by creating the class:
PERSON CLASS
public class Person implements IDoubleSource {
public enum Variables {
nChildren,
durationInCouple,
ageDiff;
}
public Person() {
...
}
public double getDoubleValue(Enum<?> variableID) {
switch ((Variables) variableID) {
case nChildren:
return getNChildren();
case durationInCouple:
return (double)getDurationInCouple();
case ageDiff:
return getAgeDiff();
default:
throw new IllegalArgumentException("Unsupported variable");
}
In another package, I have a Class:
LINEARREGRESSION CLASS
public class LinearRegression
private MultiKeyCoefficientMap map = null;
public LinearRegression(MultiKeyCoefficientMap map) {
this.map = map;
}
....
public double score(IDoubleSource iDblSrc) {
return computeScore(map, iDblSrc);
}
public static double computeScore(MultiKeyCoefficientMap coeffMap, IDoubleSource iDblSrc) {
try {
final Map<String, Double> varMap = new HashMap<String, Double>();
for (Object multiKey : coeffMap.keySet())
{
final String key = (String) ((MultiKey) multiKey).getKey(0);
Enum<?> keyEnum = (Enum<?>) key; //Throws class cast exception
double value = iDblSrc.getDoubleValue(keyEnum);
varMap.put(key, value);
}
return computeScore(coeffMap, varMap);
} catch (IllegalArgumentException e) {
System.err.println(e.getMessage());
return 0;
}
}
}
public static double computeScore(MultiKeyCoefficientMap amap, Map<String, Double> values)
{
//Do some stuff
}
I'm very grateful that you've taken the time to read through this code. Please do let me know if you have any idea what I'm doing wrong!
Many Thanks and Best Wishes,
R
The key incorrect assumption you have is that the IDoubleSource.Variables enum is connected in some way to the Person.Variables enum. They're totally unrelated. (They just happen to have the same simple name.)
When a class (like Person) implements an interface (like IDoubleSource), that class is declaring that it will provide implementations of the (non-default) methods in that interface. Any inner classes, inner enums, or inner interfaces within the implemented interface are only relevant if they appear in the signatures of one of the interface methods that must be implemented.
So you could change your interface to:
public interface IDoubleSource {
public enum Variables {
Default;
}
public double getDoubleValue(Variables variableID);
}
... but then the only legal value to pass in to any implementation of getDoubleValue is Default -- implementors of IDoubleSource can't extend the set of allowed enum values.
I think what you really want to do is to declare that implementors of IDoubleSource must declare what type of enum they deal in:
public interface IDoubleSource<T extends Variables & Enum<T>> {
public interface Variables { }
public double getDoubleValue(T variableID);
}
What you're saying here is that an implementor of the getDoubleValue() method must use some enum type as its arg, and that type must also implement the Variables interface. (If there are no meaningful methods to put in that inner inteface, you can drop it for simplicity.)
Then your implementation would look like this:
public class Person implements IDoubleSource<PersonVariables> {
public enum PersonVariables implements Variables {
nChildren,
durationInCouple,
ageDiff;
}
public double getDoubleValue(PersonVariables variableID) {
switch (variableID) { //no cast necessary here!
case nChildren:
// ...
default:
// this is now really impossible
// if the rest of your program has no unsafe casts
throw new IllegalArgumentException("Unsupported variable");
}
}
}
The last trick, then, is to enhance the signature of your computeScore method to ensure that the iDblSrc argument uses the same enum type as those found in the map:
public static <T extends IDoubleSource.Variable & Enum<T>>
double computeScore(MultiKeyCoefficientMap<T,?> coeffMap,
IDoubleSource<T> iDblSrc);
Then the keys in the map won't be Strings at all, but rather instances of the right enum type.
There are multiple problems here:
An enum declared in an interface (or class) implemented (extended) by another class is NOT overridden by the implementing class. So what you have above is two completely different enums, which happen to have the same local name. But one is IDoubleSource.Variables, with one value: IDoubleSource.Variables.Default, and the other is Person.Variables, with three values, one of which is Person.Variables.nChildren
As the OP pointed out, you cannot simply cast a String (which presumably has a value matching the name of some enum) to an enum, and have it resolve to the expected enum value.
Given these two things, and that it seems you want to select different processing for subtype specific types of things, then at worst, you could pass the string key as an argument, and then vary the logic internally. But really, you have come up with a scheme where you need to have knowledge of the subtype in order to request appropriate (supported) processing. This does not allow for the type of decoupling that is intended when using an interface/implementing class(es). You may want to review the objectives here and work out a better design.