We have inner class
class OuterClass
{
public Iterator getIterator(final String name)
{
class LocalIterator implements Iterator
{
public Iterator next()
{
return new LocalIterator();
}
}
return new LocalIterator();
}
}
Is it possible to make an anonymous class with all functionality of Local iterator and make getIterator return object of that anonymous class? The main problem is - what should be instead of
return new LocalIterator();
Im not sure if I understand your question correctly. But if you want to use an anonymous class you can do:
class OuterClass {
public Iterator<Object> getIterator(final String name) {
return new Iterator<Object>() {
#Override
public boolean hasNext() {
// validate if there is a next object
return false;
}
#Override
public Object next() {
// get the next object and return it, throw an exception if there is no next object
return null;
}
};
}
}
In general, you are always able to create an instance of any interface using anonymous classes (see, e.g., http://docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm). You also have access to the name parameter within the class and to the this instance of the outer class using OuterClass.this.
You should give this design pattern a try:
class OuterClass implements Iterable {
....
public Iterator iterator() {
return new Itr();
}
private class Itr implements Iterator {
....
}
}
it doesn't expose iterator implementation
it is easy to read and maintain this code
Itr instances can be used everywhere as a common Iterator
Make sure OuterClass implements Iterable in order to be usable with the foreach loop. Then in iterator() you could return an instance of an anonymous iterator (replace T with the concrete type you need).
public class OuterClass<T> implements Iterable<T> {
#Override
public Iterator<T> iterator() {
return new Iterator<T>() {
#Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
#Override
public T next() {
// TODO Auto-generated method stub
return null;
}
};
}
}
Related
I'm trying out Interfaces in java and I want to implement a common interface for a really simple stack, with pop() and push() methods and an iterator.
The problem is that I don't know how to specify the iterator in the interface. No matter which way I try, I get
Main.java:32: error: for-each not applicable to expression type
for (Integer i : ss)
^
required: array or java.lang.Iterable
found: Stack<Integer>
The code is as follows:
interface Stack<T> {
boolean push(T t);
boolean pop();
//Iterator<T> iterator(); // How to indicate it needs, and will have, an iterator?
}
public class DynamicStack<T> implements Iterable<T>, Stack<T>
{
// implementation-specific variables go here
public DynamicStack() {
//...
}
public boolean push(T t) {
//...
}
public boolean pop() {
//...
}
private class StackIterator implements Iterator<T> {
DynamicStack<T> stk;
//...
// Iterator constructor
private StackIterator(DynamicStack<T> stk)
{
//...
}
public boolean hasNext()
{
//...
}
public T next() throws NoSuchElementException
{
//...
}
public void remove() throws UnsupportedOperationException
{
throw new UnsupportedOperationException(); // I chose not to implement this one
}
}
// Iterator method
public Iterator<T> iterator()
{
return new StackIterator(this);
}
}
public class StaticStack<T> implements Iterable<T>, Stack<T>
{
// implementation-specific variables go here
public StaticStack()
{
//...
}
public boolean push(T t)
{
//...
}
public boolean pop()
{
//...
}
private class StackIterator implements Iterator<T>
{
StaticStack<T> stk;
//...
private StackIterator(StaticStack<T> stk)
{
//...
}
public boolean hasNext()
{
//...
}
public T next() throws NoSuchElementException
{
//...
}
public void remove() throws UnsupportedOperationException
{
//...
}
}
// Iterator method
public Iterator<T> iterator()
{
return new StackIterator(this);
}
}
Main simply does this, after creating a few stacks of each type and adding a few elements:
public static void showStuff(Stack<Integer> ss)
{
for (Integer i : ss)
System.out.print(i+" ");
System.out.println();
}
In your test class, you are operating against Stack interface, so that is the one that needs to conform to Iterable. In this case it doesn't help if StaticStack or DynamicStack implement it if Stack does not.
To get Stack to be able to be used as Iterable just change your Stack to extend Iterable:
public interface Stack<T> extends Iterable<T> {
boolean push(T t);
boolean pop();
}
and
public class StaticStack<T> implements Stack<T>
and the code runs just fine:
public class Tester {
public static void main(String args[]) {
Stack<Integer> ss = new StaticStack<>();
for (Integer i : ss)
System.out.print(i+" ");
System.out.println();
}
}
You need you class to implement Iterable<T>, which has the iterator() method, which returns Iterator<T>.
Normally when you implement a generic, you have some type T that you want to generalize. I want to write a class that generalizes a HashSet<T>.
I'm trying to write this the following way, but it's not the correct syntax or maybe it's not supported:
public class PermutationHelper<T> implements Iterable<T> {
private HashSet<T> m_set;
private long numberOfPermutations;
private boolean includeEmptyPermutationAsOutput = false;
public PermutationHelper(HashSet<T> set) {
m_set = set;
numberOfPermutations = 2 ^ set.size();
}
public void setIncludeEmptyPermutationAsOutput(boolean value) {
includeEmptyPermutationAsOutput = value;
}
#Override
public Iterator<T> iterator() {
Iterator<T> it = new Iterator<T>() {
long currentIndex = (includeEmptyPermutationAsOutput ? 0 : 1);
#Override
public boolean hasNext() {
return currentIndex < numberOfPermutations;
}
#Override
public T next() {
HashSet<T> result = new HashSet<T>();
return result; // expects T, but is a HashSet<T>..
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
return it;
}
}
I want the Iterator to give me all subsets of the passed-in HashSet<T>.
You can easly do
public class PermutationHelper<T extends HashSet<T>> implements Iterable<T>
in order to 'force' the generic type to be an HashSet or a subtype of a HashSet
What you want is simply
public class PermutationHelper<T> implements Iterable<HashSet<T>>
Your class is generic. You choose to name its generic type T. And it implements Iterable<HashSet<T>>, which means it must have a method
public Iterator<HashSet<T>> iterator()
I want to subclass Iterator into what I'll call FooIterator. My code looks something like this:
public class FooIterator<E> implements Iterator<E> {
public FooIterator(Collection<Bar> bars) {
innerIterator = bars.iterator();
}
#Override
public boolean hasNext() {
return innerIterator.hasNext();
}
#SuppressWarnings("unchecked")
#Override
public E next() {
Bar bar = innerIterator.next();
return new E(bar);
}
#Override
public void remove() {
throw new UnsupportedOperationException("Don't remove from FooIterator!");
}
private Iterator<Bar> innerIterator;
}
...except, of course, this doesn't work because I can't instantiate a new E from a Bar.
I would only ever use this with an E that has a constructor that takes a Bar. Is there any way to "prove" that to the compiler, or to just throw a runtime error if E doesn't have an appropriate constructor?
Or perhaps I'm just not using the right design pattern here? I've been doing a lot of C++ recently, and I feel like I might be approaching this the wrong way.
This is a somewhat convoluted approach but it could work and would be type safe (solutions using reflection won't). It basically consists in delegating the construction of an E from a Bar to a separate class. You could have a BarConverter interface:
interface BarConverter<E> {
E convert (Bar bar);
}
Then your class could become:
public class FooIterator<E> implements Iterator<E> {
public FooIterator(Collection<Bar> bars, BarConverter<E> converter) {
innerIterator = bars.iterator();
this.converter = converter;
}
#Override
public E next() {
Bar bar = innerIterator.next();
return converter(bar);
}
}
It is not possible to instantiate a type parameter like that.
A workaround is to pass the Class<E> type parameter in the constructor, along with the Collection<Bar>:
private Class<E> clazz;
public FooIterator(Collection<Bar> bars, Class<E> clazz) {
this.clazz = clazz;
innerIterator = bars.iterator();
}
And then in next() method, you can make use of reflection to create instance of E:
#SuppressWarnings("unchecked")
#Override
public E next() {
Bar bar = innerIterator.next();
E instance = null;
try {
instance = clazz.getConstructor(Bar.class).newInstance(bar);
} catch (Exception e) {
e.printStackTrace();
}
if (instance == null) {
// throw an unchecked exception
}
return instance;
}
P.S: You should in general do a better exception handling, than I've used here. I've just catched all the exception in Exception for brevity. In practice, you should have catch block for each specific exception.
Also, rather than using e.printStackTrace(), you can log some helpful message.
While instantiating FooIterator, you need to pass an extra argument - the class for which you are creating the iterator.
This feels a bit hacky, but with an interface and a method which simply constructs itself, you could do this:
interface Barable
{
Barable construct(Barable bar);
}
class Bar implements Barable
{
Bar(Barable bar)
{
//Do stuff
}
#Override
public Barable construct(Barable bar)
{
return new Bar(bar);
}
}
class FooIterator<E extends Barable> implements Iterator<E>
{
public FooIterator(Collection<Bar> bars)
{
innerIterator = bars.iterator();
}
#Override
public boolean hasNext()
{
return innerIterator.hasNext();
}
#SuppressWarnings("unchecked")
#Override
public E next()
{
Bar bar = innerIterator.next();
return (E) bar.construct(bar);
}
#Override
public void remove()
{
throw new UnsupportedOperationException("Don't remove from FooIterator!");
}
private Iterator<Bar> innerIterator;
}
A possible solution could be to parameterize Bar and add a method to it to create a new E. Something like this:
class Bar<E> {
// ... more implementation ...
public E build() {
// create your `E` object here
}
}
and then your code would do something like this:
public class FooIterator<E> implements Iterator<E> {
public FooIterator(Collection<Bar<E>> bars) {
innerIterator = bars.iterator();
}
#Override
public boolean hasNext() {
return innerIterator.hasNext();
}
#SuppressWarnings("unchecked")
#Override
public E next() {
Bar<E> bar = innerIterator.next();
return bar.build();
}
#Override
public void remove() {
throw new UnsupportedOperationException("Don't remove from FooIterator!");
}
private Iterator<Bar<E>> innerIterator;
}
How do I throw and UnsupportedOperationException on a method? So if I have an Iterable object and I'm trying to disallow the remove method for that object.
In the method below I'm returning an iterable object whose iterator's remove I need to disable by throwing an UnsupportedErrorException. Can I do this within the body of the method or how so?
public Iterable<String> getInNodes (String destinationNodeName) {
if (!hasNode(destinationNodeName))
return emptySetOfString;
else {
for(String e : nodeMap.get(destinationNodeName).inNodes)
{
emptySetOfString.add(e);
}
return emptySetOfString;
}
}
Try this.
#Override
public void remove() {
throw new UnsupportedOperationException();
}
I may have misunderstood your question.
If you have a normal Iterable, and you want to convert it to an Iterable that generates iterators on which remove can not be called, you can use this monstrosity made possible by anonymous subclassing:
Iterable<String> iterable = // normal Iterable<String> you already have...
Iterable<String> noRemoveIteratorGeneratingIterable = new Iterable<String>() {
#Override
public Iterator<String> iterator() {
return new Iterator<String>() {
Iterator<String> internalIterator = iterable.iterator();
#Override
public boolean hasNext() {
return internalIterator.hasNext();
}
#Override
public String next() {
return internalIterator.next();
}
#Override
public void remove() {
throw new UnsupportedOperationException("Nope!");
}
};
}
};
In your class you can just #Override the original method
public class myIterable extends Iterable {
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Then create Objects of this class instead of original Iterable.
You can try throwing the message with appropriate message as well:
public void remove() {
throw new UnsupportedOperationException("Remove is unsupported on this object");
}
I am trying to understand Java Iterator and Iterable interfaces
I am writing this class
class MyClass implements Iterable<String> {
public String[] a = null;
public MyClass(String[] arr) {
a = arr;
}
public MyClassIterator iterator() {
return new MyClassIterator(this);
}
public class MyClassIterator implements Iterator<String> {
private MyClass myclass = null;
private int count = 0;
public MyClassIterator(MyClass m) {
myclass = m;
}
public boolean hasNext() {
return count < myclass.a.length;
}
public String next() {
int t = count;
count++;
return myclass.a[t];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
It seems to be working.
Should I have:
Myclass implements Iterable<Stirng>, Iterator<String> {
}
Or I should put MyClassIterator outside MyClass as
class MyClass implements Iterable<String> {
public String[] a = null;
public MyClass(String[] arr) {
a = arr;
}
public MyClassIterator iterator() {
return new MyClassIterator(this);
}
}
public class MyClassIterator implements Iterator<String> {
private MyClass myclass = null;
private int count = 0;
public MyClassIterator(MyClass m) {
myclass = m;
}
public boolean hasNext() {
return count < myclass.a.length;
}
public String next() {
int t = count;
count++;
return myclass.a[t];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Which one is better?
You should almost never implement both Iterable and Iterator in the same class. They do different things. An iterator is naturally stateful - as you iterate using it, it has to update its view of the world. An iterable, however, only needs to be able to create new iterators. In particular, you could have several iterators working over the same original iterable at the same time.
Your current approach is pretty much okay - there are aspects of the implementation I'd change, but it's fine in terms of the separation of responsibilities.
You were on track with your first try. MyClass only needs to implement Iterable<String>, which in turn requires you to provide an Iterator<String> implementation to return from Iterable<String>.iterator().
There's no need to put the MyClassIterator outside of MyClass because in most cases you will never even need to directly use the Iterator<String> (it's used implicitly by the for .. in .. syntax on Iterable<String>s), and in all other cases the interface is sufficient unless you actually add additional behavior to the implementation (which you likely won't ever need to do).
Here's how I'd do it, see comments inlined:
import java.util.Iterator;
class MyClass implements Iterable<String>{
public String[] a=null; //make this final if you can
public MyClass(String[] arr){
a=arr; //maybe you should copy this array, for fear of external modification
}
//the interface is sufficient here, the outside world doesn't need to know
//about your concrete implementation.
public Iterator<String> iterator(){
//no point implementing a whole class for something only used once
return new Iterator<String>() {
private int count=0;
//no need to have constructor which takes MyClass, (non-static) inner class has access to instance members
public boolean hasNext(){
//simplify
return count < a.length;
}
public String next(){
return a[count++]; //getting clever
}
public void remove(){
throw new UnsupportedOperationException();
}
};
}
}
You should not do Myclass implements Iterable<String>,Iterator<String>{ since iterators are single-use. With the exception of list iterators, there's no way to return them to the start.
Incidentally, you can skip the
MyClass myClass;
public MyClassInterator(MyClass m){
myclass=m;
}
and instead of referencing
myClass
reference
MyClass.this
Your inner class is not static, so MyClass.this will reference the instance of the enclosing class that created it.