Interface methods in a class that does not implement it? - java

public interface Iterator<T> {
// Returns true if the iterator is valid (points to an element), false otherwise.
boolean isValid();
// Returns the current element and moves forward. This method can only be called if the iterator is valid. If the iterator points to the last element, it becomes invalid after the call.
T next();
// Returns the current element and moves backwards. This method can only be called if the iterator is valid. If the iterator points to the first element, it becomes invalid after the call.
T prev();
}
In a class that does not implement interface Iterator, how is it possible to create a method that returns Iterator<K>, when you can only create methods for an interface inside a class that implements it?
public class ABC<K> implements EFG<K>{
public Iterator<K> minIt() {
//method body
//return Iterator<K> variable
}
}
The class ABC containing the method minIt() does not implement Iterator<T>
(No classes implement the interface Iterator <T> )

You can use an Anonymous Class that implements the interface:
For instance:
interface Foo<T> {
T foo();
}
class Bar<T> {
T t;
public Foo<T> bar() {
return new Foo<T>() { // <-- Anonymous class implementing `Foo`
public T foo() {
return t;
}
};
}
}
Execution:
Bar<String> b = new Bar<>();
b.t = "hello"; // with a setter in real life
Foo<String> f = b.bar();
f.foo(); // will return "hello"
The other option which I think would be the most common is to use a method that returns the interface, for instance the list interface has an iterator() method even though it itself doesn't implements the Iterator interface.
List<String> list = new ArrayList<>();
Iterator<String> stringIterator = list.iterator();
Here's the implementation

Simple. By making a class that implements it. Note that you have a type that you came up with on your own and you named it Iterator. Given that java.util.Iterator exists, this is a really bad idea. You should pick another name.
public class ABC<K> implements EFG<K> {
// Let's say this contains the items that can be iterated over.
private List<K> list = new ArrayList<K>();
class MyIterator implements my.pkg.Iterator<K> {
private int position = 0;
#Override public boolean isValid() {
return position > -1 && position < list.size();
}
#Override public K next() {
if (!isValid()) throw new NoSuchElementException();
return list.get(position++);
}
#Override public K prev() {
if (!isValid()) throw new NoSuchElementException();
return list.get(position--);
}
}
public Iterator<K> minIt() {
return new MyIterator<K>();
}
}
Note that classes that you put in classes can only be constructed in instance contexts within that class: They have a 'secret' field of your outer's type. Hence why the code in MyIterator can access the list field of your outer class.
Java has 'anonymous inner class literal' syntax which lets you shorten this: Instead of explicitly declaring class MyIterator, you can also write:
public Iterator<K> minIt() {
return new your.pkg.Iterator<K>() {
private int position = 0;
#Override public boolean isValid() {
// same code goes here as the previous snippet
}
};
}
This anonymous inner class form is a lot more common. It's just syntax sugar - a shorter way to write the same thing.

Related

Implementing iterator to an ArrayList

I am having trouble with my code to add iterator support to ArrayList
this is the class i create to implement Iterator
class MyArrayListIterator<E> implements Iterator<E> {
private E[] list = null;
private int currentIndex = 0;
#Override
public boolean hasNext() {
if (currentIndex < list.length) {
return true;
} else {
return false;
}
}
#Override
public E next(){
return list[currentIndex++];
}
}
This must include, which i think i did correct
"list" of type MyArrayList
"currentIndex" of type int, initially at zero
This is my main method for testing
public static void main(String[] args) throws Exception {
MyList<String> names = new MyArrayList<>();
names.add("Steve");
names.add("Frank");
names.add("Heather");
names.add("Chris");
names.add("Oliver");
for (String string : names) { // error at names Can only iterate over an array or an instance of java.lang.Iterable
System.out.println(string);
}
}
}
In the myArrayList i have added as the requirement is Make MyArrayList implement the Iterable interface by adding the iterator() method, which should return an instance of MyArrayListIterator.
public Iterator<E> iterator() {
return new MyArrayListIterator();
}
Please let me know what I am doing wrong.
As already mentioned in the comments, your problem is that you read from list in MyArrayListIterator without initializing it. This causes a NullPointerException.
You can fix this in two different ways:
Make MyArrayListIterator a non-static nested (they are also called inner classes) class of MyArrayList.
By doing so, you get access to all fields of the outer-class, which in this case is MyArrayList. For example, see this code snippet:
public class MyArrayList<E> implements MyList<E> {
private Object[] list = new Object[10];
private int size = 0;
public Iterator<E> iterator(){
return new MyArrayListIterator<>();
}
// more of your implementation...
// This is the inner class
private class MyArrayListIterator<T> implements Iterator<T> {
private int currentIndex = 0;
#Override
public boolean hasNext() {
// Since this is a inner class, we have access to the
// "list" field defined by MyArrayList.
return currentIndex < list.length;
}
#Override
public T next() {
// Since this is a inner class, we have access to the
// "list" field defined by MyArrayList.
return (T) list[currentIndex++];
}
}
}
Make MyArrayListIterator a static nested class or a separate class.
In this case, you don't have access to the fields defined in MyArrayList, which means you have to provide them yourself. This can be done using the constructor.
public class MyArrayList<E> implements MyList<E> {
private Object[] list = new Object[10];
private int size = 0;
public Iterator<E> iterator(){
return new MyArrayListIterator<>((E[])list);
}
// More of your list implementation
// This is a static inner class, which means we do not have access to
// the fields of the outer class.
private static class MyArrayListIterator<T> implements Iterator<T> {
private final T[] elements;
private int currentIndex = 0;
public MyArrayListIterator(T[] elements) {
this.elements = elements;
}
#Override
public boolean hasNext() {
// Since we got the elements as constructor argument, they are not
// null (assuming you did not call it with null as parameter).
return currentIndex < elements.length;
}
#Override
public T next() {
// Since we got the elements as constructor argument, they are not
// null (assuming you did not call it with null as parameter).
return elements[currentIndex++];
}
}
}
For more information on nested classes, see this tutorial by Oracle on nested classes.

