Interfaces vs. enums - java

Between interfaces and enums, which is better for declaring constants? Why is it so?

Its always better to use Enums to declare constants as the objective of interfaces are on a totally different level. Yes, there are lots of interfaces which have a public static final constants, but I feel that enums exclusive job is to provide you these constants.

If there is a reason for your constants to have a specific type, if they need some kind of behavior (i.e., methods), or if they are composites of other values, enums are the way to go.
For example, let's assume you're implementing a card game and you want to represent values and suits:
enum Rank {
ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN,
EIGHT, NINE, TEN, JACK, QUEEN, KING;
}
enum Suit { SPADES, CLUBS, DIAMONDS, HEARTS }
There, it's now impossible to create cards with bogus suits or ranks.
Sometimes, though, you are just interested in having a bunch of frequently used values declared somewhere. In that case, putting them in an enum would just be unnecessary effort, since these constants are just a tool to save us from remembering all the decimals of, say, π when we are calculating the circumference of a circle, or something. Which looks better?
// Using enum:
enum MathConstant {
PI(3.14159265358979323846), E(2.7182818284590452354);
private final double value;
MathConstant(double v) { value = v; }
public double value() { return value; }
}
// Usage:
double circumference = MathConstant.PI.value() * diameter;
// Using a constant class:
final class MathConstants {
private MathConstants() { throw new UnsupportedOperationException(); }
public static final double PI = 3.14159265358979323846,
E = 2.7182818284590452354;
}
// Usage:
double circumference = MathConstants.PI * diameter;
As for interfaces: Never put constants in an interface. The "constant interface" pattern is bad (justification), and the only argument to use it has been rendered invalid since import static was added to Java.

