Does comparator interface inherit Object class? - java

I think it might, because the Comparator interface contains an equals method.

From section 9.2 of the Java Language Specification:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.
This allows you to call any of the Object methods via a reference of an interface type - which makes sense, given that the implementation will certainly be a subclass of Object.
EDIT: In the case of Comparator, it so happens that equals is explicitly redeclared, in order to provide more documentation. However, you'd be able to call equals on a Comparator reference anyway.

No interface implements Object class but the implementation does

In Java, every class will ultimately extend Object. While you can't instanciate Comparator itself, all comparator implementations will still extend Object.
The equals() method is redeclared in Comparator in order to adapt the Javadoc for the special contract that Comparator imposes on equals()

No interfaces ever extends/inherit an Object. Only it's implemented classes does extends Object implicitly (if not explicitly extended).
The Comparator.equals() method follows the same signature as Object.equals() method. The reason for this is stated on the JavaDoc:
However, overriding this method may,
in some cases, improve performance by
allowing programs to determine that
two distinct comparators impose the
same order.

Interface types are not officially subtypes of Object, but behave as if they were:
They also implicitly declare all the methods of Object (as quoted by Jon)
They can be converted to Object by an widening conversion without an explicit cast
All objects of the interface type are automatically objects of the object type
In this case, the interface type redeclares the equals method in a compatible way, and the implementation from Object is used if the implementing class does not provide its own implementation.
The specification here is done in a way that the default implementation from Object.equals also fits the specification of Comparator.equals, and that every (conformant) implementation of Comparator.equals also fits the specification of Object.equals.

Please refer below link
http://www.docjar.com/html/api/java/util/Comparator.java.html
You can see in the code that Comparator interface has its own equals method.

In java, an interface can never be created by inheriting it from a class. So, no, Comparator interface doesn't inherit Object class.

The interfaces are like Roles and its responsibilities are declared as interface methods.
Comparator being the interface just lists all the responsibilities which needs to be provided by a class which implements this interface.
The object of the class which implements Comparator will be subclass of the Object class.

Related

When we define the abstract methods of an interface in a class do we 'override' or 'implement' or simply say 'define' those methods?

Is the show() method in class B 'overridden', 'implemented' or simply 'defined'?
interface A
{
void show();
}
class B implements A
{
public void show()
{
System.out.println("What is the proper term to explain?");
}
}
A short answer, we override those methods, why?
Because this represents the concept of polymorphic statement, Remember
List<String> aa = new ArrayList<>();
// List => interface
// ArrayList => class
aa.add("polymorphic statment");
Polymorphic statement and overiding go hand in hand.
Although any class also has the option to implement an interface by declaring itself abstract and no need to override any method.
Note: Apply the same concept in any IDE, will guide you to add #Override annotation.
Generally speaking I say "override" to mean redefining an inherited behavior and I keep "implement" to mean defining a behavior (not implemented yet).
So I would say that B implements show().
And the JLS seems to go in this way :
If a non-abstract method mC overrides an abstract method mA from a
class C, then mC is said to implement mA from C.
The oracle example documentation seems to says that override is to redefine a behavior too :
The ability of a subclass to override a method allows a class to
inherit from a superclass whose behavior is "close enough" and then to
modify behavior as needed. The overriding method has the same name,
number and type of parameters, and return type as the method that it
overrides. An overriding method can also return a subtype of the type
returned by the overridden method. This subtype is called a covariant
return type.
Note that the java.lang.Override annotation doesn't say the contrary (emphasis is mine) :
Indicates that a method declaration is intended to override a method
declaration in a supertype. If a method is annotated with this
annotation type compilers are required to generate an error message
unless at least one of the following conditions hold:
The method does override or implement a method declared in a
supertype.
The method has a signature that is override-equivalent to that of any
public method declared in Object.
The API could have provided #Implement additionally to the #Override annotation.
But it seems rather clumsy to have both. So they probably kept a single one : #Override to convey the two things.
The method show() in class B implements the method declared in interface A.
You should say implement because override means that you are overwriting some existing method which is not true in case of interfaces. Interfaces cannot contain method definitions, they merely specify a contract.

Why does the Collection interface have equals() and hashCode()?

