Java method arguments: type declaration in parentheses?

81 Views Asked by At

I'm implementing a LinkedListDeque data structure. I've written an equals method and a helper that:

  1. Checks if object o is an instance of class LinkedListDeque. If true,
  2. Checks if each node in o is equal to the nodes in this deque.

I wrote a helper because I needed a way to do the comparison operation in 2 between two LinkedListDeque objects and not between the this deque and the o object. When I first wrote the equals_helper method, I left out the parentheses in the type declaration. Tested, didn't work. The IDE suggested that I put a parentheses around the type declaration (i.e. equals_helper(LinkedListDeque o) to equals_helper((LinkedListDeque) o)), and that worked.

I've tried to find some documentation on what I'm doing here, but I don't have the background knowledge to know what I'm searching for. What is this concept called, am I applying it correctly in the context of Java OOP principles, and is there a better way to do this?

public boolean equals(Object o) {
    if (!(o instanceof LinkedListDeque)) {
        return false;
    } else {
        return this.equals_helper((LinkedListDeque) o);
    }
}

public boolean equals_helper(LinkedListDeque L) {
    if (L.size() != this.size()) {
        return false;
    } else {
        Node orig_curr = sentinel.next;
        Node curr = L.sentinel.next;
        while (orig_curr.item != null || curr.item != null) {
            if (orig_curr.item == curr.item) {
                curr = curr.next;
                orig_curr = orig_curr.next;
            } else return curr.next.item == null && orig_curr.next.item == null;
        }
    }
    return true;
}
2

There are 2 best solutions below

0
WJS On BEST ANSWER

Since the argument to equals is of type Object you need to cast it to the type that you want to use. Otherwise, it could be a different type. In this case LinkedListDeque. But as of Java 14, you can do it as follows:

public boolean equals(Object o) {
    if (o instanceof LinkedListDeque lld)) {
       return this.equals_helper(lld);
    }
    return false;
}

If the instanceof returns true, it is automatically cast to the correct type and placed in lld which may then be used. No explicit casting is required.

Note: You should first check to see if the objects are the same. if(this == obj) return true;

And it's a good habit to also override hashCode when you override equals.

0
Himanshu Gupta On

I think you might have mistyped one thing in your question. When you say: When I first wrote the equals_helper method, I left out the parentheses in the type declaration

and then you mention The IDE suggested that I put a parentheses around the type declaration (i.e. equals_helper(LinkedListDeque o) to equals_helper((LinkedListDeque) o))

So, what I see equals_helper((LinkedListDeque) o)) is not part of equals_helper method but when you are invoking equals_helper method inside equals method. (equals_helper(LinkedListDeque L) is the declaration of helper method with parameter name L and not O).

So, maybe you generally mean your overall equals/equals_helper logic.

Assuming you are talking about invoking equals_helper method inside equals: this.equals_helper((LinkedListDeque) o) and your question is about the parentheses up there. . . As WJS already answered...

As you see your equals method declaration:

public boolean equals(Object o)

o is an object of Class Object. equal_helper method expects an argument of type LinkedListDeque or its sub class. Since you already validated "o instanceof LinkedListDeque" you are good to cast it to LinkedListDeque and that is how you cast an object to a type(putting the type in parentheses in front/left of object variable).

To answer your "What is this concept called, am I applying it correctly in the context of Java OOP principles, and is there a better way to do this?" part. I would recommend going through the book CoreJava Volume 1 topic 5.2.2 The equals Method There are whole set of guidelines for righting equals method more efficiently and the casting is also discussed there in more detail. I am mentioning some of it here.

you can include a null pointer check if (o == null) return false;

a quick reference check if (this == o) return true;

if you want comparision between objects of LinkedListDeque and not of sub type you can use getClass() method if (getClass()!=o.getClass()) return false

note that you're using instance of operator which works one way or downstream and it will not hold the symmetry:

Let's assume A is a class where equals is defined. B extends A. In equals method defined inside a the check is - o instance of A let's say a is an object of A, b is an object of B. The result of instanceof operator will hold true for a.equals(b) but will be false for b.equals(a) hence no symmetry in outcome. To avoid that you can use getClass() that will make a.equals(b) false as well and will only hold true when both objects are either of type A or B.

Quoting from the book: 5.2.3 Equality Testing and inheritance The java language specification requires that the Equals method has following properties: It is reflexive. . . symmetric, transtive, consistent.

But that is up to your requirements :)