I am learning Enums in java I like to know what are the major differences of Enum in java and C++.
Thanks
In c++ an enum is just a list of integer values.
In java an enum is a class which extends Enum and is more a nice way to write:
class MyEnum extends Enum<MyEnum>
{
public final static MyEnum VE01 = new MyEnum();
public final static MyEnum VE02 = new MyEnum();
}
as enum:
enum MyEnum
{
VE01,VE02;
}
For the Methods of enum see this.
Since a java enum is an object it supports everything a normal java object does.
as giving them values or functions:
enum Binary{
ZERO(0),ONE(1);
Binary(int i)
{
value = i;
}
public final int value;
}
a nice one is anonymous classes:
enum State{
StateA{
public State doSomething()
{
//state code here
return StateB;
}
},
StateB{
public State doSomething()
{
return StateA;
}
};
public abstract State doSomething();
}
In C++, an enumeration is just a set of named, integral constants. In Java, an enumeration is more like a named instance of a class. You have the ability to customize the members available on the enumeration.
Also, C++ will implicitly convert enum values to their integral equivalent, whereas the conversion must be explicit in Java.
More information available on Wikipedia.
Enums in C/C++ are plain Integers.
Enums in Java are objects - they can have methods (with different behavior from one enum instance to the other). Moreoever, the enum class supplies methods which allows iteration over all enum instances and lookup of an enum instance.
C++:
typedef enum { Red, Yellow, Green } Colors;
void canCrossIntersection(Colors c) {
return c == Green;
}
Java:
public enum Colors {
RED(false),
Yellow(false),
Green(true)
;
Color(boolean b) { this.b = b; }
private boolean b;
public boolean canCrossIntersection() { return b; }
}
In Java you can even emulated extensible enums by letting them implement the same interface and then add all of their values to some sort of collection by calling their values() method.
For a semi-answer... C++0x Strongly Typed Enums bring many of the benefits of Java Enums to C++: strong typing, scope and so forth. If your compiler supports C++0x Strongly Typed Enums, you should consider using them.
Reference:
http://www2.research.att.com/~bs/C++0xFAQ.html#enum
A great feature of Java Enums which lacks in C++ is the name() method. This way you can get the Enum value name (as written in the enum definition) without any extra line of code in definition. For example:
enum Type {T1, T2, T3}
Type t = Type.T1;
System.out.println(t.name()); // prints T1
Related
Is it possible to write an equivalent code in Java for the following swift code? In fact, I want to know if it's possible to have a case of functions inside Java's enum (X, Y in MyEnum)
enum MyEnum{
case X((Int) -> String)
case Y((Double) -> Int)
}
No, you can't; at least, not if you want the differing types to be available when you use the enum. All enum values have to have the same type.
When you want "enum" values to have heterogenous types, you could use a class with static final fields:
final class MyHeterogeneousEnum {
private MyHeterogeneousEnum() {} // Not instantiable.
static final Function<Integer, String> X = ...;
static final Function<Double, Integer> Y = ...;
}
which allows you to use the values with their full type information:
String s = MyHeterogeneousEnum.X.apply(123);
Integer i = MyHeterogeneousEnum.Y.apply(999.0);
Of course, you don't have useful methods like name(), or values() to iterate over the constants in this class, nor is it inherently serializable. You can make implement these yourself - but for values() you have to use wildcards in the return type, in order that all values can be returned:
static Iterable<Function<?, ?>> values() {
return Collections.unmodifiableList(Arrays.asList(X, Y));
}
However, note that a Function with a wildcard input type parameter is pretty much useless: you can't actually pass anything into it (other than null); so the values() method has limited utility.
It is possible (technically), but it might not be that useful, as creating a simple class, that consumes a Function instance.
As you might already know, in Java, the enums represent one or more constants of the same type, which could have their own properties - this include java.util.Function instances. However, these Function instances cannot be passed dynamically at Runtime, but should be rather set at compile time, so that the constant is created.
Of course, you could make each enum constant have a different typed Function, by just creating the enum's constructor Generic:
enum MyEnum {
X((String x) -> "Hello"), Y((Double d) -> 1);
Function<?, ?> function;
MyEnum(Function<?, ?> function) {
this.function = function;
}
}
This, however, is not quite useful (although it compiles just fine). The Function in X doesn't use it's String parameter and returns a fixed value. So does the one in Y.
I'd rather introduce two separate instances of the same class:
class Instance<T, U> {
private Function<T, U> function;
public Instance(Function<T, U> function) {
this.function = function;
}
}
This will allow you to dynamically pass a Function instance, instead of setting it at compile-time.
Yes for sure you can, in java enums can be more that just constants... every one of it values can be an anonymous class (take a look to TimeUnit.class for example)
now, you can do somthing like:
interface IFunction {
double getY(double x);
}
enum Function implements IFunction {
LINE {
#Override
public double getY(double x) {
return x;
}
},
SINE {
#Override
public double getY(double x) {
return Math.sin(x);
}
}
}
and then the implementation
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(Function.LINE.getY(i));
System.out.println(Function.SINE.getY(i));
}
}
I finally have a reason to implement an enum in Java and and find it to be an invalid type in 1.6. So I declare the enum as
public enum MyEnum = {A=0, B=1, C=3};
and get an error invalid type in Eclipse.
That's not how they are used. See examples at http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html, such as
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
Java enums are much more powerful than in, say, C#. They're (almost) full-blown objects, and thus cannot be represented with just a number. They can however contain a number, and they do have an ordinal number value.
You could have the number value with
public enum MyEnum {
A(0), B(1), C(3);
private final int number;
MyEnum(int number) {
this.number = number;
}
}
Java enums are quite different to C and C++ enums. The biggest difference is that the enum constants are full-blown objects rather than compile-time integer constants.
In your example, A, B and C are objects. Therefore constructs like A=0, B=1, C=3 are not allowed.
I recommend taking a look at the tutorial.
If you have to associate numeric values with enum constants, you can achieve a similar effect like so:
public enum MyEnum {
A(0), B(1), C(3);
public final int val;
private MyEnum(int val) {
this.val = val;
}
}
Having done this, you can access the values using MyEnum.A.val etc.
In Java, enum is a type, but it is incompatible with integers. Enum objects are closer to classes than to primitives, in that they can have methods, member variables, and so on.
Java lets you get the effect that you wanted by adding an int member to your enumeration, and initializing it differently for different enumeration members, like this:
public enum MyEnum {
A(1), B(2), C(3);
int val;
private MyEnum (int v) {
val = v;
}
public int value() {
return val;
}
};
Now each member of your enum has a public method value() that returns the integer value associated with the corresponding element of the enumeration.
you can't do this as you do. enum define in java in the following way
enum myenum{a,b,c,d}
public enum ModuleType {A,B,C}
To answer your question: enum is technically not a type. Therefore you cannot define a variable of type enum as you have tried.
enum is a keyword to define an enumerated (abbreviated to enum) type which is a special data type.
Once an enum type is defined (very much like how you would define a class), you refer to it using the name of the enum type. Please check the enum types documentation.
enum icecream {
vanilla(100), strawberry(20);
int price;
icecream(int i) {
price = i;
}
}
I am a little confused as to how the enum objects are created during compilation time
I saw some examples where they mentioned it like this
public enum Flavor
{
COFFEE, VANILLA, CHOCOLATE, STRAWBERRY, RUM_RAISIN, PEACH
}
This gets translated into(during compilation)
public final class Flavor
extends java.lang.Enum
{
public static final Flavor COFFEE = new Flavor("COFFEE", 0);
public static final Flavor VANILLA = new Flavor("VANILLA", 1);
// ...
}
Link: http://www.kdgregory.com/index.php?page=java.enum
But how are the objects created when I pass a value along with the name cause to me they just look like method calls. E.x. vanilla(100) here for vanilla the price is 100 but how does it actually gets created? I am not getting it at all. Please help :(
the vanilla(100), strawberry(20) is just a java5+ notation. It gets translated during the compilation to proper object creation code:
public static final icecream vanilla = new icecream(100);
public static final icecream strawberry = new icecream(20);
BTW, java type should be CamelCased, so, icecream should be named IceCream.
Enums are read by the java compiler as constants, but ultimately, they are implemented like any other objects (that is, they are not special types, like ints/floats/arrays, but rather, a syntactic wrapper over a pure object-oriented language feature). Thus, enums have constructors which you can override, so that your static enums have more than just a name. This can be very useful, for example, if you want your enumerated values to have multiple fields.
For example, I may have an Animal enum, where each animal has a name, as well as a number of legs :
public enum Animal{
Dog(4), Baboon(2);
public int legs;
private Animal(int legs) {
legs=legs;
}
}
However, in the absence of such overriding, the compiler generate default enumeration objects, which is essentially what you have pasted.
How can I cast a value from Enum1 to Enum 2 in Java?
Here is an example of what I'm trying to do :
public enum Enum1 {
ONE,
TWO,
THREE;
}
public enum Enum2 {
FOUR,
FIVE,
SIX;
}
So I want to do something like this:
Enum2 en2 = (Enum2)ONE;
Is it possible and how can I do that?
Thanks in advance!
You cannot cast from one enum to another, however each enum has guaranteed order, and you can easily translate one enum to another (preserving order). For example:
enum E1 {
ONE, TWO, THREE,
}
enum E2 {
ALPHA, BETA, GAMMA,
}
we can translate E1.TWO to/from E2.BETA by:
static E2 E1toE2(E1 value) {
return E2.values()[value.ordinal()];
}
static E1 E2toE1(E2 value) {
return E1.values()[value.ordinal()];
}
The answer depends on what the "casting" should do...
Casting by ordinal position
In the provided example, there is no commonality between the two sets of enum values so I'm assuming the intention was to translate by ordinal position so Enum1.ONE => Enum2.FOUR, Enum1.TWO => Enum2.FIVE and Enum1.THREE => Enum2.SIX. This can be done as follows:
Enum2 en2 = Enum2.values()[Enum1.ONE.ordinal()];
A natural follow-on question is how this can be extended to a generic function that does the same for any two enum types. Not for the faint hearted but this does the job - it requires the Google Guava library:
public <F extends Enum<F>> F castByOrdinal(Enum<?> e, Class<F> fClass) {
return Iterators.get(EnumSet.allOf(fClass).iterator(), e.ordinal());
}
If Guava isn't being used, it can be done manually in a few more lines of code:
public <F extends Enum<F>> F castByOrdinal(final Enum<?> e, final Class<F> fClass){
final Iterator<F> iter = EnumSet.allOf(fClass).iterator();
int count = 0;
F fValue = null;
while (count <= e.ordinal()) {
if (!iter.hasNext()) {
return null; // ...Or throw an exception e.g. IndexOutOfBoundsException
}
fValue = iter.next();
count++;
}
return fValue;
}
Example usage:
Enum2 en2 = castByOrdinal(Enum1.ONE, Enum2.class);
Casting by shared enum value names
There is another possible way of casting between enums that share some of the same value names.
E.g:
enum Shape {
TRIANGLE, SQUARE, PENTAGON, HEXAGON, UNKNOWN, NOT_APPLICABLE
}
enum Size {
SMALL, MEDIUM, LARGE, UNKNOWN, NOT_APPLICABLE
}
The casting will only work for common values (i.e. UNKNOWN and NOT_APPLICABLE above) and can be done as follows:
Size size = Size.valueOf(Shape.UNKNOWN.name());
This will throw an IllegalArgumentException if the value name does not exist in the target enum. The generic method for this casting is a bit simpler:
public <F extends Enum<F>> F castByName(final Enum<?> e, final Class<F> fClass) {
return F.valueOf(fClass, e.name());
}
Example usage:
Size size = castByName(Shape.UNKNOWN, Size.class);
You can define a method in Enum1 to return the corresponding Enum2:
enum Enum1 {
ONE {
#Override
public Enum2 toEnum2() {
return Enum2.ALFA;
}
},
TWO {
#Override
public Enum2 toEnum2() {
return Enum2.BETA;
}
}
,
THREE {
#Override
public Enum2 toEnum2() {
return Enum2.GAMMA;
}
}
;
public abstract Enum2 toEnum2();
}
enum Enum2 {
ALFA, BETA, GAMMA;
}
or, a bit more readable (IMO):
enum Enum1 {
ONE(Enum2.ALFA),
TWO(Enum2.BETA),
THREE(Enum2.GAMMA);
private final Enum2 enum2;
private Enum1(Enum2 enum2) {
this.enum2 = enum2;
}
public Enum2 toEnum2() {
return enum2;
}
}
enum Enum2 {
ALFA, BETA, GAMMA;
}
EDIT:
if you need to maintain the 2 enums decoupled, create a map containing the mapping from Enum1 to Enum2 (in a 3rd utility class).
It's not possible. Enum1 and Enum2 are different types with nothing in common.
Even though this ticket was active quite a while ago I'm adding another possibility:
You could also create a Map e.g. like this:
HashMap<Enum1, Enum2> e1ToE2 = new HashMap<Enum1, Enum2>();
e1ToE2.put(Enum1.ONE, Enum2.FOUR);
e1ToE2.put(Enum1.TWO, Enum2.FIVE);
usage
Enum2 e2 = e1ToE2.get(Enum1.ONE);
(+) you dont have to double check the order of your elements
(+) easy to read
(+) fast
(-) requires space
Correct me if I'm wrong :)
You can't do that, because they're objects of different classes.
You could convert from one to the other based on ordinal value or name, but I'd question the design of any program that needed to do that.
You can't ; but you can create a static method in your enums, with a translation code. But you must have a clear idea of the rules you want to implement.
A cast operation is not possible, but you can write a static member function for enum1 that casts enum2 to enum1:
public static Enum1 fromEnum2(Enum2 enum2) {
...
}
By the way, you can assign an ID to every constant of both enums which simplifies the implementation.
Here is a tutorial on enums.
It probably won't help you, but you can have
public enum Enum1 implements MyInterface {...}
public enum Enum2 implements MyInterface {...}
We don't have enough information about what you are trying to do to help you.
It makes no sense as it is to cast an enum to another enum.
You cannot cast from one enum to another, however each enum has guaranteed order, and you can easily translate one enum to another
Are there any objects created respective to each of the enum constants ARROGANT, RASCAL, IDIOT?
public enum Manager {
ARROGANT,
RASCAL,
IDIOT
}
and if the following code does the same as the above, explicitly though,
public enum Manager {
ARROGANT(),
RASCAL(),
IDIOT();
Manager() {}
}
Yes, exactly one instance will be created for each enum constant.
And yes, the second sample code is effectively identical.
Yes, both should result in the same bytecode, the first is only syntactic sugar.
The second is useful when you have to associate values with an enum.
enum Numbers{
ONE(1),TWO(2),THREE(3),TEN(10);
Numbers(int i){
value = i;
}
public final int value;
}