I need some container to keep elements so, if I'll try to get the size()+i element, i'll get element number i. Or with iterator, which starts from the beginning of container after it tries to get the last element? What are the best practicies in both cases? I mean performance and easy useability.
You could create a simple subclass of ArrayList<T> and override the get(int n) method as follows:
public T get(int n)
{
return super.get(n % this.size());
}
As to the iterator, you will need to implement your own, which shouldn't be all that hard.
EDIT:
Assuming your new class is called RingList, here's a sample RingIterator (untested):
public class RingIterator<T> implements Iterator<T>
{
private int cur = 0;
private RingList<T> coll = null;
protected RingIterator(RingList<T> coll) { this.coll = coll; }
public boolean hasNext() { return size() > 0; }
public T next()
{
if (!hasNext())
throw new NoSuchElementException();
int i=cur++;
cur=cur%size();
return coll.get(i);
}
public void remove() { throw new UnsupportedOperationException(); }
}
You would then override the iterator() method in RingList<T> as
public Iterator<T> iterator()
{
return new RingIterator(this);
}
For the first part, just ask for n % list.size() perhaps?
For the iterator part, create a class that wraps an iterator, and when next() returns null, just have it reset the iterator.
Thanks everyone, thats what I've created:
public class RingIterator<E> {
private List<E> _lst;
private ListIterator<E> _lstIter;
public RingIterator(ListIterator<E> iter, List<E> lst) {
super();
_lstIter = iter;
_lst = lst;
}
public E next() {
if(!_lstIter.hasNext())
_lstIter = _lst.listIterator();
return _lstIter.next();
}
public E previous() {
if(!_lstIter.hasPrevious())
_lstIter = _lst.listIterator(_lst.size());
return _lstIter.previous();
}
}
Then get method:
/*
* Returns ring iterator,
* use it with 'ParentClass' type.
*/
public RingIterator<SubClass> getRingIter(int i) {
return new RingIterator(_subs.listIterator(i),_subs);
}
And I use it:
RingIterator<SubClass> ri = _logic.getRingIter(1);
ParentClass ai = ri.next();
I wanted to make only type ParentClass (not SubClass) available via getRingIter, but I don't see a way to do it with no creation of List - convertion of List.
Extend the ArrayList class and implement the get(Integer) method the way you like. I think this is the 'best practice'.
Related
I have created two iterators for an array: the first runs the array by rows (iteratorRow) and then by columns and the second, first by columns and then by rows (iteratorColumn).
I have another class, Matrix, in which I must create two methods for performing iteration (iteratorRowColumn and iteratorColumnRow) that return iterators that have created to be accessible to other classes.
The array must implement the Iterable interface and may be configured (using a Boolean) which of the two iterators it shall be refunded by calling iterator () method.
How can I do that? Do I have to do some getters methods? Something like this?
public Iterator iteratorRowColumn () {
return new iteratorRow;
}
I think that the last sentence of assignment explains a problem very well. I am not sure what part of it is unclear so let me explain in detail:
The array must implement the Iterable interface
public class Matrix<T> implements Iterable<T>
may be configured (using a Boolean)
public Matrix(boolean defaultRowColumnIterator) {
this.defaultRowColumnIterator = defaultRowColumnIterator;
}
which of the two iterators it shall be returning by calling iterator() method
#Override
public Iterator<T> iterator() {
return defaultRowColumnIterator ? iteratorRowColumn() : iteratorColumnRow();
}
Here is a compilable example:
public class Matrix<T> implements Iterable<T> {
T[][] array;
boolean defaultRowColumnIterator;
public Matrix(boolean defaultRowColumnIterator) {
this.defaultRowColumnIterator = defaultRowColumnIterator;
}
// other methods and constructors
public Iterator<T> iteratorRowColumn() {
return null; // your current implementation
}
public Iterator<T> iteratorColumnRow() {
return null; // your current implementation
}
#Override
public Iterator<T> iterator() {
return defaultRowColumnIterator ? iteratorRowColumn() : iteratorColumnRow();
}
}
Something like this:
public class Proba {
Integer[][] array = new Integer[10][10];
public class MyIter implements Iterator<Integer> {
private Integer[] integers;
private int index = 0;;
public MyIter(Integer[] integers) {
this.integers = integers;
}
#Override
public boolean hasNext() {
return index < integers.length -1 ;
}
#Override
public Integer next() {
return integers[index];
}
#Override
public void remove() {
//TODO: remove
}
}
public static void main(String[] args) {
Iterator<Integer> iter = new Proba().getIterator(1);
while (iter.hasNext()) {
System.out.println(iter.next());
}
}
public Iterator<Integer> getIterator(int row) {
return new MyIter(array[row]);
}
}
I'm creating an ArraySetIterator Class and having trouble with the next() method.
I have done some research but nothing seems to work for me. I'm sure its a simple piece of code but I can't seem to figure it out....
private class ArraySetIterator <E> implements Iterator <E> {
private ArraySet<E> set;
private int index = 0;
public ArraySetIterator(ArraySet<E> set) {
this.set = set;
}
public boolean hasNext() {
return (index + 1) < set.size();
}
public E next() {
???
}
public void remove() {
set.remove(index);
}
}
next() should increase the index and return the current element. I addition, it should throw NoSuchElementException if there are no more elements left to iterate over.
This works:
public E next() {
return set.get(index++);
}
You might also want to think about checking to see if hasNext() is true.
EDIT: Based on your comment, it sounds like your ArraySet is only implementing the Set interface. So you can't use .get(). I think you need do do something like this instead:
private class ArraySetIterator <E> implements Iterator <E> {
private E[] set;
private int index = 0;
public ArraySetIterator(ArraySet<E> set) {
this.set = (E[]) set.toArray();
}
public boolean hasNext() {
return (index + 1) < set.length;
}
public E next() {
if(hasNext) {
return set[index++];
} else {
throw new NoSuchElementException();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
I am trying to implement the next() method through an interface, however it is giving me an error. Here is what I have:
private class MyIterator implements Iterator<Term>
{
private final Polynomial myArray;
private int current;
MyIterator(Polynomial myArray) {
this.myArray = myArray;
this.current = myArray.degree;
}
#Override
public boolean hasNext() {
return current < myArray.degree;
}
#Override
public Integer next() { //this method right here does not work
if (! hasNext()) throw new UnsupportedOperationException();;
return myArray.coeff[current++];
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
The next() method then throws me this error :
And this is my interface:
public interface Term {
int coeff();
int exp();
String toString();
}
So my question is why the interface does not allow the MyIterator to implement the next() method
Your class is implementing Iterator<Term>, so next() must return a Term, not an Integer.
Edit: This line
if (! hasNext()) throw new UnsupportedOperationException();;
is wrong. If the Iterator has no more items, next() must throw a NoSuchElementException.
The Iterator<Term> promises that your iterator will return references of type Term, but your next() method attempts to return Integer.
One of the two things needs to change to be consistent with the other one.
It's useful to me to have a data structure in Java that has all the functionality of a List, but has a maximum storage capacity, and drops older data when newer data is added. Conceivably at some point I might want to implement a fixed size Queue which keeps a more general ordering of the data, and drops the old data lowest in that ordering, but that's the for the future.
At the moment I'm implementing it like this:
public class FixedSizeList<T> {
private final int maxSize;
private final LinkedList<T> list = new LinkedList<T>();
public FixedSizeQueue(int maxSize) {
this.maxSize = maxSize < 0 ? 0 : maxSize;
}
public T add(T t) {
list.add(t);
return list.size() > maxSize ? list.remove() : null;
}
// add remaining methods...
}
Is there either (a) an existing data structure that serves my needs, or (b) a better way of implementing this data structure?
I would use array and 2 indexes for head and tail of the list.Make sure that head is always < tail and you're safe.
Here's a List with a size limit, based on Guava's ForwardingList:
A list which forwards all its method
calls to another list. Subclasses
should override one or more methods to
modify the behavior of the backing
list as desired per the decorator
pattern.
Guava has base classes like this for all JDK-5 Collection types. Each of them fulfills the same purpose: making it easy to add value, while delegating all default functionality to the underlying collection.
public class LimitingList<E> extends ForwardingList<E> {
private final class LimitingListIterator extends ForwardingListIterator<E> {
private final ListIterator<E> innerListIterator;
private LimitingListIterator(final ListIterator<E> innerListIterator) {
this.innerListIterator = innerListIterator;
}
/**
* {#inheritDoc}
*/
#Override
public void add(final E element) {
if (inner.size() < maxSize)
innerListIterator.add(element);
else
throw new IndexOutOfBoundsException();
}
#Override
protected ListIterator<E> delegate() {
return innerListIterator;
}
}
public LimitingList(final int maxSize) {
this(new ArrayList<E>(), maxSize);
}
public LimitingList(final List<E> inner, final int maxSize) {
super();
this.inner = inner;
this.maxSize = maxSize;
}
#Override
public boolean addAll(final Collection<? extends E> collection) {
boolean changed = false;
for (final E item : collection) {
final boolean tmpChanged = add(item);
changed = changed || tmpChanged;
if (!tmpChanged)
break;
}
return changed;
}
#Override
public boolean add(final E e) {
if (inner.size() < maxSize)
return super.add(e);
else
return false;
}
#Override
public ListIterator<E> listIterator() {
return new LimitingListIterator(inner.listIterator());
}
#Override
public void add(final int index, final E element) {
throw new UnsupportedOperationException();
}
#Override
public boolean addAll(final int index, final Collection<? extends E> elements) {
throw new UnsupportedOperationException();
}
#Override
public ListIterator<E> listIterator(final int index) {
return new LimitingListIterator(inner.listIterator(index));
}
private final int maxSize;
private final List<E> inner;
#Override
protected List<E> delegate() {
return inner;
}
}
It delegates all real functionality to an underlying list, which is an ArrayList per default (single argument constructor), but you can also supply (two argument constructor)
Unless you want to use an actual array, I don't believe there is a list type data structure you can use.
Personally I would extend one of the existing list classes to get the functionality, and override the add methods. This way you get all the other list operations for free. ie something like the following...
public class FixedSizeArrayList<T> extends ArrayList<T> {
private final int maxSize;
public FixedSizeArrayList(int maxSize) {
super();
this.maxSize = maxSize
}
public boolean add(T t) {
if (size() >= maxSize) {
remove(0);
}
return super.add(t);
}
// implementation of remaining add methods....
}
If you extend the LinkedList class you will have direct access to all it's methods. Instead of having to write stuff like
fixedList.getList().pop()
you could just write
fixedList.pop()
You could then override the methods where you need to add the maxSize criteria.
If I have a list containing [alice, bob, abigail, charlie] and I want to write an iterator such that it iterates over elements that begin with 'a', can I write my own ? How can I do that ?
The best reusable option is to implement the interface Iterable and override the method iterator().
Here's an example of a an ArrayList like class implementing the interface, in which you override the method Iterator().
import java.util.Iterator;
public class SOList<Type> implements Iterable<Type> {
private Type[] arrayList;
private int currentSize;
public SOList(Type[] newArray) {
this.arrayList = newArray;
this.currentSize = arrayList.length;
}
#Override
public Iterator<Type> iterator() {
Iterator<Type> it = new Iterator<Type>() {
private int currentIndex = 0;
#Override
public boolean hasNext() {
return currentIndex < currentSize && arrayList[currentIndex] != null;
}
#Override
public Type next() {
return arrayList[currentIndex++];
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
return it;
}
}
This class implements the Iterable interface using Generics. Considering you have elements to the array, you will be able to get an instance of an Iterator, which is the needed instance used by the "foreach" loop, for instance.
You can just create an anonymous instance of the iterator without creating extending Iterator and take advantage of the value of currentSize to verify up to where you can navigate over the array (let's say you created an array with capacity of 10, but you have only 2 elements at 0 and 1). The instance will have its owner counter of where it is and all you need to do is to play with hasNext(), which verifies if the current value is not null, and the next(), which will return the instance of your currentIndex. Below is an example of using this API...
public static void main(String[] args) {
// create an array of type Integer
Integer[] numbers = new Integer[]{1, 2, 3, 4, 5};
// create your list and hold the values.
SOList<Integer> stackOverflowList = new SOList<Integer>(numbers);
// Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
for(Integer num : stackOverflowList) {
System.out.print(num);
}
// creating an array of Strings
String[] languages = new String[]{"C", "C++", "Java", "Python", "Scala"};
// create your list and hold the values using the same list implementation.
SOList<String> languagesList = new SOList<String>(languages);
System.out.println("");
// Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
for(String lang : languagesList) {
System.out.println(lang);
}
}
// will print "12345
//C
//C++
//Java
//Python
//Scala
If you want, you can iterate over it as well using the Iterator instance:
// navigating the iterator
while (allNumbers.hasNext()) {
Integer value = allNumbers.next();
if (allNumbers.hasNext()) {
System.out.print(value + ", ");
} else {
System.out.print(value);
}
}
// will print 1, 2, 3, 4, 5
The foreach documentation is located at http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html. You can take a look at a more complete implementation at my personal practice google code.
Now, to get the effects of what you need I think you need to plug a concept of a filter in the Iterator... Since the iterator depends on the next values, it would be hard to return true on hasNext(), and then filter the next() implementation with a value that does not start with a char "a" for instance. I think you need to play around with a secondary Interator based on a filtered list with the values with the given filter.
Sure. An iterator is just an implementation of the java.util.Iterator interface. If you're using an existing iterable object (say, a LinkedList) from java.util, you'll need to either subclass it and override its iterator function so that you return your own, or provide a means of wrapping a standard iterator in your special Iterator instance (which has the advantage of being more broadly used), etc.
Good example for Iterable to compute factorial
FactorialIterable fi = new FactorialIterable(10);
Iterator<Integer> iterator = fi.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
Short code for Java 1.8
new FactorialIterable(5).forEach(System.out::println);
Custom Iterable class
public class FactorialIterable implements Iterable<Integer> {
private final FactorialIterator factorialIterator;
public FactorialIterable(Integer value) {
factorialIterator = new FactorialIterator(value);
}
#Override
public Iterator<Integer> iterator() {
return factorialIterator;
}
#Override
public void forEach(Consumer<? super Integer> action) {
Objects.requireNonNull(action);
Integer last = 0;
for (Integer t : this) {
last = t;
}
action.accept(last);
}
}
Custom Iterator class
public class FactorialIterator implements Iterator<Integer> {
private final Integer mNumber;
private Integer mPosition;
private Integer mFactorial;
public FactorialIterator(Integer number) {
this.mNumber = number;
this.mPosition = 1;
this.mFactorial = 1;
}
#Override
public boolean hasNext() {
return mPosition <= mNumber;
}
#Override
public Integer next() {
if (!hasNext())
return 0;
mFactorial = mFactorial * mPosition;
mPosition++;
return mFactorial;
}
}
This is the complete code to write an iterator such that it iterates over elements that begin with 'a':
import java.util.Iterator;
public class AppDemo {
public static void main(String args[]) {
Bag<String> bag1 = new Bag<>();
bag1.add("alice");
bag1.add("bob");
bag1.add("abigail");
bag1.add("charlie");
for (Iterator<String> it1 = bag1.iterator(); it1.hasNext();) {
String s = it1.next();
if (s != null)
System.out.println(s);
}
}
}
Custom Iterator class
import java.util.ArrayList;
import java.util.Iterator;
public class Bag<T> {
private ArrayList<T> data;
public Bag() {
data = new ArrayList<>();
}
public void add(T e) {
data.add(e);
}
public Iterator<T> iterator() {
return new BagIterator();
}
public class BagIterator<T> implements Iterator<T> {
private int index;
private String str;
public BagIterator() {
index = 0;
}
#Override
public boolean hasNext() {
return index < data.size();
}
#Override
public T next() {
str = (String) data.get(index);
if (str.startsWith("a"))
return (T) data.get(index++);
index++;
return null;
}
}
}
You can implement your own Iterator. Your iterator could be constructed to wrap the Iterator returned by the List, or you could keep a cursor and use the List's get(int index) method. You just have to add logic to your Iterator's next method AND the hasNext method to take into account your filtering criteria. You will also have to decide if your iterator will support the remove operation.
Here is the complete answer to the question.
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
class ListIterator implements Iterator<String>{
List<String> list;
int pos = 0;
public ListIterator(List<String> list) {
this.list = list;
}
#Override
public boolean hasNext() {
while(pos < list.size()){
if (list.get(pos).startsWith("a"))
return true;
pos++;
}
return false;
}
#Override
public String next() {
if (hasNext())
return list.get(pos++);
throw new NoSuchElementException();
}
}
public class IteratorTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("alice", "bob", "abigail", "charlie");
ListIterator itr = new ListIterator(list);
while(itr.hasNext())
System.out.println(itr.next()); // prints alice, abigail
}
}
ListIterator is the iterator for the array which returns the elements that start with 'a'.
There is no need for implementing an Iterable interface. But that is a possibility.
There is no need to implement this generically.
It fully satisfies the contract for hasNext() and next(). ie if hasNext() says there are still elements, next() will return those elements. And if hasNext() says no more elements, it returns a valid NoSuchElementException exception.