I would like to write a class(called Seii) that is basically a sequence of whole numbers starting from s0. s0 is set in the constructor:
se + 1 = 3*(se/2)
The catch is: A for-loop should be able to iterate through the objects of this class and spit out the elements of the sequence (without the starting number s0). Also, the sequence ends with the first element larger than 42.
For example:
for(int i:new Seii(2)){
System.out.println(i)
gives out:
3,4,6,9,10,15,16,24,36,54
I would like to do it using iterators. Can someone pls help me out?
My idea would be to rewrite the next() method so that it does the calculation for the next element of the sequence, but i'm not getting anywhere with the logic of this.
public class Seii<T> implements Iterator {
private ArrayList<Integer> list = new ArrayList<>();
Iterator<Integer> it = list.iterator();
private final int size;
public Seii(int size) {
this.size = size;
}
int seii = 0;
#Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
#Override
public Object next() {
if ((size % 2) == 0) {
seii = 3 * (seii/2);
return seii;
}
}
}
}
This is my implementation.
Seii should implement Iterable<Integer>, which will allow it to support the enhanced for loop syntax. The easiest way of doing that, IMHO, is just to have an inner Iterator class which implements your logic:
public class Seii implements Iterable<Integer> {
private class SeiiIterator implements Iterator<Integer> {
#Override
public boolean hasNext() {
return value <= 42;
}
#Override
public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
value = 3 * (value / 2);
return value;
}
}
private int value;
public Seii(int value) {
this.value = value;
}
#Override
public Iterator<Integer> iterator() {
return new SeiiIterator();
}
}
You do not need to store the sequence, so the array list can be removed from your implementation. All you need is the last value, which can be set in the constructor:
// This is a wrapper class that constructs iterators.
// It is used for plugging in your code into enhanced "for" loop
class Seii implements Iterable<Integer> {
private int current;
private int max;
public Seii(int current, int max) {
this.current = current;
this.max = max;
}
#Override
public Iterator<Integer> iterator() {
return new SeiIterator(current, max);
}
}
// This is the actual iterator that maintains state
// and produces the desired sequence.
class SeiIterator implements Iterator<Integer> {
private int current;
private int max;
public SeiIterator(int current, int max) {
this.current = current;
this.max = max;
}
#Override
public boolean hasNext() {
return current < max;
}
#Override
public Integer next() {
current = (3*current)/2;
return current;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Note that in order to use your iterator in an enhanced for loop you need to wrap it in an Iterable<Integer>.
Demo.
Your Seii class should implement Iterable<Integer> not Iterator, since that's the interface required by the enhanced for loop. It would have an iterator method that returns an instance of a class that implements the Iterator<Integer> interface.
Related
I'm working in a school project, where I want to implement the Iterator design pattern. I want to use generic arrays.
Container.java
public interface Container {
Iterator getIterator();
}
Iterator.java
public interface Iterator <T> {
boolean hasNext();
T next();
}
TransactionRepository.java
public class TransactionRepository<T> implements Container {
public TransactionRepository(){
userTransactions = new ArrayList<>();
}
public List<T> userTransactions;
#Override
public Iterator <T> getIterator() {
return new UserTransactions();
}
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
private class UserTransactions implements Iterator <T> {
int index;
#Override
public boolean hasNext() {
return index < userTransactions.size();
}
#Override
public T next() {
if(this.hasNext())
return userTransactions.get(index);
return null;
}
}
}
In my other class, I add the elements to the list by first creating the TransactionRepository object like this: TransactionRepository<String> companyName = new TransactionRepository<String>();.
Then I add elements to the array with the add method companyName.add("CompanyName");. After that I want to print the array using Iterator, but It just won't print the elements. I have tried multiple variations, but none of them worked.
Iterator <String> stringIterator = companyName.getIterator();
while (stringIterator.hasNext()) {
System.out.println("Name : " + companyName.get());
}
With the current implementation List<T> userTransactions is never updated.
In this case userTransactions.size() in hasNext() method will always return 0 so the result of method will be false.
Moreover, you should use stringIterator.next() instead of companyName.get(). Since you implement your own iterator you don't want to use get() method at all.
There is also a need to update index counter variable after calling next() method.
#Override
public T next() {
if (this.hasNext())
return userTransactions.get(index++);
return null;
}
Change modifier on userTransactions to private final as it should be referenced just with iterator.
Code with proposed improvements:
public class TransactionRepository<T> implements Container {
public TransactionRepository() {
userTransactions = new ArrayList<>();
}
public List<T> userTransactions;
#Override
public Iterator<T> getIterator() {
return new UserTransactions();
}
public void add(T t) {
userTransactions.add(t);
}
private class UserTransactions implements Iterator<T> {
int index;
#Override
public boolean hasNext() {
return index < userTransactions.size();
}
#Override
public T next() {
if (this.hasNext()) {
return userTransactions.get(index++);
}
return null;
}
}
}
It seems that you are never adding elements to your userTransactions List on the add method
You add() method doesnt add anything to your list , it's just like a setter of the attribute t , you should use it to add elements to the list instead
public void add(T t) {
userTransactions.add(t);
}
There is also another problem , the index , your next() method gets the index element while you didnt initialise your index variable , i recommand you to do it in this way :
int index = 0 ;
...
public T next() {
if(this.hasNext())
int temp = index;
index++;
return userTransactions.get(temp);
return null;
}
Here is my test :
public static List<String> list =new Vector<String>();
#Test
public void main(){
new ThreadOne().start();
new ThreadTwo().start();
}
public static void printAll(){
String valueString= null;
Iterator<String> iterator=list.iterator();
while(iterator.hasNext()){
valueString = (String) iterator.next();
System.out.print(valueString+",");
}
System.out.println("\n");
}
public static class ThreadOne extends Thread{
public void run(){
int i=10;
while(i<100000){
list.add(String.valueOf(i));
printAll();
i++;
}
}
}
public static class ThreadTwo extends Thread{
public void run(){
int i=0;
while(i<100000){
list.add(String.valueOf(i));
printAll();
i++;
}
}
}
and I saw the source code in about the iterator in Vector.class:
public synchronized Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
// Racy but within spec, since modifications are checked
// within or after synchronization in next/previous
return cursor != elementCount;
}
public E next() {
synchronized (Vector.this) {
checkForComodification();
int i = cursor;
if (i >= elementCount)
throw new NoSuchElementException();
cursor = i + 1;
return elementData(lastRet = i);
}
}
I was confuced about it.When the program carried out the iterator.next(),
the vector Object was locked,While the program carried out the list.add(),the vector was locked,too.The variable “expectedModCount” always equals “modCount”. Why the ConcurrentModificationException occured?
The iterator's next method is what's synchronized. That means it releases the lock after reading each element, then acquires the lock when reading the subsequent one. There is still an opportunity between calls to next for the contents of the vector to change in a way that triggers the ConcurrentModificationException.
I am writing an iterator method for my own array list class, however, when I try to test the class it says foreach loop is not applicable to MyArrayList. can anyone help me out with where I have gone wrong?
The class itself uses arrays of objects and the necessary methods to act like an arraylist (add, remove, get etc.)
Here is the class constructor and my iterator class:
public class MyArrayList {
public Object[] arrayList = new Object[5];
int length1 = 5;
public MyArrayList() {
}
public MyArrayList(Object[] arrayList) {
this.arrayList = arrayList;
length1 = arrayList.length;
}
public ArrayListIterator iterator(){
return new ArrayListIterator(this);
}
class ArrayListIterator<MyArrayList> implements Iterator<Object> {
private Object[] arrayListIterable;
private int count = 0;
public ArrayListIterator(Object[] x){
arrayListIterable = x;
}
public ArrayListIterator(MyArrayList myArrayList) {
}
public boolean hasNext(){
if(count < arrayList.length){
return true;
}else{
return false;
}
}
public Object next(){
int x = count;
count++;
return arrayListIterable[x];
}
}
Your MyArrayList class must implement Iterable<T> interface.
Check the javadoc for Iterable:
Implementing this interface allows an object to be the target of the "for-each loop" statement.
The list over which I want to iterate, contains an Array.
What I am trying to do is to make it possible to create an Iterator within the Iterator, so that I am able to iterate over the array in every Listelement.
I tried it this way:
#Override
public Iterator<A> iterator() {
return new MyListIterator();
}
private class MyListIterator implements Iterator<A>, Iterable<B>
{
private Listelem current;
private MyListIterator()
{
this.current = head;
}
#Override
public boolean hasNext()
{
return this.current != null;
}
#Override
public A next()
{
A next = this.current.getValue();
this.current = this.current.getSuccessor();
return next;
}
#Override
public void remove()
{
Listelem tmp = head;
while( tmp.getSuccessor().getSuccessor() != this.current )
{
tmp = tmp.getSuccessor();
}
tmp.setSuccessor(this.current);
}
#Override
public Iterator<B> iterator() {
return new MyInnerListIterator();
}
private class MyInnerListIterator implements Iterator<B>
{
private int currentIndex = 0;
private B[] array = current.getAssoc();
#Override
public boolean hasNext() {
return currentIndex < array.length && array[currentIndex] != null;
}
#Override
public B next() {
return array[currentIndex++];
}
#Override
public void remove() {
}
}
}
The problem is, when I am creating the first Iterator with iterator() the object does not contain the method iterator().
Can somebody explain to my why this is not working, and how to do it different?
The problem is that iterator returns an Iterator, even though in this case it happens to also be a MyListIterator. Class Iterator does not have an iterator() function. You need to have iterator() return a MyListIterator, so that you can use methods not in the Iterator interface.
It is likely simpler however, to simply use a for:in loop:
List<Object[]> list = ....
for (Iterator<Object[]> it = list.iterator(); it.hasNext();) {
Object[] arr = it.next();
for (Object o : arr) {
...
}
}
And if you don't need to remove elements from the list, then you can replace the iterator use with another for:in
I am trying to implement an Iterator with Iterable in Java, here is what I have so far:
public class keysIterator<A> implements Iteratble<A<{
A[] elements;
int nextElement;
keysIterator(A[] elements, int nextElement) {
this.elements = elements;
this.nextElement = 0;
}
public boolean hasNext() {
return this.nextElement < elements.length;
}
public A next() {
A result = elements[nextElement];
nextElement = nextElement + 1;
return result;
}
public void remove() {
// TODO Auto-generated method stub
}
public Iterator<A> iterator() {
// TODO Auto-generated method stub
}
}
I need help writing the remove and iterator methods, any assistance is greatly appericated.
Thank you.
Having an Iterator implement Iterable doesn't make sense to me
Something Iterable has an iterator() method, that returns an Iterator.
Also an iterator usually doesn't hold the data but refers to someother instance that has the data.
So usually
class Foo implements Iterable
{
public Iterator iterator() {
return new FooIterator();
}
}
class FooIterator implements Iterator {
// with methods as you've defined them
}
You are mixing up implementation of the Iterator interface with your Iterable class. Try this:
public class KeysIterable<A> implements Iterable<A> {
A[] elements;
int nElements;
private class KeysIterator<A> implements Iterator<A> {
int nextElement = 0;
public boolean hasNext() {
return nextElement < nElements;
}
public A next() {
A result = elements[nextElement];
nextElement = nextElement + 1;
return result;
}
public void remove() {
if (nextElement < nElements - 1) {
System.arraycopy(elements, nextElement + 1,
elements, nextElement, nElements - nextElement - 1);
}
nElements--;
}
}
public Iterator<A> iterator() {
return new KeysIterator<A>();
}
public KeysIterable() {
}
// other methods
}
It would probably be better to implement your Iterable class using an ArrayList instead of a generic array.
Use an ArrayList instead of an array, so you can just do:
public Iterator<A> iterator() {
return elements.iterator();
}
If you really want an array, you can always do:
public Iterator<A> iterator() {
return Arrays.asList(elements).iterator();
}