Why does the Collection interface have equals(Object o) and hashCode(), given that any implementation will have those by default (inherited from Object) ?
From the Collection JavaDoc:
While
the Collection interface adds no stipulations to the general contract
for the Object.equals, programmers who implement the Collection
interface "directly" (in other words, create a class that is a
Collection but is not a Set or a List) must exercise care if they
choose to override the Object.equals. It is not necessary to do so,
and the simplest course of action is to rely on Object's
implementation, but the implementor may wish to implement a "value
comparison" in place of the default "reference comparison." (The List
and Set interfaces mandate such value comparisons.)
The general contract for the Object.equals method states that equals
must be symmetric (in other words, a.equals(b) if and only if
b.equals(a)). The contracts for List.equals and Set.equals state that
lists are only equal to other lists, and sets to other sets. Thus, a
custom equals method for a collection class that implements neither
the List nor Set interface must return false when this collection is
compared to any list or set. (By the same logic, it is not possible to
write a class that correctly implements both the Set and List
interfaces.)
and
While the Collection interface adds no stipulations to the general contract for the Object.hashCode method, programmers should take note that any class that overrides the Object.equals method must also override the Object.hashCode method in order to satisfy the general contract for the Object.hashCode method. In particular, c1.equals(c2) implies that c1.hashCode()==c2.hashCode().
To answer your specific question: why does it have these methods? It's done simply for convenience to be able to include Java Docs giving hints as to what implementers should do with these methods (e.g. comparing equality of values rather than references).
To add to the other great answers. In the Collections interface, the equals method is defined in that interface to make some decisions in the way equaling two instances of collection should work. From the JAVA 8 documentation:
More generally, implementations of the various Collections Framework
interfaces are free to take advantage of the specified behavior of
underlying Object methods wherever the implementor deems it
appropriate.
So you don’t add methods from the Object class for any other reason that giving more definitiveness to the java doc. This is the reason why you don’t count those methods in the abstract methods in the abstract methods of an interface.
Moreover, in JAVA 8, along the same line of reasoning, default methods from the Object class are not allowed and will generate a compile error. I believe it’s was done to prevent this type of confusion. So if you try to create a default method called hashCode(), for example, it will not compile.
Here is a more in-depth explanation for this behavior in JAVA 8 from the Lambda FAQ:
An interface cannot provide a default implementation for any of the
methods of the Object class. This is a consequence of the “class wins”
rule for method resolution: a method found on the superclass chain
always takes precedence over any default methods that appear in any
superinterface. In particular, this means one cannot provide a default
implementation for equals, hashCode, or toString from within an
interface.
This seems odd at first, given that some interfaces actually define
their equals behavior in documentation. The List interface is an
example. So, why not allow this?
One reason is that it would become more difficult to reason about when
a default method is invoked. The current rules are simple: if a class
implements a method, that always wins over a default implementation.
Since all instances of interfaces are subclasses of Object, all
instances of interfaces have non-default implementations of equals,
hashCode, and toString already. Therefore, a default version of these
on an interface is always useless, and it may as well not compile.
Another reason is that providing default implementations of these
methods in an interface is most likely misguided. These methods
perform computations over the object’s state, but the interface, in
general, has no access to state; only the implementing class has
access to this state. Therefore, the class itself should provide the
implementations, and default methods are unlikely to be useful.
Just to add to the great answers above, it makes sense to have the 'equals' or `hashCode' methods in this scenario:
Collection<Whatever> list1 = getArrayList();
Collection<Whatever> list2 = getAnotherArrayList();
if(list1.equals(list2)){
// do something
}
In the absence of the equals method in the interface, we'll be forced to use concrete types, which is generally not a good practice :
ArrayList<Whatever> list1 = getArrayList();
ArrayList<Whatever> list2 = getAnotherArrayList();
if(list1.equals(list2)){
// do something
}

Why is it not necessary to override both methods of interface Comparator in Java

We know that it is necessary to implement all methods of an interface, if we want to make an object of that class. But why is it not necessary to implement both the methods compare() and equals() of interface Comparator in java?
I agree that the purpose is solved but even then why is it not mandatory to override equals() if we override compare()?
Since all classes implicitly extend Object every implementation of a Comparator has an equals method, because every Object has one.
It would be the same if you define an interface with a toString() method.
public interface ToString {
public String toString();
}
public class SomeClass implements ToString {
// toString implicitly implemented, because Object defines it
}
When you look at the class it says "implements ToString" and this is true, isn't it?
Because it is already overridden by java.lang.Object on every object you can create.
Every object implicitly has an equals from Object (as every object is a sub-type of Object) - and since it's a virtual method, standard Java polymorphism takes over.
Now, Comparator#equals imposes an additional restriction, which is why it is specified as part of the interface.
..this method can return true only if the specified object is also a comparator and it imposes the same ordering as this comparator.
However, since the coverse need to be true, then not overloading equals doesn't break the new requirement.
Note that it is always safe not to override Object.equals(Object).. [as then different comparator instances will never be equal].

Precise definition of "functional interface" in Java 8

Recently I started exploring Java 8 and I can't quite understand the concept of "functional interface" that is essential to Java's implementation of lambda expressions. There is a pretty comprehensive guide to lambda functions in Java, but I got stuck on the chapter that gives definition to the concept of functional interfaces. The definition reads:
More precisely, a functional interface is defined as any interface that has exactly one abstract method.
An then he proceeds to examples, one of which is Comparator interface:
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
I was able to test that I can use a lambda function in place of Comparator argument and it works(i.e. Collections.sort(list, (a, b) -> a-b)).
But in the Comparator interface both compare and equals methods are abstract, which means it has two abstract methods. So how can this be working, if the definition requires an interface to have exactly one abstract method? What am I missing here?
From the same page you linked to:
The interface Comparator is functional because although it declares two abstract methods, one of these—equals— has a signature corresponding to a public method in Object. Interfaces always declare abstract methods corresponding to the public methods of Object, but they usually do so implicitly. Whether implicitly or explicitly declared, such methods are excluded from the count.
I can't really say it better.
Another explanation is given in the #FunctionalInterface page:
Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract. If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface's abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.
You can test which interface is a correct functional interface using #FunctionalInterface.
E.g.:
this works
#FunctionalInterface
public interface FunctionalInterf {
void m();
boolean equals(Object o);
}
this generates an error:
#FunctionalInterface
public interface FunctionalInterf {
void m();
boolean equals();
}
Multiple non-overriding abstract methods found in interface FunctionalInterf
Q. But in the Comparator interface both compare() and equals() methods are abstract, which means it has two abstract methods. So how can this be working, if the definition requires an interface to have exactly one abstract method? What am I missing here?
A.
A functional interface may specify any public method defined by Object, such as equals( ),
without affecting its “functional interface” status. The public Object methods are considered implicit
members of a functional interface because they are automatically implemented by an instance of a
functional interface.
An interface cannot extend Object class, because Interface has to have public and abstract methods.
For every public method in the Object class, there is an implicit public and abstract method in an interface.
This is the standard Java Language Specification which states like this,
“If an interface has no direct super interfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.”
That's how Object class' methods are declared in an interface. And according to JLS, this does not count as interface' abstract method. Hence, Comparator interface is a functional interface.
A functional interface has only one abstract method but it can have multiple default and static methods.
Since default methods are not abstract you’re free to add default methods to your functional interface as many as you like.
#FunctionalInterface
public interface MyFuctionalInterface
{
public void perform();
default void perform1(){
//Method body
}
default void perform2(){
//Method body
}
}
If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface’s abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.
Comparator is a functional interface even though it declared two abstract methods. Because one of these abstract methods “equals()” which has signature equal to public method in Object class.
e.g. Below interface is a valid functional interface.
#FunctionalInterface
public interface MyFuctionalInterface
{
public void perform();
#Override
public String toString(); //Overridden from Object class
#Override
public boolean equals(Object obj); //Overridden from Object class
}
Here is a "show me the code" approach to understanding the definition:
we shall look into OpenJDK javac for how it checks validity of classes annotated with #FunctionalInterface.
The most recent (as of July, 2022) implementation lies here:
com/sun/tools/javac/code/Types.java#L735-L791:
/**
* Compute the function descriptor associated with a given functional interface
*/
public FunctionDescriptor findDescriptorInternal(TypeSymbol origin,
CompoundScope membersCache) throws FunctionDescriptorLookupError {
// ...
}
Class Restriction
if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0 || origin.isSealed()) {
//t must be an interface
throw failure("not.a.functional.intf", origin);
}
Pretty simple: the class must be an interface and must not be a sealed one.
Member Restriction
for (Symbol sym : membersCache.getSymbols(new DescriptorFilter(origin))) { /* ... */ }
In this loop, javac goes through the members of the origin class, using a DescriptorFilter to retrieve:
Method members (of course)
&& that are abstract but not default,
&& and do not overwrite methods from Object,
&& with their top level declaration not a default one.
If there is only one method matching all the above conditions, then surely it is a valid functional interface, and any lambda will overwrite that very method.
However, if there are multiple, javac tries to merge them:
If those methods all share the same name, related by override equivalence:
then we filter them into a abstracts collection:
if (!abstracts.stream().filter(msym -> msym.owner.isSubClass(sym.enclClass(), Types.this))
.map(msym -> memberType(origin.type, msym))
.anyMatch(abstractMType -> isSubSignature(abstractMType, mtype))) {
abstracts.append(sym);
}
Methods are filtered out if:
their enclosing class is super class of that of another previously matched method,
and the signature of that previously matched method is subsignature of that of this method.
Otherwise, the functional interface is not valid.
Having collected abstracts, javac then goes to mergeDescriptors, which uses mergeAbstracts, which I will just quote from its comments:
/**
* Merge multiple abstract methods. The preferred method is a method that is a subsignature
* of all the other signatures and whose return type is more specific {#see MostSpecificReturnCheck}.
* The resulting preferred method has a thrown clause that is the intersection of the merged
* methods' clauses.
*/
public Optional<Symbol> mergeAbstracts(List<Symbol> ambiguousInOrder, Type site, boolean sigCheck) {
// ...
}
Conclusion
Functional interfaces must be interfaces :P , and must not be sealed or annotations.
Methods are searched in the whole inheritance tree.
Methods overlapping with those from Object are ignored.
default methods are ignored, unless they are later overridden by sub-interfaces as non-default.
Matching methods must all share the same name, related by override equivalence.
Either there is only one method matching the above conditions, or matching methods can get "merged" by their class hierarchy, subsignature relations, return types and thrown clauses.
The Java docs say:
Note that it is always safe not to override Object.equals(Object).
However, overriding this method may, in some cases, improve
performance by allowing programs to determine that two distinct
comparators impose the same order.
Maybe Comparator is special? Maybe, even though it's an interface, there is somehow a default implementation of equals() that calls compare()? Algorithmically, it's trivial.
I thought all methods that were declared in interfaces were abstract (i. e. no default implementation). But maybe I'm missing something.
Definition:
If an interface contains only one abstract method, then such type of interface is called functional interface.
Usage:
Once we write Lambda expression "->" to invoke its functionality ,
then in this context we require Functional Interface.
We can use the Functional Interface reference to refer Lambda
expression.
Inside functional interface we can have one abstract method and n
number of default/static methods.
Functional interface with respect to inheritance:
If an interface extends Functional interface and the child interface does not contain any abstract method , then the child interface is also considered to be Functional Interface.
Functional interface is not new to java, its already used in following interface API's:
Runnable : contains run() method only.
Callable : contains call() method only.
Comparable : contains compareTo() method only.
Before Java 8, an interface could only declare one or more methods also known as Abstract Method (method with no implementation, just the signature). Starting with Java 8 an interface can also have implementation of one or more methods (knows as Interface Default Method) and static methods along with abstract methods. Interface Default Methods are marked default keyword.
So the question is, what is Functional Interface?
An interface with Single Abstract Method (SAM) is called Functional Interface.
Which means -
An interface with Single Abstract Method is a Functional Interface
An interface with Single Abstract Method and zero or more default
methods and zero or more static method is also a valid Functional
Interface.
More detail with example code https://readtorakesh.com/functional-interface-java8/

Java interface extends interface in the java.util package

As we know, interfaces can extend interface in the Java. I have a question about this, if interface B extends interface A, B need not implement the methods defined in the A. But in the java.util package, the List interface extends Collection interface, and it implements the Collection method, these methods also just have the method declaration.
Why does it do this, and it there a better practice? Does it make any difference between implementing the method in the sub interface or not?
Overriding a method, besides providing/replacing a method implementation, allows to provide a more specific javadoc, and to narrow the return type.
For instance, Collection.iterator() is specified by:
Returns an iterator over the elements in this collection. There are no
guarantees concerning the order in which the elements are returned
(unless this collection is an instance of some class that provides a
guarantee).
while List.iterator() is specified by
Returns an iterator over the elements in this list in proper sequence.
I don't see any implementation in java.util.List but declarations. Instead the javadocs of List say,
The List interface places additional stipulations, beyond
those specified in the Collection interface, on the
contracts of the iterator, add, remove,
equals, and hashCode methods. Declarations for
other inherited methods are also included here for convenience.
The interface List do not implement Collections' methods because interfaces just cannot implement methods, they just declare them. An interface is like a 100% abstract class: all the methods must be abstract methods.
Probably your confusion comes from abstract classes that implement interfaces: these classes must not implement interface's methods (despite being allowed to), only the first concrete class must.
Interfaces are fully abstract in Java. They can't have any implementation.
Redeclaring a method is not the same as implementing it. And it doesn't make any sense to redeclare a method (if the method signature is exactly same), because the purpose of an interface extending another interface is to add some more-specific method declarations, and not to just redeclare the existing ones.
Edit
As pointed out in #Arham's and #meriton's answer, the purpose of the redeclaration is to respecify the method according to the sub-interface. So, for a client code, accessing the underlying collection, there would be a separate more-specific specification on the redeclared methods than the more-general one in the super-interface.

Categories