why the java generic type is a must when I implement Interator<E>

I wrote this piece of code, and it works fine. but I have a question:
why it should be public class PeekingIterator<E> implements Iterator<E>, not
public class PeekingIterator implements Iterator<E>. I ask this because if I replace E with Integer in the code, it will work. I mean public class PeekingIterator implements Iterator<Integer> is correct.
import java.util.Iterator;
public class PeekingIterator<E> implements Iterator<E> {
private E nextElem;
private boolean hasNextElem;
private Iterator<E> iter;
public PeekingIterator(Iterator<E> iterator) {
iter = iterator;
nextElem = next();
hasNextElem = true;
}
public E peek() {
return nextElem;
}
#Override
public E next() {
if (!hasNextElem) {
throw new RuntimeException();
}
E res = nextElem;
if (hasNext()) {
nextElem = iter.next();
hasNextElem = true;
} else {
hasNextElem = false;
}
return res;
}
#Override
public boolean hasNext() {
return hasNextElem;
}
}
E is an identifier. If you say that class PeekingIterator<E> implements Iterator<E>, the compiler knows that this identifier is a generic type parameter.
This allows you to instantiate PeekingIterator as:
PeekingIterator<Integer> it1 = new PeekingIterator<>();
or
PeekingIterator<String> it2 = new PeekingIterator<>();
i.e. your PeekingIterator class can iterate over any type of elements.
If you declare PeekingIterator as class PeekingIterator implements Iterator<E>, the compiler searches for some type (class or interface) named E. If it doesn't find it, that's a compilation error.
If you declare class PeekingIterator implements Iterator<Integer>, this works, since Integer is a class. This limits your PeekingIterator to always iterate over Integer elements.

Meaning of "this" in this code?

