throw an exception on a method call - java

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");
}

Related

How to implement an interface for two classes with an iterator

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>.

How to create a custom Iterator in Java?

I've this problem:
Given the iterable class Foo, which keeps always only one int
value which is set on its constructor, make an iterator so it
respects all of its restrictions which are: you can't change the int
value after its initialization. You should include only the required
exceptions to be thrown.
Ok, so far, if I understood the question the right way, I should create an iterator for that Foo class, however I've never done this before and it seems to be that the question itself is a bit misleading. Is it a list? Or shouldn't it be? Anyway, despite that, all I want to know is how to create it.
So now I've this:
public class Foo implements Iterable<Foo> {
#Override
public Iterator<Foo> iterator() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
But I don't even know if this is the right way to do so.
I'd be very appreciated if someone could help me out with this.
Thank you in advance.
A minimal example would be to return an empty iterator, whose hasNext() always returns false and next() will throw NoSuchElementException.
public Iterator<Foo> iterator() {
return new Iterator<Foo>() {
public boolean hasNext() {
return false;
}
public Foo next() {
throw new NoSuchElementException();
}
};
}
Of course most iterators have states. For example you can iterate from 0 to the integer value the Foo instance holds.
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Foo implements Iterable<Foo> {
private final int value;
public Foo(final int value) {
this.value = value;
}
#Override
public Iterator<Foo> iterator() {
return new Iterator<Foo>() {
private Foo foo = new Foo(0);
#Override
public boolean hasNext() {
return foo.value < Foo.this.value;
}
#Override
public Foo next() {
if (!hasNext()) throw new NoSuchElementException();
Foo cur = foo;
foo = new Foo(cur.value+1);
return cur;
}
};
}
public static void main(String[] args) {
Foo foo = new Foo(10);
for (Foo f: foo) {
System.out.println(f.value);
}
}
}

Create object of anonymous class

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;
}
};
}
}

Making assumptions about type parameters?

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;
}

java generic array with iterator

I have a code like the following.
public class DefaultIterator<E> implements Iterator<E> {
private E[] array;
private int i = 0;
public DefaultIterator(E[] array) {
this.array = array;
}
#Override
public boolean hasNext() {
return false;
}
#Override
public E next() {
return array[i++];
}
#Override
public void remove() {
}
}
// here is my execution.
public Iterator<String> createNewIterator(Iterator<String>... generalIterators) {
return new DefaultIterator<Iterator<String>[]>(generalIterators);
}
I am getting the compilation error at the execution code. can somebody explain why it is failing and how to fix it?
Thanks.
So the complaint is that none of the generic types match up between the field declaration, the constructor declaration, and the method declaration.
You want:
public Iterator<String> createNewIterator(String... generalIterators) {
return new DefaultIterator<String>(generalIterators);
}
Your return type is another one than expected! DefaultIterator<Iterator<String>[]> isn't compatible with Iterator<String> Choose DefaultIterator<Iterator<String>[]> as your return type, this should solve it.

Categories

Resources