Interfaces are designed to define common behaviours, enums to define common values.
Enum represents a real value which can be compared to another value, or stored in the database easily.
You can also have a flag-enum (in C#, don't know in Java) which let you perform binary operations on enum's values (AND, OR, XOR, etc).

If you work with Java 5 or newer then Enum are the way to go. The only exception is if your list of const is open and can be extended. Enums can not be extended. Another exception is if it are single values like a MAX_INTEGER.

Just a code :
public interface InterfaceForConstants() {
String **TOTO** = "Et voilà !";
double **PI** = 3.14159265358979323846;
}
Using :
class ClasseName implements InterfaceForConstants () {
String myString;
if (myString.equals(**TOTO**) {
// do something
}
double circumference = **PI** * diameter; // instead of MathConstants.PI * diameter;
}
Clean and simple. If something can do what you need, take the simplest one!
Writing code by the rules is good, writing code that is easy to read is better, even if a rule is not respected. Think about when you have to read your code after a few months.
If you want to be more specific, make a javadoc to explain it!

Related

Passing arguments, good and bad practice in Java/OOP programming

I've recently started writing android applications in Java, I'm completely new to Java and I did the basics of object oriented programming in c++ at college. My question is, what is good and bad practice when passing variable data to different methods in Java? For example, something I have been doing in my code is:
String one;
String two;
String three;
String four;
exampleOne(one, two, three, four);
exampleOne(String one, String two, String three, String four) {
// do something
exampleTwo(one, two, three, four);
}
exampleTwo(String one, String two, String three, String four) {
// do something
exampleThree(one, two, three, four);
}
exampleThree(String one, String two, String three, String four) {
// do something
}
In my code I've done something like this where I pass arguments up to 5 times, is it bad practice to do this? What would be a cleaner more eco option?
If there are many arguments and they would be passed many times, I would go for a DTO object.
Create a Pojo class which encapsulates those parameters and pass the instance between methods. You can add some helper functions/methods in the DTO as well, to ease some processing.
It could be useful to declare a class like this:
public class YourClass{
private String one;
private String two;
private String three;
private String four;
public YourClass(String one, String two, String three, String four){
this.one = one;
this.two = two;
this.three = three;
this.four= four;
}
public void exampleOne() {
// do something
exampleTwo();
}
public void exampleTwo() {
// do something
exampleThree();
}
public void exampleThree() {
// do something
}
}
And use it:
YourClass c = new YourClass(one, two, three, four);
c.exampleOne();
There is nothing wrong in what you did but you can clarify things up using varargs (as TAsk stated) or by creating a small container class (like a c struct, often called bean) which represents a set of parameters.
This allows you to tidy things and make code more readable.
Please be aware that when creating a class you will introduce a little overhead due to a new allocation while this wasn't true with c-struct as it is the compiler which manage references to struct members.
Parameters are passed in stack like in c and there is no concept of by-reference-arguments in java, using a bean can overcome this limitation.
Well,Passing Argument is required when ever you want to call method with some attributes but for huge number of arguments of Same type you can use following.
You can use VarArgs instead.
public void Method(String.. str) {
//Here you will have Array str[](Of String)
if(str!=null)
for (String s: str)
System.out.println(s);//Iterate through Array for More Processing
}
If you want to Pass Other Argument as well
Method(int i, String... Other) {
//VarArgs Must be Last
}
NOTE:
Pass Arguments of Different type and Use conversion methods to convert String to Double,Int,etc.(well This is not recommended but can be done because you need to make sure at which place you have passed double,int etc.)

Change from String to Object Name Java

I have 3 ints named A, B, and C. These are to be multiplied with the number 52. I have a string that contains the name of which int I want to mulitply (in example below my string type == A;.
I want to know if there is anyway to make the name of the String change into the name of the object/int that I wish to use.
What I have right now:
public class MultiplySomeNumbers{
int A = 100;
int B = 200;
int C = 300;
String type = "A";
final int multiplied = 52;
public int multiply(String type){
return multiplied* ____ //What goes here?
}
}
I DON'T want to do anything like this:
public int multiply(String type){
if(type.equalsIgnoreCase("A"){
return multiplied*A;
}else if(type.equalsIgnoreCase("B"){
...
Any help would be greatly appreciated!
No, that is not possible (maybe with Reflection, but it's still a no-go). Every single situation where you think you might need this does not need it.
There are several issues, but here are a few:
No intellisense for those generated variables
Very unclear code
Ambiguous naming (what if you create a new variable that happens to have the same name as a generated one?)
etc etc etc
You will have to go with your second option.
We might be able to provide a different solution, but the question is rather unclear as it is right now. Perhaps you could expand a little so we can help you better.
Although there may be a way to do this with reflection, it's probably a really bad idea. If you really can't just pass in the value, but want to specify a limited set of constants by which you can multiply, I'd recommend creating an enumerated type.
Taking your same example, but using an enum instead of trying to look up constants by name, would look something like this:
public class MultiplySomeNumbers{
public enum Type {
A(100),
B(200),
C(300);
private final int value;
private Type(int value) {
this.value = value;
}
public final int getValue() {
return value;
}
}
Type type = Type.A;
final int multiplied = 52;
public int multiply(Type type){
return multiplied * type.getValue();
}
}
While there is nothing wrong with using an enum for this solution, it may not be the most flexible solution. Enums are, by design, effectively immutable ... they are intended to have the sense of constants. If you wish to change the value of a variable by multiplying its value by 52, then this is not possible with enums.
What I think you really should do is use a HashMap. A Map is a key / value pair.
The key is the "variable's name"; a String quantity
The value is the "variable's current value"; an Integer quantity (not int!)
Your Map can be declared like this:
Map<String, Integer> myVariables = new HashMap<String, Integer>();
then to load your variables into the map, you simply call the Map's put() method:
myVariables.put("A", Integer.valueOf(100));
myVariables.put("B", Integer.valueOf(200));
myVariables.put("C", Integer.valueOf(300));
Retrieving the value of a variable is as simple as using the get() method with your variable name as the key:
int val = myVariables.get("A").intValue();
Notice that I have chosen to box and unbox the primitive int values myself rather than rely on autoboxing. This is just a personal choice. It does trade off conciseness, but I'd rather see what's actually happening.
In my opinion, using reflection to determine a class field to access dynamically at run time is wholly unsatisfactory and should be avoided ... most especially since using the Java Collections API enables a statically typed, type safe solution that can be checked at compile time.
You can't check for a variable's name. For more information look here, there are some good answers:
Java Reflection: How to get the name of a variable?
But maybe a HashMap can help you, where you store "A", "B", "C" as keys and the respective numbers as value.
edit: Okay, maybe with something like this http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html it could be possible.

Is it a bad practice to use arrays as parameter(s) to return multiple values

I sometimes (actually, often) find myself using a one-element array to return multiple values from a method. Something like this:
public static int foo(int param1, int param2[], String param3[])
{
// method body
....
// set return values
param2[0] = <some value>;
param3[0] = <some value>;
return <some value>;
}
Is this a bad practice? (It seems like it is because some of my friends said they didn't know what it was doing for 2 seconds!)
But the reason I used this in the first place was because this looked closest to what is know as pass-by-reference in C++. And the practice wasn't discouraged in C++, so ...
But if this is really a wrong way of doing things, any idea how to rewrite this in the clean way?
Thanks
Create an object that contains the data you want to return.
Then you can return an instance of that object.
class FooData {
private int someInt;
private int anotherInt;
private String someString;
public FooData(int a, int b, String c) {
someInt = a;
anotherInt = b;
someString = c;
}
}
public FooData foo() {
// do stuff
FooData fd = new FooData(blah, blahh, blahhh);
return fd;
}
While I agree with the general opinion here that using arrays for such a purpose is bad practice, I'd like to add a few things.
Are you sure that "pass by reference" really is what you need in the first place?
Many have said that your code is bad style, but now let me tell you why that is IMHO.
"Pass by reference" is mostly a synonym for "programming by side effect" which is a thing you always want to avoid. It makes code much harder to debug and understand, and in a multi-threaded environment, the bad effects of this attitude really can hit you hard.
To write scalable and thread-safe code in Java, you should make objects "read-only" as much as possible, i.e. ideally, you create an object and initialize it at the same time, then use it with this unmodifiable state throughout your application. Logical changes to the state can almost always be considered a "creation" of new state, i.e. creation of a new instance initialized to a state then needed. Many modern scripting languages only let you work in this way, and it makes things much easier to understand.
As opposed to C++, Java is much more efficient in allocating and releasing short-lived objects, so there is actually nothing wrong with what others here have suggested: To create an instance of a special class to hold the function result, just for the purpose of returning the result. Even if you do that in a loop, the JVM will be smart enough to deal with that efficiently. Java will only allocate memory from the OS in very large chunks when needed, and will deal with object creation and release internally without the overhead involved in languages like C/C++. "Pass by reference" really doesn't help you very much in Java.
EDIT: I suggest you search this forum or the net for the terms "side-effect", "functional programming" or "immutability". This will most likely open a new perspective to your question.
I believe that it is bad practice to "return" values using one-element arrays that are parameters to your method.
Here's another SO question about this topic. In short, it's very bad for readability.
There is an easy workaround: Wrap all values that you wish to return in a class you define specifically for this purpose, and return an instance of that class.
return new ValueHolder(someValue1, someValue2, someValue3);
That's not very idiomatic java. There are usually better approaches to software design.
What you're really doing with the "one-element array" is creating a mutable object (since String is immutable, as are primitives like int) and passing it by reference. Modifying this mutable object is called a "side effect" of the method. In general, you should minimize mutability (Effective Java Item 15) and your methods should be side-effect free. There are a couple approaches here.
1. Split the method into two (or three) methods that all take the same params:
public static int foo1(int param1)
{
// method body
....
return <some value>;
}
Similarly, you might have
public static int foo2(int param1) { ... }
and
public static String foo3(int param1) { ... }.
2. Return a composite object.
public Container {
private final int originalReturn;
private final int param2;
private final String param3;
public Container(int originalReturn, int param2, String param3) {
this.originalReturn = originalReturn;
this.param2 = param2;
this.param3 = param3;
}
// getters
}
public static Container foo(int param1, int param2[], String param3[])
{
// method body
....
// set return values
return new Container(<some value>, <some value>, <some value>);
}
This is indeed bad practice if the values are unrelated. This is usually an indicator that you can split that function into two, with each returning one of the values.
EDIT:
I am assuming that you are returning two values calculated in the method in an array. Is this not the case?
e.g.
public int[] getStatistics(int[] nums)
{
//code
int[] returns = new int[2];
returns[0] = mean;
returns[1] = mode;
return returns;
}
The above function could be split into getMean() and getMode().
Passing variables by reference allows the function to "legally" change their value. See this article to clear up the confusion of when this is possible in Java, and when it's not...
This is bad practice if the values are of different type and different entities, e.g. name and address, etc. It is fine with create an array with same data type, e.g list of addresses.

Arrays of different types

Is it possible to have an array that contains two different types of data? I want to have an array that contains a double and also a string. I attempted:
ArrayList<double><String> array;
But that didn't work.
Sorry for the silly question, but it has been a while since I have used something like this.. Can you refresh my memory on how would I declare and populate such an array?
And then to take it a step further, I would like to sort the array by the double if possible?
Thanks!
Firstly, it's worth being clear about the difference between an array and an ArrayList - they're not the same thing at all.
However, in either case you can't do what you want. The closest you can probably come is declaring your own type. (EDIT: My original code had a double or a string... I've now changed it to be a double and a string. Let me know if this change isn't what you had in mind.)
public final class DoubleAndString
{
private final String stringValue;
private final double doubleValue;
public DoubleAndString(String stringValue, double doubleValue)
{
this.stringValue = stringValue;
this.doubleValue = doubleValue;
}
public String getString()
{
return stringValue;
}
public String getDouble()
{
return doubleValue;
}
}
Then create an ArrayList<DoubleAndString> or a DoubleAndString[].
Now, this feels somewhat vanilla at the moment - presumably the double and string values actually have a greater meaning - a name and a score, for example. If so, encapsulate that in a type which describes the pairing more appropriately.
As for ordering - you could make DoubleAndString implement Comparable<DoubleAndString> - but unless that's the only natural ordering which makes sense, I'd write a Comparator<DoubleAndString>:
public class DoubleComparator implements Comparator<DoubleAndString>
{
public int compare(DoubleAndString ds1, DoubleAndString ds2)
{
return Double.compare(ds1.getDouble(), ds2.getDouble());
}
}
Then you can use Collections.sort to sort an ArrayList<DoubleAndString> or Arrays.sort to sort an array.
You can use ArrayList<Object> and you can then use anything you'd like. Encapsulate the double in a Double object and when you retrieve the object use instanceof to check if it's really a double or a String.
I must say, it's unlikely this 'design' would win you any awards. Is it possible to rethink the solution you're considering for your problem, and see if you could do with a different kind of approach?
It sounds like you want a Map. Since you wish to sort the Map, a TreeMap may be optimal.
Map<Double, String> myMap = new TreeMap<Double, String>();
Maps are associative. Each double has an associated string. If you want multiple strings per double, you can use a
Map<Double, ArrayList<String>>
You might already know this, but it is not certainly not a good idea to store different types in a list. By definition an array is a collection of similar objects and stuffing all kinds in it makes things fuzzy. So really you would rather have a separate type to hold these different values.
Well, if you want to have an array with an arbitrary number of elements, then you simply need to use a type that is a common ancestor to both. In this case, that would be Object (since String and Double both inherit from Object). This will require you to check the types, though, when you retrieve or use them.
If you are using a fixed number of multiple different types, then what you really want is a "tuple". However, Java currently does not have an implementation of tuple available. For two items:
public class Pair<T1,T2>
{
public Pair(){
this(null,null);
}
public Pair(T1 x1){
this(x1,null);
}
public Pair(T1 x1, T2 x2){
_x1 = x1;
_x2 = x2;
}
public T1 getFirst(){
return _x1;
}
public T1 getSecond(){
return _x2;
}
private T1 _x1;
private T2 _x2;
}
You can just do ArrayList<object> arraylist and then you can put anything in it, but that may not be what you want.
Then, to sort you would just use your own comparator but, as theatrus mentioned, are these two values supposed to be connected, or do you have a single-dimension array with two different data types?
An ArrayList by definition only contains one object per position. You could do something like this:
List<MyTuple> list = new ArrayList<MyTuple>();
public static class MyTuple implements Comparable<MyTuple> {
private Double doubleValue;
private String stringValue;
//getters and setters
public int compareTo(MyTuple tuple) {
return doubleValue.compareTo(tuple.getDoubleValue());
}
}
You can then use the Collections.sort() method to sort it by the Doubles.
What do you want to do?
If it is not a key value mapping, you should create a new class for this.
You may want to look at the Number base class.
List<Number> list = new ArrayList<Number>();
list.add(new Integer(3));
list.add(new Double(5.2));
You may interpret the numbers as strings, using NumberFormat:
NumberFormat formatter = new DecimalFormat("#.##");
String s = formatter.format(list.get(0));
Though this may not be what you want, you are a bit short on details about your end goal.
if you are basically not trying to do any comparisons/sorting on the ArrayList then you could create something as below:
List list = new ArrayList();
otherwise.. Jon Skeet's answer was best approach.

How to handle numbers in a generic fashion?

My question is eerily similar to "Writing a generic class to handle built-in types" including being inspired by the fact of working on a class to handle operations on matrices.
Although that question was asked using C# and pointed to an article on Generic Operators.
I don't get it. Java Number does not have an add method so you can have a method like:
public Number myAdd(Number a, Number b){
return a.add(b);
}
So how do you handle a case where you want to be able to handle multiple types of Numbers in Java?
The fundamental problem is with the Java type system which is very primitive.
Since there is no notion of a sealed set of types in Java (nor is it possible for Java to infer the types like Haskell does) there is no way to make make a general Number + Number -> Number without trickery.
For primitives (and those objects like Integer which can be automagically mapped to them) types promotion and the + operation is part of the language. (And this is actual part of the problem: what should Number a + Number b return where a and b are of different types?)
If you really want this behavior you'll have to find (or create) your own custom class that either uses reflection or a series (of checks and) casts and such. Even if you use generics (remember that generics are type-erased) casting will need to be done.
I imagine these problems are part of the reason why Number is as bland as it is.
How good do you want the result to be? If the answer is "good enough, mostly", then this should be sufficent:
public Number myAdd(Number a, Number b){
return a.doubleValue() + b.doubleValue();
}
But if you want something that, say, matches the promotion semantics of Java primitives, you're probably going to have to write it yourself. And then you'll have to figure out what the rules are for all combinations of "non-standard" Number implementations, including BigDecimal, BigInteger, AtomicDouble, AtomicLong, everything in org.apache.commons.lang.mutable, and any random implementation that somebody might decide to write next Tuesday.
It's not clear what the right thing to do is in most of these cases -- converting everything to BigDecimal, for instance, is not an option if one of the arguments is Apache Commons' Fraction.ONE_THIRD; and besides, doing the conversion in a general way presents the same problems as doing the addition in a general way. But having an add() method on Number would require every Number implementation to handle all these cases -- and that's probably why it isn't there.
I don't get it. Java Number does not
have an add method ...
Suppose that java.lang.Number did have an add method or methods, how would you define its signature? How would you define its semantics? How would you deal with "mixed mode" arithmetic?
While it is no doubt possible to answer these questions and design an API, the result is likely to be tricky to use correctly. In addition, it is most unusual for an application to need to perform "representation agnostic" arithmetic. Usually you want / need explicit control over the way that arithmetic is performed and conversions happen. (The Java primitive type promotion rules are already difficult enough for people to get their heads around!!)
All in all, I think that Sun have done us a good service by not trying to support arithmetic in the Number API.
One way of implementing a generic add method is to let the left hand argument infer the return type.
package mixins;
import java.math.BigDecimal;
public class Numbers {
public static boolean isZ(Number n) {
return n instanceof Integer || n instanceof Long || n instanceof Short || n instanceof Byte;
}
public static boolean isR(Number n) {
return n instanceof Double || n instanceof Float;
}
public static BigDecimal add(BigDecimal a, Number b) {
if (b instanceof BigDecimal) {
return a.add((BigDecimal) b);
} else if (isZ(b)) {
return a.add(new BigDecimal(b.longValue()));
} else if (isR(b)) {
return a.add(new BigDecimal(b.doubleValue()));
}
throw new IllegalArgumentException("No valid big decimal translation for " + b.getClass());
}
public static Integer add(Integer a, Number b) {
return a + b.intValue();
}
public static Long add(Long a, Number b) {
return a + b.longValue();
}
public static Float add(Float a, Number b) {
return a + b.floatValue();
}
public static Double add(Double a, Number b) {
return a + b.doubleValue();
}
}
If this is implemented as static methods, you can use static imports.
import static mixins.Numbers.*;
public class Example {
public static void main(String[] args) {
BigDecimal fortytwo = new BigDecimal(42);
BigDecimal fiftyfive = add(fortytwo, 13);
System.out.println(fiftyfive);
}
}
You cannot add any two numbers, for the reasons other pointed out, but you can add numbers of same type, and the result will also be that same type.
You can create generic arithmetics in Java, with something like this:
interface Arithmetics<T> {
T add(T val1, T val2);
}
class IntegerArithmetics implements Arithmetics<Integer> {
Integer add(Integer val1, Integer val2) { return val1 + val2; }
}
//similarly DoubleArithmetics, BigIntegerArithmetics, ...
Generic Java Math library does exactly that for you.
Actually, I've been working on a generic "real" number class (called 'Value') for a while now, but more as a design exercise than anything; and I can see why it hasn't been done sooner.
First off, you have to have to have some basic rules to work by - I chose to use Java FP (IEEE-754) rules - which means you have have to allow for results like 'infinity' and 'NaN', even if the type doesn't actually support them; and things like reciprocals have proved surprisingly tricky. But I'm getting there, and it's been a fun journey.
One thing that helped me was deciding early on that I needed to deal with "identity" values - specifically 0, 1, and -1, along with -0, +/-infinity and NaN as special cases; the reason being that (for example) multiplication by any of them usually doesn't need any calculation at all.
x * 1 = x, x * NaN = NaN, x * 0 = 0 (or NaN), and x * +/-infinity = +/-infinity; and there are similar rules for division, addition and subtraction, which means you can eliminate a lot of dross quickly and consistently.
And that leaves implementers to only have to deal with cases that do need calculation.
Of course, not all types will support all identities, but if you make them methods, you can just throw an exception when either an operand or a result is "unsupported".
Hope it helps anyone else interested in giving it a bash, but it's not as simple it looks. :-)
Personally, I use BigDecimals for almost everything (but that is mainly because I work with currency values). They handle all numeric values of any size. Because of that, in my opinion they are a generic value and could be used as such in your hypothetical example instead of the Number abstract class. Everything can be turned into a BigDecimal, why not use it?
public BigDecimal myAdd(BigDecimal a, BigDecimal b) {
return a.add(b);
}
EDIT: To address BigBrothers comment below, you could always use the doubleValue() method to create your own generic method. The only problem with this is that you may lose precision in some rare cases where someone IS passing in a BigDecimal and it is larger than a Double.maxValue
public Number myAdd(Number a, Number b) {
return new BigDecimal(a.doubleValue() + b.doubleValue());
}
A BigDecimal is a Number, so returning one is of no consequence.

Categories

Resources