In JDK 8, java.util.Collection starts with
public interface Collection<E> extends Iterable<E> {
// Query Operations
/**
* Returns the number of elements in this collection. If this collection
* contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* #return the number of elements in this collection
*/
int size();
Interestingly, java.util.Set starts with
public interface Set<E> extends Collection<E> {
// Query Operations
/**
* Returns the number of elements in this set (its cardinality). If this
* set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* #return the number of elements in this set (its cardinality)
*/
int size();
What is the purpose of overriding method declarations in interfaces? Why does not extends suffice?
EDIT java.util.List also shows redundancy, and the javadoc of List.size() is only minimally different that of Collection.size(), and does not introduce any new term:
public interface List<E> extends Collection<E> {
// Query Operations
/**
* Returns the number of elements in this list. If this list contains
* more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* #return the number of elements in this list
*/
int size();
Overriding a method can be used for a lot of reasons besides to change the behavior. It can change the signature of the method (refining the return type with a covariant override), add annotations, broaden the accessibility (turning a protected method into public in a subclass), or refine the specification (expressed as Javadoc). In this case, the override exists so that the Set Javadoc could define the term "cardinality".
Related
I have methods toSaveString(StringBuilder) and toSaveString() in several classes and thought of turning those into an interface. The first method would always have to be implemented and the second I could default because it basically only calls the first method every time with a new string builder and returns the resulting string. (Not what default is designed for, but bear with me.)
Now I wouldn't need to implement toSaveString() in the classes implementing the interface, but I would like to change its documentation nonetheless to match the class. Is there a way to achieve this without overriding the toSaveString() method in the implementing class? Because adding three lines to call the default method or five to copy the implementation seems redundant and easy to get errors mixed in.
Also feel free to leave comments about design alternatives here, but the question stays because it is interesting in its own right.
Look at the javadoc of the ArrayList#removeIf method:
/**
* #throws NullPointerException {#inheritDoc}
*/
#Override
public boolean removeIf(Predicate<? super E> filter) {
return removeIf(filter, 0, size);
}
It overrides its superclass Collection#removeIf method:
/**
* Removes all of the elements of this collection that satisfy the given
* predicate. Errors or runtime exceptions thrown during iteration or by
* the predicate are relayed to the caller.
*
* #implSpec
* The default implementation traverses all elements of the collection using
* its {#link #iterator}. Each matching element is removed using
* {#link Iterator#remove()}. If the collection's iterator does not
* support removal then an {#code UnsupportedOperationException} will be
* thrown on the first matching element.
*
* #param filter a predicate which returns {#code true} for elements to be
* removed
* #return {#code true} if any elements were removed
* #throws NullPointerException if the specified filter is null
* #throws UnsupportedOperationException if elements cannot be removed
* from this collection. Implementations may throw this exception if a
* matching element cannot be removed or if, in general, removal is not
* supported.
* #since 1.8
*/
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
In your case, you can override only javadoc, and write something like this in the method body:
/**
* custom javadoc
*/
#Override
public boolean customMethod(Object parameter) {
return super.customMethod(parameter);
}
See also: Can I add code to an inherited method without overriding the whole method?
I am having trouble here. The question is:
The union of two collections consists of their contents combined into a new collection. Add a method union to the interface BagInterface for the ADT bag that returns as a new bag the union of the bag receiving the call to the
method and the bag that is the method’s one argument. Include sufficient comments to fully specify the method. Note that the union of two bags might contain duplicate items. For example, if object x occurs five times in one
bag and twice in another, the union of these bags contains x seven times. Specifically, suppose that bag1 and bag2 are Bag objects, where Bag implements BagInterface; bag1 contains the String objects a, b, and c; and bag2 contains
the String objects b, b, d, and e. After the statement BagInterface everything = bag1.union(bag2); executes, the bag everything contains the strings a, b, b, b, c, d, and e. Note that union does not affect the contents
of bag1 and bag2.
So essentially I have a class called ResizableArrayClass that specifies T[] bag in it's data field, and is essentially resizable per other methods within the class. The method header for "union" as defined in my interface is as follow's:
public BagInterface union(BagInterface anotherBag);
Normally, finding the union between two array's would be very simple. But I am trying to find the union between two array's that are part of two separate objects (bag1, bag2 of ResizableArrayClass). My question is, how would I go about finding the union between two array's in this way when using the following statement in a demo program:
BagInterface<String> everything = bag1.union(bag2);
Interface (sorry for comments):
public int getCurrentSize();
/** Sees whether this bag is empty.
#return True if the bag is empty, or false if not. */
public boolean isEmpty();
/** Adds a new entry to this bag.
#param newEntry The object to be added as a new entry.
#return True if the addition is successful, or false if not. */
public boolean add(T newEntry);
/** Removes one unspecified entry from this bag, if possible.
#return Either the removed entry, if the removal.
was successful, or null. */
public T remove();
/** Removes one occurrence of a given entry from this bag.
#param anEntry The entry to be removed.
#return True if the removal was successful, or false if not. */
public boolean remove(T anEntry);
/** Removes all entries from this bag. */
public void clear();
/** Counts the number of times a given entry appears in this bag.
#param anEntry The entry to be counted.
#return The number of times anEntry appears in the bag. */
public int getFrequencyOf(T anEntry);
/** Tests whether this bag contains a given entry.
#param anEntry The entry to locate.
#return True if the bag contains anEntry, or false if not. */
public boolean contains(T anEntry);
/** Retrieves all entries that are in this bag.
#return A newly allocated array of all the entries in the bag.
Note: If the bag is empty, the returned array is empty. */
public T[] toArray();
//public <T> T[] toArray(); // Alternate
//public Object[] toArray(); // Alternate
/** Creates a new bag that combines the contents of this bag and anotherBag.
#param anotherBag The bag that is to be added.
#return A combined bag. */
public BagInterface union(BagInterface anotherBag);
I think you could use BagInterface's methods only:
public BagInterface<T> union(BagInterface<T> anotherBag) {
BagInterface<T> result = new ResizableArrayClass<T>();
T[] mine = this.toArray();
for (T elem : mine) {
result.add(elem);
}
T[] others = anotherBag.toArray();
for (T elem : others) {
result.add(elem);
}
return result;
}
java.util.Map.Entry as I know is a public static interface in java.util package that
returns collection view of a map but as far now I am confused with the static interface
and as it is Map.Entry is it an inner interface if so how do we have inner static interfaces in java
The definition of Entry happens to live inside the definition of Map (allowed by java). Being static means you don't need an instance of Map to refer to an Entry.
It's easiest to show how to use Map.Entry by an example. Here's how you can iterate over a map
Map<Integer, String> map = new HashMap<Integer, String>();
for (Map.Entry<Integer, String> entry : map.entrySet()) {
Integer key = entry.getKey();
String value = entry.getValue();
// do something with key and/or value etc
// you may also alter the entry's value inside this loop via entry.setValue()
}
There isn't really anything to be confused about.
Yes, Java allows interfaces to be members of classes or other interfaces.
No, that does not mean anything special. It changes absolutely nothing about how you can use such an interface or what you can do with it.
It only changes the name of that interface and creates a strong conceptual link between it and its enclosing type. In this case, a Map.Entry represents an entry of a Map. The designers of the API apparently felt that it made sense to stress this connection by making it a member type.
Example:
public class Outer {
public interface Bar {
Bar get();
}
}
Bar is a nested interface. Nested interfaces are static by default, so you could as well write:
public class Outer {
public static interface Bar {
Bar get();
}
}
Now, what static in this context means is that the interface is a static member, i.e. a member of the class.
You can do this with classes as well:
public class Tree {
private static class Node {
}
}
Here, Node is even private, meaning it's only visible within Tree. So, what's the benefit of this? Why not make Node a public class? Because of better encapsulation. First, the Node is an implementation detail of the Tree, so you don't want it to be visible. Second, if you expose Node via a public API, some client (programmer) could use it in his code. Now, he has a hard dependency on this class. If at some point you want to change the representation of you Tree, and you change/remove the Node class, the client code's may break. And last but not least, your public API becomes smaller, which is also desirable.
So, when to use static member classes/interfaces? Mostly, if you build some sort of Composite object (like a Tree, or a Linked List) or when the class only makes sense in the context of the outer class.
Java allows nested interfaces. You can nest them into classes or interfaces. For instance, Map.Entry is a nested interface defined in the Map interface.
Map implementations (TreeMap, HashMap) provide private implementations of Map.Entry, which are not visible outside the class.
Bohemian's answer addresses how to use Map.Entry.
Yes, it's an inner interface of the Map interface.
/**
* A map entry (key-value pair). The <tt>Map.entrySet</tt> method returns
* a collection-view of the map, whose elements are of this class. The
* <i>only</i> way to obtain a reference to a map entry is from the
* iterator of this collection-view. These <tt>Map.Entry</tt> objects are
* valid <i>only</i> for the duration of the iteration; more formally,
* the behavior of a map entry is undefined if the backing map has been
* modified after the entry was returned by the iterator, except through
* the <tt>setValue</tt> operation on the map entry.
*
* #see Map#entrySet()
* #since 1.2
*/
interface Entry<K,V> {
/**
* Returns the key corresponding to this entry.
*
* #return the key corresponding to this entry
* #throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
K getKey();
/**
* Returns the value corresponding to this entry. If the mapping
* has been removed from the backing map (by the iterator's
* <tt>remove</tt> operation), the results of this call are undefined.
*
* #return the value corresponding to this entry
* #throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V getValue();
/**
* Replaces the value corresponding to this entry with the specified
* value (optional operation). (Writes through to the map.) The
* behavior of this call is undefined if the mapping has already been
* removed from the map (by the iterator's <tt>remove</tt> operation).
*
* #param value new value to be stored in this entry
* #return old value corresponding to the entry
* #throws UnsupportedOperationException if the <tt>put</tt> operation
* is not supported by the backing map
* #throws ClassCastException if the class of the specified value
* prevents it from being stored in the backing map
* #throws NullPointerException if the backing map does not permit
* null values, and the specified value is null
* #throws IllegalArgumentException if some property of this value
* prevents it from being stored in the backing map
* #throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V setValue(V value);
/**
* Compares the specified object with this entry for equality.
* Returns <tt>true</tt> if the given object is also a map entry and
* the two entries represent the same mapping. More formally, two
* entries <tt>e1</tt> and <tt>e2</tt> represent the same mapping
* if<pre>
* (e1.getKey()==null ?
* e2.getKey()==null : e1.getKey().equals(e2.getKey())) &&
* (e1.getValue()==null ?
* e2.getValue()==null : e1.getValue().equals(e2.getValue()))
* </pre>
* This ensures that the <tt>equals</tt> method works properly across
* different implementations of the <tt>Map.Entry</tt> interface.
*
* #param o object to be compared for equality with this map entry
* #return <tt>true</tt> if the specified object is equal to this map
* entry
*/
boolean equals(Object o);
/**
* Returns the hash code value for this map entry. The hash code
* of a map entry <tt>e</tt> is defined to be: <pre>
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
* (e.getValue()==null ? 0 : e.getValue().hashCode())
* </pre>
* This ensures that <tt>e1.equals(e2)</tt> implies that
* <tt>e1.hashCode()==e2.hashCode()</tt> for any two Entries
* <tt>e1</tt> and <tt>e2</tt>, as required by the general
* contract of <tt>Object.hashCode</tt>.
*
* #return the hash code value for this map entry
* #see Object#hashCode()
* #see Object#equals(Object)
* #see #equals(Object)
*/
int hashCode();
}
For more information about interfaces, see the Interfaces tutorial and this Static Nested Interfaces article.
Inner interfaces are implicitly public and static.
You can have inner interfaces as follows :
1. interface A {
.....
.....
interface B {
....
....
}
}
2. class A {
....
....
interface B {
....
....
}
}
You can access the above inner interface(B) by A.B where A is a class or an interface according to the above two cases.
For example,
class x implements A.B
{
....
....
}
What is the difference between removeAllElements() and clear() method of DefaultListModel in java swing?
The java docs for DefaultListModel says :-
public void clear()
Removes all of the
elements from this list. The list will
be empty after this call returns
(unless it throws an exception).
and
public void removeAllElements()
Removes all components from this list
and sets its size to zero.
So both basically removes all elements from list so what is the difference? How to decide when to use which?
They are both same.
DefaultListModel uses a Vector under the hood.
The clear() method was added later when Vector was re-written to fit into the Collection API's.
With version 1.3 the Collections API made its' entrance so the Vector was re-written to fit into the List interface.
In order for it to be backwards compatible, they simply forwarded the calls to the old existing methods where available & possible.
EDIT
From Java Source:
/**
* Removes all components from this list and sets its size to zero.
* <blockquote>
* <b>Note:</b> Although this method is not deprecated, the preferred
* method to use is <code>clear</code>, which implements the
* <code>List</code> interface defined in the 1.2 Collections framework.
* </blockquote>
*
* #see #clear()
* #see Vector#removeAllElements()
*/
public void removeAllElements() {
int index1 = delegate.size()-1;
delegate.removeAllElements();
if (index1 >= 0) {
fireIntervalRemoved(this, 0, index1);
}
}
I am getting the following warning from my NetBeans IDE.
Suspicious call to java.util.Collection.contains
Expected type T, actual type Object
May I know what does that means?
This doesn't make sense to me. Both List and Collection class's contains method, are using Object as their method parameter.
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
*
* #author yan-cheng.cheok
*/
public abstract class AbstractCollection<T> implements Collection<T> {
protected List<T> list = new ArrayList<T>();
public boolean contains(Object o) {
// Suspicious call to java.util.Collection.contains
// Expected type T, actual type Object
return list.contains(o);
}
Code snippet from Collection class
/**
* Returns <tt>true</tt> if this collection contains the specified element.
* More formally, returns <tt>true</tt> if and only if this collection
* contains at least one element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* #param o element whose presence in this collection is to be tested
* #return <tt>true</tt> if this collection contains the specified
* element
* #throws ClassCastException if the type of the specified element
* is incompatible with this collection (optional)
* #throws NullPointerException if the specified element is null and this
* collection does not permit null elements (optional)
*/
boolean contains(Object o);
Code snippet from List class
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
* at least one element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* #param o element whose presence in this list is to be tested
* #return <tt>true</tt> if this list contains the specified element
* #throws ClassCastException if the type of the specified element
* is incompatible with this list (optional)
* #throws NullPointerException if the specified element is null and this
* list does not permit null elements (optional)
*/
boolean contains(Object o);
In the call to list.contains you are comparing an object to a type T. Casting o to type T should resolve your warning.
Calling the contains method with an Object instead of the generic type may be a programming error. Since the code is still valid the compiler will only show a warning.
An example why this warning is necessary:
List<Long> l = new ArrayList<Long>();
l.add(1l);
l.contains(1);
The code is valid but would always return false. An error that is normally hidden by contains accepting object instead of a generic type, so the compiler is limited to warnings.
Since there are valid use cases for passing an object, you should be able to use a #SuppressWarnings() annotation to hide this warning (only do this if you know what you are doing).