I don't think we can instantiate an Enum. So do we need to have toString(), equals() and hashCode() method for an enum? Is this statement true?
Also as a follow up question
What does "this" keyword refers to in the following enum class?
public enum DocuType {
text, print, html, pdf; //Why aren't these in caps?
public boolean isPrint() {return this == print; } //What does this refers to?
public boolean isText() {return this == text; }
public boolean isTextOrPrint() { return isText() || isPrint(); }
}
How do I call any of the boolean methods of this enum as they are not static?
Also when I call, what does the keyword "this" refers to ?
I don't think we can instantiate an Enum.
Enum is one of type as we have class type. The way we can create instance (i.e. create variable) of a class, similarly we can create variables of Enum but that's only during during its definition which eventually makes them a Constant.
So do we need to have toString(), equals() and hashCode() method for an enum?
equals() & hashcode() are used to compare two instances. In case of class instances, the instances are created dynamically. So this means we don't have knowledge about instances beforehand and hence we need to compare them to know if they are equal. However, in case of Enum we know the instances when we define the Enum. So, we know beforehand whether they are equal or not. If the enum instances mean to be equal why on the earth we need two separate equal enum instances. So, in case of enum we generally don't override these methods.
What does "this" keyword refers to in the following enum class?
&
How do I call any of the boolean methods of this enum as they are not static?
&
Also when I call, what does the keyword "this" refers to ?
this means an instance currently in access. In your example, you have DocuType instances as text, pdf, print, html. When you invoke a method on any of the instance, ex: DocuType.text.isPrint(), this keyword inside the isPrint method will point to text. So, for instance pdf, all the methods will return false except isPdf().
So do we need to have toString(), equals() and hashCode() method for an enum? Is this statement true?
You don't need any of these methods in the enum.
Also as a follow up question What does "this" keyword refers to in the following enum class?
Imagine you have this code:
DocuType myType = DocuType.print;
If you want to check if the document is a PRINT document, you can do this:
boolean isPrint = myType.isPrint();
In this case, this is the myType, which means that it's the print enum. In the end, the result is true, because print == print;
I would also suggest to read the Tutorial to Enums
It seems you lack the knowledge of the concept of an enum.
And to your last question, an enum is static, but each "type" of it is an object, meaning you can do
DocuType.html.isText(); // false
DocuType.print.isPrint(); // true
To initalize your own Enum you have to
DocuType TextDocu = DocuType.text;
And you can write them in CAPS, but you don't have to, but it's recommened.
To explain it more in detail:
enum DocuType //this is an enum and not instantiatable
text,print,html,pdf // these are Objects with the functions of the enum and are an instance
As preparation for an explanation, a quick glance back in history.
Before enums were available in Java, a possible replacement could have been constructed like that:
public class DocuType {
public final static DocuType text=new DocuType();
public final static DocuType print=new DocuType();
public final static DocuType html=new DocuType();
public final static DocuType pdf=new DocuType();
private DocuType(){}; // hide constructor
public boolean isPrint() {return this == print; }
public boolean isText() {return this == text; }
public boolean isTextOrPrint() { return isText() || isPrint(); }
}
As you can see, while you cannot create new instances of DocuType, 4 static instances of them are already prepared for you in the Class.
Javas enum work very similar to that example (less writing involved, obviously); therefore, this refers to the instance you execute the method on. Regarding toString, it's up to you; the default implementation can be good enough or not. There is no need to implement neither equals nor hashCode.
Related
I have one Enum like Below
public enum Game {
CRICKET("cricket"),
FOOTBALL("football"),
VOLLEYBALL("volleyball")'
private String val;
private Game(String val) {
this.val = val;
}
public String getValue() {
return this.val;
}
}
In here, Do I want to overide the equal(),hashCode(),toString() methods
based on this What issues should be considered when overriding equals and hashCode in Java?
Question is meaningless, because you cannot override equal() and hashCode() of an enum.
That is because they are defined as final in the Enum class, which implicitly is the base class of all enum types.
No, enum is not a regular class (and as Andreas pointed out, they're final methods). For example, you don't need to use equals() to compare them, as there is a single instance of each enum value. This allows you to use == instead.
if(gameType == Game.CRICKET)
You can override toString(), as by default it prints the same as name(), which is just the name of the enum (e.g. FOOTBALL).
My first question is why you would need the enum to contain a String in the first place. The point of your enum already looks like it is to differentiate each type of game within a certain list of possible games. So the enum itself here functions as a constant value. For example you could do:
public void playGame( Game myGame ){
switch(myGame){
case FOOTBALL:
playFootball();
break;
case CRICKET:
playCricket();
break;
// and so on but you get the point
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
This question may seem dumb at first, but after having worked with different person, I see everyone seems to have their own, different knowledge about it, so here's my question.
So now I'm wondering what is the best way to do it, and why ("why" is more important for me):
I'm wondering about two methods to write Java code:
Do you always pass Object or can you pass primitive data type ?
Do you call variables using this.name, name or getName() inside your class instance ?
public class MyClass {
private String someStr;
private int someNumber;
private Integer someOtherNumber; // int, Integer ? which one to choose ?
public MyClass(String someStr, int someNumber, int someOtherNumber) { // int someNumber ? Integer someNumber ? why ?
this.someStr = someStr; // Here, it's clearly this.{name} = {name} because of the variable name conflict
this.someNumber = someNumber;
this.someOtherNumber = someOtherNumber;
}
public int someMethod(boolean first) { // Boolean ? boolean ?
if (first) {
return someNumber;
} else {
return this.someOtherNumber; // this.{name} ? just {name} or even this.get{name}() or get{name}() ? (supposing getters exists)
}
}
}
I hope someone will provide me with a great explanation about which to use in order for me to write better code.
Do you always pass Object or can you pass primitive data type ?
You can't pass an Object, only a reference to an Object. You can pass primitive data.
Do you call variables using this.name, name or getName() inside your class instance ?
I don't make it more complicated than I need to, unless it's conflicts with a local variable or my getName() does something special, but that is a matter of style.
Do you always pass Object or can you pass primitive data type ?
You can pass primitives or references to objects depending on your need.
Do you call variables using this.name, name or getName() inside your
class instance ?
this is used to refer to the current object. If there are conflicting variable names and you want to distinguish between the object variable and local variable then use this.
Also you seems to be confused about primitives and Wrapper classes. Wrapper classes provides utilities methods and are of use especially working with collections.
If you need to work with the primitive data types then you should use them, e.g., int, double, char, float, etc. The only exception is String which in Java is a special class that represents a char array and also holds instance methods.
The case with Integer vs int, is when you need to use Integer methods (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html). But if you only need a data type to hold your value then choose int.
Do you always pass Object or can you pass primitive data type ?
public int someMethod(boolean first) { // Boolean ? boolean ?
}
In the following example, you can pass boolean and Boolean with the same success. In Java this is called Autoboxing.
N.B. Be careful, because when passing an object it may be null!
Do you call variables using this.name, name or getName() inside your
class instance ?
Depends. If name is an class member variable, you can access it with name if there isn't any other variable in the current scope that has the same name. In this case you should use this.name to point exactly to the class member variable. getName() may be used, as well. It's just a matter of style.
I keep it simple. I'm using name, but if I have a local variable with the same name I must use this.name (my prefered solution) over getName().
getName() must be used if it do some logic like validation.
Do you always pass Object or can you pass primitive data type ?
It depends on your application and your needs. If you pass a reference to an object, you are able to use the methods of the related type which may be more secure and portable. Let say you are using the class Double. Double has many peer-reviewed and tested methods which may be helpful to you.If you prefer to use primitive type, double, you need to be careful in your manipulations like comparing, validating etc.
For performance issue, you may check a previous discussion below:
Why do people still use primitive types in Java?
Do you call variables using this.name, name or getName() inside your class instance ?
I prefer using this when I refer a class member because i think it will be helpful for others reading my code to understand that the variable is a class member.
Finally, whatever style you prefer, I think you should stick to it in your applications.
Do you call variables using this.name, name or getName() inside your class instance ?
It is mostly a matter of personal style and principle.
private int someOtherNumber; I almost always use int because it seems more natural to me --perhaps influenced by the C days. And, from performance and memory usage point of view using int is a better choice. As a rule of thumb, I don't use objects for primitives unless I have a good reason to.
return this.getSomeOtherNumber(); I prefer using getters/setters; since sometimes -not always- the getter method is not just a simple return statement, rather it encapsulates some logic. As a result, I don't directly access class attributes (like this.someAttr or someClass.somePublicAttr) unless it's a final attribute. Believe me, it's much safer.
Continuing 2: It may seem a bit strange but I, having a strong Lisp background, try to avoid using even getter/setter methods (class state) as much as possible and instead explicity pass the required parameters and use the methods' return values. Consider the following example:
public class C {
private int a;
private int b;
public int getA() { return a; }
public void setA(int a) { this.a = a; }
public int getB() { return a; }
public void setB(int b) { this.b = b; }
// Usual style
public void someMethod1(int x) {
mainLogic1(x);
}
private void mainLogic1(int x) {
b = a + x;
}
// My preferred style
public void someMethod2(int x) {
setB(mainLogic2(x, getA()));
}
private int mainLogic2(int x, int a) {
return x + a;
}
}
As you can see, someMethod1 and mainLogic1 both have side effects which are hard to detect when looking at the code. On the other hand mainLogic2 doesn't have a side effect at all and someMethod2 side effect is easier to spot by just looking. This may seem like overkill, but it has made my Java code more readable, more testable and easier to refactor as it consists of large number of small methods with no side effects.
System.out.println(this);
Why would you use 'this' in the brackets? Is it for printing the references? Or as in the code below for comparing if the object points to the same reference?
public void compareDrzewo(Drzewo tree)
{ if (tree == this)
{ System.out.println("true"); }
else { System.out.println("false"); }
main method code
Drzewo name1 = name2;
name1.compareDrzewo(name2);
The other examples of the use of 'this.' are quite straight forward (inner class etc.) Please comment only on this or similar use.
That instance has a toString() method associated with it, which means it will invoke it to print out meaningful information, or it uses Object's toString() (meaning it'll print out a memory location, which is much less useful).
System.out.println(this)
is the same as
System.out.println(this.toString());
So if the class of which this is an instance overrides the toString method, that line of code would be meaningful.
You use this to refer to the current object.
One example is when your want to refer to the current instance of your class, so if you need to call a method with your class, for example something.equals(this) or something == this.
Another example is explicitly specifiying a class instance of a variable rather than a local instance, for example a setter:
public void setMyVar(String myVar) {
this.myVar = myVar;
}
So myVar is the variable declared in the method, this.myVar is the variable declared in your class.
If I do the following
myObject.myMethod(myClass.getComparator());
with
public void myMethod(Comparator<? super myOtherObject> comparator) {
if (comparator.equals(myClass.getComparator()) {
//do sth
}
}
and in myClass
static Comparator<ListItem> getComparator() {
return new Comparator<myOtherObject>() {
public int compare(myOtherObjectitem1, myOtherObjectitem2) {
return (Integer.valueOf(myOtherObject.getRating()).compareTo(Integer.valueOf(myOtherObject.getRating())));
}
};
}
then "//do sth" is not gonna be executed. So the objects I get from getComparator the two times are different. How can that be? Is there a chance to see, which comparator "myMethod" gets?
You're calling the equals method on this line:
if (comparator.equals(myClass.getComparator())
Since you haven't defined this method explicitly on your Comparator class (which is an anonymous inner class), this defaults to the version inherited from Object - which considers two references equal only if they are the exact same object.
And your getComparator() method states return new Comparator() { ... }, so it's calling the constructor and creating a new object each time it's called. Thus the result of one call to getComparator will be a distinct object, and hence will not be considered equal to, the result of another call.
I can think of two possible ways to change your code so that the equality test returns true:
Create the comparator only once, and return this same object from
getComparator. This would involve a change somewhat like the
following in myClass:
private static Comparator<ListItem> cmp = new Comparator<myOtherObject>() {
public int compare(myOtherObjectitem1, myOtherObjectitem2) {
return (Integer.valueOf(myOtherObject.getRating()).compareTo(Integer.valueOf(myOtherObject.getRating())));
}
};
static Comparator<ListItem> getComparator() {
return cmp;
}
Provide an explicit equals() implementation (and thus a hashCode() one too, ideally). You can then control exactly which objects are considered equal to one of your comparators. This might be much easier if you define a concrete class for your comparator rather than it being an anonymous inner class.
At the end of the day, though, I fear your approach might not be right. What does it mean for two comparators to be equal to one another? I feel this is an ambiguous concept for anything other than data classes, and I would be hesitant to use the Object.equals method for this.
(For example, if by equality you mean "they will sort lists in the same order", then I'd add a method to your comparator class called isEquivalentSortOrder or something similar. This way you can specify exactly what you mean without having to rely on the woolly definition of "being the same".)
Why not to create inside myClass static variable of Comparator like:
class myClass{
public static Comparator<ListItem> = new Comparator<myOtherObject>() {
public int compare(myOtherObjectitem1, myOtherObjectitem2) {
...
}
};
}
I'm going through a book on data structures. Currently I'm on graphs, and the below code is for the vertex part of the graph.
class Vertex<E>{
//bunch of methods
public boolean equals(Object o){
//some code
}
}
When I try to implement this equals method my compiler complains about not checking the type of the parameter and just allowing any object to be sent it. It also does seem a bit strange to me why that parameter shouldn't be a Vertex instead of an Object. Is there a reason why the author does this or is this some mistake or antiquated example?
#Override
public boolean equals(Object obj)
{
if (!(obj instanceof Vertex)) return false;
else return // blah blah
}
equals(Object) is the method defined in the root - Object. If you don't match the signature exactly, Object's version will be called when someone checks if two objects are equal. Not what you want.
You've probably seen other methods (like Comparator) where you can use the exact time. That's because those APIs were generic-ified with Java 5. Equals can't be because it is valid to call equals with two separate types. It should return false, but it is valid.
equals is a method inherited from Object, is defined to be flexible enough so that you can take any object and test if it is equal to any other object (as it rightfully should be able to do), so how could it be any other way?
Edit 1
Comment from jhlu87:
so is it not good form to write an equals method that has an input parameter of vertex?
You are welcome to create your own overload to any method, including equals, but doing so without changing the name could risk confusing many who would assume that your equals is the one that inherits from Object. If it were my code and I wanted a more specific equals method, I'd name it slightly different from just "equals" just to avoid confusion.
If your method doesn't take an argument of type Object, it isn't overriding the default version of equals but rather overloading it. When this happens, both versions exist and Java decides which one to use based on the variable type (not the actual object type) of the argument. Thus, this program:
public class Thing {
private int x;
public Thing(int x) {
this.x = x;
}
public boolean equals(Thing that) {
return this.x == that.x;
}
public static void main(String[] args) {
Thing a = new Thing(1);
Thing b = new Thing(1);
Object c = new Thing(1);
System.out.println(a.equals(b));
System.out.println(a.equals(c));
}
}
confusingly prints true for the first comparison (because b is of type Thing) and false for the second (because c is of type Object, even though it happens to contain a Thing).
It's because this method existed before generics, so for backward compatabitity it has to stay this way.
The standard workaround to impose type is:
return obj instanceof MyClass && <some condition>;
It is because the author is overriding equals. Equals is specified in java.lang.Object and is something that all classes inherrits from.
See the javadoc for java.lang.Object