public boolean contains(Object o) {
for (E x : this)
if (x.equals(o))
return true;
return false;
}
Can someone tell me what excatly means "this" in this code? Can I write it without this and how?
Here this represents object on which current method was invoked. For instance if you have a.contains(x) then inside contains method this will return reference to same object as held in a reference variable.
Since you ware able to use this in for-each it means that contains method is placed in class which implements Iterable<E> interface because for-each can iterate only over:
arrays like String[] array = ...; for(String s : array){...}
instances of classes which implement Iterable<E> like List<String> where we can write for(String s : list){...}
To avoid this you can explicitly add to your method parameter of class which contains this method, like
public boolean contains(YourClass yc, Object o) {
//and use that parameter in loop instead of `this`
for (E x : yc)
if (x.equals(o))
return true;
return false;
}
but this means you would need to call such method in a way a.contains(a,x) so it needs to repeat a twice (not to mention it can allow us to pass other instance of our class than a like a.contains(b,x)).
To avoid this repetition we can make contains method static which will allow to invoke it via YourClass.contains(a,x). But this way we need to resign from one of basic OOP concepts - polymorphism - since it doesn't work with static methods.
Compiler solves it using first solution, so it compiles our methods like they would be written (and we actually CAN write methods that way) as
public boolean contains(YourClass this, Object o) {
// ^^^^^^^^^^^^^^
...
}
Then when we write a.contains(x) it is compiled as if we would invoke a.contains(a,x).
this is a object of the class that contains your contains() method. It refers to the object of that class for which the method is executed.
Putting it after the : of an enhanced for loop means that the class that contains this method must implement Iterable<E>, since the enhanced for loop can be used to iterate over either arrays or instances of classes that implement the Iterable interface. This means your class is able to iterate over some collection of E elements. E is probably a generic type parameter`.
In order to write your method without this, you would have to supply a reference to some alternative object that implements Iterable<E>, but I don't see the point of doing that.
What exactly means this in this code?
It is always a reference to the current instance. I assume your class implements the Iterable<T> interface and overrides the Iterator<T> iterator() method from it.
The loop is just a syntax sugar for the enhanced for statement. According to the specification (§14.14.2.):
for ({VariableModifier} UnannType VariableDeclaratorId : Expression)
Statement
The type of the Expression must be Iterable or an array type (§10.1), or a compile-time error occurs.
If the type of Expression is a subtype of Iterable, then the translation is as follows.
If the type of Expression is a subtype of Iterable<X> for some type argument X, then let I be the type java.util.Iterator<X>; otherwise, let I be the raw type Iterator.
The enhanced for statement is equivalent to a basic for statement of the form:
for (I #i = Expression.iterator(); #i.hasNext(); ) {
{VariableModifier} TargetType Identifier = (TargetType) #i.next();
Statement
}
Usually, a class implements the Iterable to provide to an API user the ability of being allowed to iterate over the internal collection hiding the actual implementation.
Can I write it without this and how?
Use the logic you have written for the inner iterator.
Use the implementation of the underlying collection (if it's and it suits).
Choose one of the options mentioned above and rewrite into a standard for.
Keyword this is just a reference to the current object.
Here is a example how can be this used:
public class Person {
public final String name;
public Person(String name) {
// name = name;
// which one is an argument, and which one is class field?
// by default, both are reference on argument
// using "this" to access class field
this.name = name;
}
public void copyFields(Person other) {
// current object's reference is the same as other object reference
// in other words "this" and "other" are the same instances
// example:
// Person p1 = new Person("a");
// Person p2 = p1; // p2 is now pointing on the same memory address
// // as p1, so both are pointing on the same object
// // stored in memory.
// p1.copyFields(p2);
if (this == other) { // copying from self? useless...
return;
}
this.name = other.name;
}
}
Anything that implements Iterable interface has method which returns Iterator instance, which is implicitly used by foreach loop to iterate over items hold by object. Iterator
has methods hasNext() which returns true, if there is another object
in iterable container, relative to current position, and next() which returns
next object or throws NoSuchElementException if there is no next object (last invokation of hasNext() has returned false).
Here is a simple example of Iterable implementation with contains methods:
public class Customer extends Person implements Iterable<Item> {
private final List<Item> list = new LinkedList<>();
public final String name;
public Customer(String name) {
this.name = name;
}
public void add(Item item) {
list.add(item);
}
// implementing iterable interface
#Override
public Iterator<Item> iterator() {
return list.iterator();
}
// some contains implementations
public boolean contains1() {
for (Item item : this) { // customer implements Iterable = OK
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains2() {
for (Item item : list) { // list implements Iterable = OK
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains3(Object o) {
for (Iterator<Item> iter = iterator(); iter.hasNext(); ) {
Item item = iter.next();
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains4(Object o) {
for (Iterator<Item> iter = list.iterator(); iter.hasNext(); ) {
Item item = iter.next();
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains5(Object o) {
Iterator<Item> iter = iterator();
while (iter.hasNext()) {
Item item = iter.next();
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains6(Object o) {
Iterator<Item> iter = list.iterator();
while (iter.hasNext()) {
Item item = iter.next();
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains7(Object o) {
return list.contains(o);
}
}
Methods are defined in classes, not in objects.
But they are (generally) invoked from objects.
Methods - as they are defined in classes - don't know in advance which object will call them.
So there is a mechanism (implemented by a hidden parameter this) by which the object - when calling a method - secretively passes the address of itself to parameter this.
(In other programming languages may be used other names, as Me or self.)
I would put it in points for you
When we create a new instance of a class then the non static methods and non static member fields are part of it. We access these methods and fields using . operator.
All the non static method or member fields has access to this. The this keyword simply is a reference to the current object upon which that method is executed upon.
Any class which implements Iterable interface can be used with enhanced For-Loop.
Enhanced for loop uses a syntax
for (Object object : objectOfIterableType)
If the class implementing Iterable interface is parametized, suppose its E. then its what you have to in your code.
for (E x : this)
It means current class has the behaviour of being iterable and can be iterated on the collection of items it holds. Above statement will be executed for each item in the collection of items of type E represented by by the current object referred by this keyword. In each iteration x will represent an item from those contained items.

Iterable as a return type

I'm having trouble understanding a method. I have methods that I need to fill out, but I don't really understand the first one. How can Iterable be a return type and how is it used ? An example would be great..
#Override
public Iterable<ClientInterface> getNeighbours() {
return null;
}
#Override
public void addNeighbour(ClientInterface newNeighbour){
//TODO Implement me!
}
#Override
public void removeNeighbour(String clientID) {
//TODO Implement me!
}
It looks like your class should have an implementation of Iterable<ClientInterface> as a class member, like ArrayList.
Let's use this as an example:
public class Bus {
private ArrayList<Person> riders;
... //constructors and other methods
public Iterable<Person> getRiders() {
return riders;
}
... //other methods
}
Everything can be a return type: an enum, a class, an interface, an int, an exception etc.
Iterable is an interface which could be used to use the return in a foreach call (that's why you can use for(T something : AnArrayList) because ArrayList<T> implements Iterable<T>)
Now, my answer contains an example:
We have a method getNeighbours which returns Iterable<ClientInterface>
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>();
}
Well, ok since Iterable is just an interface we need to implement methods or use an implementation.
Since it's something which we should do manually we should implement the methods by ourself.
The only method (in Java8, there are 3 methods but we will ignore it) is iterator() which returns an iterator.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
#Override
public Iterator<ClientInterface> iterator()
{
return null;
}
};
}
Iterator is another interface which is used to provide the logic to iterate over the collection, a list of items etc.
We are forced to implements two methods: hasNext and next
hasNext is used to determinate if there are more items to iterate over, next is used to iterate over it.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
#Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
#Override
public boolean hasNext()
{
return false;
}
#Override
public ClientInterface next()
{
return null;
}
};
}
};
}
We here need to remember which was our last position so we would create a field inside our Iterator.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
#Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
private int position;
#Override
public boolean hasNext()
{
return false;
}
#Override
public ClientInterface next()
{
return null;
}
};
}
};
}
Here the problem: What we should iterate? It depends to you, an example could be:
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
#Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
private int position;
private ClientInterface[] items = new ClientInterface[]{new ClientInterface(), new ClientInterface()};
#Override
public boolean hasNext()
{
return position != items.length;
}
#Override
public ClientInterface next()
{
if (!hasNext()) throw new NoSuchElementException();
return items[position++];
}
};
}
};
}
Note here how we created an array of items and used our two methods hasNext and next to provide a way to iterate over it.
Every call of next increment the internal pointer, and our hasNext method just checks if the pointer reached the end of the array.
Collections like ArrayList, LinkedList etc. already did the job for you and better (implements remove method) you can get this iterator by using ArrayList.iterator()
Now you could write something like:
for (ClientInterface el : yourClass.getNeighbours())
{
System.out.println(el);
}
Iterable<T> is an interface. What this means is that when you receive it as a return value from a method, you actually receive an implementation of it. So, although you don't know what the name of that implementation is (the name of the class that implements the Iterable<T> interface), you can still access the methods that it implements, and act upon it.
Some built-in implementations include ArrayList, LinkedList, HashSet, PriorityQueue, and Stack.
When you need to return an interface type, you must return an implementation of it.

error: method does not override or implement a method from a supertype

Building queue implementation based on linked list. Cannot run application because of the two errors:
public class Queue<Integer> implements Iterable<Integer> {
...
public Iterator<Integer> iterator() {
return new ListIterator(first);
}
private class ListIterator<Integer> implements Iterator<Integer> {// error #1
private Node<Integer> current;
public ListIterator(Node<Integer> first) {
current = first;
}
public boolean hasNext(){ return current != null; }
public void remove() { throw new UnsupportedOperationException();}
public int next() { // error #2
if (!hasNext()) throw new NoSuchElementException();
int item = current.item;
current = current.next;
return item;
}
}
}
error #1: error: Queue.ListIterator is not abstract and does not override abstract method next() in Iterator
where Integer is a type-variable:
Integer extends Object declared in class Queue.ListIterator
error #2: error: next() in Queue.ListIterator cannot implement next() in Iterator
return type int is not compatible with Integer
where E,Integer are type-variables:
E extends Object declared in interface Iterator
Integer extends Object declared in class Queue.ListIterator
How to get it working?
Boxing and unboxing in Java simplify code in many places, but method return types is not one of them. The next method must return an Integer, not an int. It must match the generic type parameter exactly.
public Integer next()
Second, you've declared a generic type parameter Integer in your Queue and ListIterator classes that has nothing to do with java.lang.Integer. Remove it:
// here
public class Queue implements Iterable<Integer> {
and
// here
private class ListIterator implements Iterator<Integer> {

Categories