Collection interface defines the most common general methods which can be applicable for any Collection object.
Some of the methods are like:
1) boolean add(Object obj)
2) boolean addAll(Collection c)
3) boolean remove(Object obj)
4) boolean removeAll(Collection c) (Removes particular group of
objects.)
5) boolean retainAll(Collection c) (Removes all the elements except
those present in c)
I want know the justification for this statement.
There is no concrete class which implements collection interface
directly.
There is nothing stopping you from creating a concrete direct implementation of Collection. However, such an implementation would probably have some additional properties not covered by the Collection contract.
For example, if the elements of your Collection implementation have an ordering, you might as well implement the List interface.
On the other hand, if the storage of your Collection implementation doesn't allow duplicate elements, you might as well implement the Set interface.
...and so on.
This may give you an idea why no concrete direct implementation was deemed necessary by the designers of the standard Collections library.
Related
Following the hierarchy of the Collections Framework in Java, I struggle to understand where these 2 methods of the Iterator Interface are being implemented.
boolean hasNext();
E next();
The other 2 methods
default void remove()
default void forEachRemaining(Consumer<? super E> action)
have default implementations in the Iterator Interface itself (although they are probably overridden somewhere else too).
image source: https://www.javatpoint.com/collections-in-java
I know that depending on the hierarchy, for example Interface -> Interface -> Class, the implementation can be either in the interface itself as a default method or in the concrete class. But lets take for example the ArrayList, where in the whole hierarchy are the hasNext() and next() methods being implemented.
Collection implements Iterable and Iterable has the method iterator() that returns the Iterator interface, so implementations dont have to implement the Iterator interface.
If you take ArrayList for example, it inherits AbstractList which implements iterator and that is used by different lists implementations.
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
}
I have an Interface MyInterface with numerous implementations and a Collection Collection<MyInterface>.
Now how can I make sure that there's no two elements in this Collection are of the same type?
And how can I prevent any entry from being overridden?
Meaning that there's at any given point in time only ever 1 instance of each implementation in the Collection.
For obvious reasons I can't add a default equals(Object obj) implementation to the interface.
Nor can I guarantee in any way that each of the implementations overrides the equals(Object obj) method (obvious but in here for the sake of thoroughness).
The only way I currently see is to create an abstract Class MyAbstractClass. But that seems overkill(?)
You can use a Map<Class<?>,MyInterface> instead of a Collection<MyInterface>. The key would be the implementing Class. This would ensure that at most one instance of each type can be added to the Map.
Here's how you can initialize the map and add entries to it without overriding existing entries:
Map<Class<?>,MyInterface> map = new HashMap<>();
...
if (!map.containsKey(obj.getClass())) {
map.put(obj.getClass(),obj);
}
Also, if you'd like, see Collections.newSetFromMap for how to implement a Collection backed by a Map. Be aware that at runtime, your map could be filled with all kinds of classes as keys. You could use Map<Class<? extends MyInterface>, MyInterface> to get at least a compile-time protection.
Why LinkedList and ArrayList extends AbstractList in Java?
Abstract classes are used when we want to specify a common behaviour in implementation classes.
But all the methods which are in AbstractList are overridden by ArrayList and LinkedList.
So what is the use of extending this class?
subList(int,int) method is not overriden by both ArrayList and LinkedList, and for this AbstractList provides a common implementation
From Java source
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<E>(this, fromIndex, toIndex) :
new SubList<E>(this, fromIndex, toIndex));
}
In addition there are other methods which are not overriden like toString() and iterator()
You can get Answer from Here,,, AbstractList
This class provides a skeletal implementation of the List interface to minimize the effort required to implement this interface backed by a "random access" data store (such as an array). For sequential access data (such as a linked list), AbstractSequentialList should be used in preference to this Class.
To implement an unmodifiable List, the programmer needs only to extend this class and provide implementations for the get(int index) and size() methods.
To implement a modifiable List, the programmer must additionally override the set(int index, Object element) method (which otherwise throws an UnsupportedOperationException. If the List is variable-size the programmer must additionally override the add(int index, Object element) and remove(int index) methods.
The programmer should generally provide a void (no argument) and Collection constructor, as per the recommendation in the Collection interface specification.
Unlike the other abstract Collection implementations, the programmer does not have to provide an Iterator implementation; the iterator and listIterator are implemented by this class, on top the "random access" methods: get(int index), set(int index, Object element), set(int index, Object element), add(int index, Object element) and remove(int index).
The documentation for each non-abstract methods in this class describes its implementation in detail. Each of these methods may be overridden if the Collection being implemented admits a more efficient implementation.
Not all methods from AbstractList are overridden. Remember that AbstractList subclasses AbstractCollection, which defines methods like containsAll or toString which are not overridden by either ArrayList nor LinkedList.
Usage is noted at the top of the AbstractList source file
"This class provides a skeletal implementation of the {#link List}
interface to minimize the effort required to implement this interface
backed by a "random access" data store (such as an array). For sequential
access data (such as a linked list), {#link AbstractSequentialList} should
be used in preference to this class."
So essentially it provides some methods to build around and a framework that is more robust than the List interface.
I am new to Java.
Java has Collection interface
public interface Collection<E> extends Iterable<E>
{ // a lot of other stuff.
Iterator<E> iterator(); }
What I don't understand is how does Iterator Interface is tying into Collection Interface ? When I look at the Collection Interface, I see that it has a method that returns Iterator. When Iterator for Collection is created, where does JVM looks to create an object that IS-An Iterator ?
Thanks !
The JVM doesn't do it; the code that ultimately implements the abstract iterator() method just creates an instance of an appropriate class and returns it. For example, in the class ArrayList(), which implements List which extends Collection, there is a method that implements iterator() by returning an instance of a class that understand how ArrayList is implemented internally. This Iterator class is private to the java.util package -- normally you'll never see its name.
Ok so this is all pretty advanced java stuff and it will be pretty tough to explain in one go here but I will do my best.
BACKGROUND: If you don't know about those funny <E> things, you should do a bit of looking into Java Generics. Also, if you don't already, you really need to know what an interface is. One really basic way to think of it is as a promised bit of functionality a class promises to provide.
Now to answer your question: There are three interfaces in the above code snippet, and if you want to create your own collection class you will need to provide implementations of all three:
The first is Collection. This is a simple concept that maps to the real world, it is literally a "collection" of objects. I think you get this...
The next one is Iterable this defines a singe type of behavior that all collections need to provide: the ability to traverse all of the elements of a collection, while accessing them one by one ie "iterate" over them. But it doesn't stop there. As you pointed out the Iterable functionality is provided by objects that implement the last interface:
Iterator: objects that implement this interface, actually know how to traverse the elements of a collection class, they hide all the details of how its actually done from thier clients and proved a few clean easy methods for actually doing it like hasNext() which checks to see if there are more things in the collection to visit and next() which actually visits the next thing.
phew...
The code for the iterator() method determines which concrete implementation of Iterator to return.
All non-abstract classes that implement the Collection interface are required to provide an implementation for the iterator() method.