I have created in class a generic class that works like ArrayList. The class included an array that gets bigger and smaller by demand by functions. Now, I have to implement the List interface and got stuck on the Iterator and ListIterator. I get only errors all the time, when I try to realize methods that depends on Iterator or ListIterator. Of course I have searched on the internet but I think I miss something.
public class EviatarList implements List, Iterable {
private E[] arr;
private static final int DEFAULT_CAPACITY = 3;
private int index = 0;
private int iteratorIndex = 0;
#Override
public Iterator<E> iterator() {Iterator<E> it = new Iterator<E>() {
#Override
public boolean hasNext() {
return index < arr.length && arr[index + 1] != null;
}
#Override
public E next() {return arr[iteratorIndex++];}
#Override
public void remove(){
E [] arr1 =(E[]) new Object [size()-1];
try {
arr[iteratorIndex] = null;
iteratorIndex--;
index--;
for (int i = 0, j = 0; i < arr.length; i++, j++) {
if (arr[i] != null)
{
arr1[j] = arr[i];
} else{
j--;
}
}
} catch (Exception e)
{
System.out.println(e.getMessage());
}
arr = arr1;
}
};
return it;
}
public ListIterator<E> listIterator() {
ListIterator<E> li = new ListIterator<E>() {
//o(1)
#Override
public boolean hasNext() {
return index < arr.length;
}
//o(1)
#Override
public E next() {
return arr[index++];
}
//o(1)
#Override
public boolean hasPrevious() {
return index > 0;
}
//o(1)
#Override
public E previous() {
return arr[index--];
}
//o(1)
#Override
public int nextIndex() {
return iteratorIndex;
}
//o(1)
#Override
public int previousIndex() {
return iteratorIndex--;
}
// o(n)
#Override
public void remove() {
E[] newArr = (E[]) new Object[arr.length - 1];
index--;
for (int i = 0, j = 0; i < index; i++, j++) {
if (i != iteratorIndex) {
newArr[i] = arr[j];
} else {
j--;
}
}
arr = newArr;
}
Sorry, but your question is a little vague so I cannot really answer. The implementation of EviatarList is not shown but used (e.g. size()) and "I get only errors all the time" is not clear about the kind of errors (from the compiler or runtime using it, ...).
Some thoughts on your implementation that may help one step further:
Why you implement your own List instead of extending AbstractList (that would offer ready to use iterators)?
You can have multiple iterators on the same collection, therefore the iteratorIndex has to be state (aka member) of the Iterator, not of the List!
There is some confusion about index and iteratorIndex in your implementation. What is the difference and what is the role of index?
As ListIterator extends Iterator it would simplify your implementation using the same for both:
public Iterator<E> iterator() {
return listIterator();
}
Related
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.
I've scoured this site (as well as the web) and for some reason cannot find an answer that works. Either I get an index out of bounds error, or the next part of my code won't execute. All I am trying to do is remove a item from a list in Java using an iterator. Here is my code:
public boolean remove(T item) {
while (bag.iterator().hasNext()) {
T i = bag.iterator().next();
if (i.equals(item)) {
bag.iterator().remove();
return true;
}
}
return false;
}
My iterator inherits from my "Bag" class obviously, but here it is as well:
public Iterator<T> iterator() {
return new Iterator<T>() {
private int current = 0;
public boolean hasNext() {
return current < size;
}
public T next() {
return data[current++];
}
public void remove() {
for (int i=current-1; i<size-1; i++)
data[i] = data[i+1];
size--;
}
};
}
Any help is much appreciated, thanks guys!!
Clayton
Every time you call bag.iterator(), you get a new Iterator object, not the same one you had before. You should get the iterator once, then use it through your loop:
public boolean remove(T item) {
Iterator<T> iter = bag.iterator();
while (iter.hasNext()) {
T i = iter.next();
if (i.equals(item)) {
iter.remove();
return true;
}
}
return false;
}
Your code has another issue: if you call remove() on your iterator before you call next(), your code will try to access data[-1]. You might want to put some protection code around that such as:
public void remove() {
if(current > 0) {
for (int i=current-1; i<size-1; i++)
data[i] = data[i+1];
size--;
}
}
I have made a Priority Queue class with an array list, but I am having trouble with the insert and delMin (delete minimum areas). I cannot create more functions and here is my code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class MyMinPQ<E extends Comparable<E>> implements Iterable<E> {
private ArrayList<E> pq;
private int N;
public MyMinPQ() {
pq = new ArrayList<E>();
}
public E delMin(){
E minVal = min();
pq.remove(0);
N--;
return minVal;
}
public E min (){
if (isEmpty())
throw new NoSuchElementException();
return pq.get(0);
}
public void insert (E item){
for (int i = 0; i < N; i++){
pq.add(item);
if (pq.get(i) > pq.get(i+1)) {
E tmp = pq.get(i);
pq.set(i+1, tmp);
}
}
N++;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
public Iterator<E> iterator() {
return new Iterator<E>(){
int current = 0;
public boolean hasNext() {
return current != size();
}
public E next() {
if (hasNext())
return pq.get(current++);
else throw new NoSuchElementException( );
}
public void remove() {
throw new UnsupportedOperationException( );
}
};
}
}
At the insert portion of the code, I know that I have to sort the new additions to Arraylist but I am having issues with going about this. I tried to compare the values that is within the list, but eclipse does not allow it based on how I formatted it. When I use compareTo, it does not work with my iterator and everything goes into disarray.
My question is how can I go about modifying my insert function so it can sort new items in descending order? Will my delMin() also have to change because of it?
try this
public void insert(E item) {
int i = 0;
while (i < N && pq.get(i).compareTo(item) <= 0) {
i++;
}
N++;
}
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
So I am a college student just looking for a little help and understanding, I have a professor that does not allow us to use java pre-written classes such as ArrayList, so I am trying to figure out how to modify my current encapsulated array class to use generics so that I don't have to do so much casting in the application class of my program
public class ArrayClass {
private Object[] objArray;
private int index = 0;
public static final int MAX_SIZE = 100;
public ArrayClass(){
objArray = new Object[100];
}
public ArrayClass(int numSlots){
objArray = new Object[numSlots];
}
public ArrayClass(Object[] anArray, int newIndex){
objArray = new Object[newIndex];
for(int i=0; i<newIndex; i++){
objArray[i] = anArray[i];
}
index = newIndex;
}
//return object array, accessor
public Object[] getstrArr(){
return objArray;
}
//return # of actual data in array, accessor
public int getIndex(){
return index;
}
//return an object at given pos, accesor
public Object getObject(int pos){
return objArray[pos];
}
//assign a new object array, mutator
public void setObjArr(Object[] aStrArr){
for(int i=0; i<index; i++){
objArray[i] = aStrArr[i];
}
}
//assign a new index, mutator
public void setIndex(int anIndex){
index = anIndex;
}
//insert a new string into the array if there is room, increment index
public void add(Object someObj){
if(index < objArray.length){
objArray[index] = someObj;
index++;
}
}
//return the string with contents of array
public String toString(){
String output = " ";
for(int i=0; i<index; i++){
output = output + objArray[i].toString();
}
return output;
}
//return true if calling object is equivalent to argument
public boolean equals(Object someObj){
for(int i=0; i< index; i++){
if(objArray[i].equals(someObj))
return true;
}
return false;
}
}
public class ArrayClass<E> {
// return object array, accessor
public <T> T[] getstrArr(T[] t) {<--This is done because arrays are covarant in nature
return (T[]) Arrays.copyOf(objArray, index, t.getClass());
}
// return an object at given pos, accesor
public E getObject(int pos) {<-- For single elements just return E with casting
return (E) objArray[pos];
}
Implementation Notes
Length checks should be considered for Arrays.copy of
You can read a nice article about generics
Well, i would not expose your index with methods like setIndex, etc. Not adding null element check too.
Anyway, I would make something like:
public class ArrayClass<E> {
...
private E[] elements;
private int index;
...
public ArrayClass() {
this.elements = (E[]) new Object[MAX_SIZE];
this.index = 0;
}
// this constructor substitutes the method setObjArr
public ArrayClass(E[] elements) {
this.elements = elements;
this.index = elements.length;
}
...
public void add(E element) {
if (needsToGrow()) {
duplicateArraySize();
}
this.elements[index++] = element;
}
private boolean needsToGrow() {
return index + 1 == elements.length;
}
private void duplicateArraySize() {
E[] extendedArray = (E[]) new Object[this.elements.length * 2];
System.arraycopy(elements, 0, extendedArray, 0, elements.length);
this.elements = extendedArray;
}
public E get(int index) {
return this.elements[index];
}
public int size() {
return this.index;
}
...
}
I would do it like that:
public class ArrayClass<T> {
public T[] objArray;
private int index = 0;
public static final int MAX_SIZE = 100;
#SuppressWarnings("unchecked")
public ArrayClass(Class<T> c) {
objArray = (T[]) Array.newInstance(c,MAX_SIZE);
}
}
and so on.
And then:
ArrayClass<String> myStringArray = new ArrayClass<String>(String.class);