Removing an item from a list in Java - java

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

Related

List Interface implementation

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

Made a Priority Queue, having problems with delMin and insert

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

Flatten an iterator of iterators in Java

Flatten an iterator of iterators in Java. If the input is [ [1,2], [3,[4,5]], 6], it should return [1,2,3,4,5,6]. Implement hasNext() and next(). Be careful when the inner iterator or list is empty.
I don't think my code works for multiple levels of inner lists.
public class FlattenList {
int index = 0; // keep an index to indicate where the current accessed element is
List<Integer> flattenedList = new ArrayList<>(); // flattenedList
public FlattenList(List<List<Integer>> lists){
for(List<Integer> list : lists){ // add all inner list to our underlying list.
flattenedList.addAll(list);
}
}
public boolean hasNext(){ // check if the index has exceeded the list size
return flattenedList.size() > index? true : false;
}
public Integer next(){ // return the next element, and increment the index
Integer result = flattenedList.get(index);
index++;
return result;
}
}
So basically this is like writing a depth first traversal of a tree. Leaf nodes of this tree are numbers, all interior nodes are modeled as Iterators. Here is some pseudo code:
void flatten(Iterator<Object> iterator, List<Integer> flattenedList) {
for (Object o : iterator) {
if (o instanceof Iterator) {
flatten((Iterator) o, flattenedList);
} else {
flattenedList.add((Integer) o);
}
}
}
Here, I'll start it for you:
public <T> Iterator<T> flatten(final Iterator<Iterator<T>> iterators) {
if (iterators == null) {
throw new IllegalArgumentException("iterators can't be null");
}
return new Iterator<>() {
#Override
public boolean hasNext() {
throw new UnsupportedOperationException("Not implemented: hasNext");
}
#Override
public T next() {
throw new UnsupportedOperationException("Not implemented: next");
}
};
}
Now you just do that pesky brainwork and you'll be done.
EDIT
If you're not used to that syntax, here's a slightly easier one:
public <T> Iterator<T> flatten(final Iterator<Iterator<T>> iterators) {
return new MyFlatteningIterator<>(iterators);
}
public class MyFlatteningIterator<T> implements Iterator<T> {
private final Iterator<Iterator<T>> iterators;
public MyFlatteningIterator(final Iterator<Iterator<T>> iterators) {
if (iterators == null) {
throw new IllegalArgumentException("iterators can't be null");
}
this.iterators = iterators;
}
#Override
public boolean hasNext() {
throw new UnsupportedOperationException("Not implemented: hasNext");
}
#Override
public T next() {
throw new UnsupportedOperationException("Not implemented: next");
}
}
You should not treat this as a list, rather as Jon stated this is more suitable when you are talking about trees. If you infect looking for a solution to get a flatted iterator of list of lists (something that looks like [[1],[1,2,3],[8,9]]) then I think that the following solution will work better
import java.util.Collection;
import java.util.Iterator;
public class FlattedIterator<T> implements Iterator<T> {
private Iterator<T>[] iteratorsArray;
public FlattedIterator(Collection<T>[] items) {
this.iteratorsArray = new Iterator[items.length];
for(int index = 0; index < items.length; index++) {
this.iteratorsArray[index] = items[index].iterator();
}
}
#Override
public boolean hasNext() {
boolean hasNext = false;
for(int index = 0; index < this.iteratorsArray.length; index++) {
hasNext |= this.iteratorsArray[index].hasNext();
}
return hasNext;
}
#Override
public T next() {
int index = 0;
while(index < this.iteratorsArray.length && !this.iteratorsArray[index].hasNext()) {
index++;
}
if(index >= this.iteratorsArray.length ) {
throw new IndexOutOfBoundsException("Reached end of iterator");
}
return this.iteratorsArray[index].next();
}
}
Bear in mind that the reason that I think this solution will work better is due to the fact that in your solution you initialized flattenedList by adding all the data from the given lists meaning that if in some point of the program one of those lists will received more data after you initialized FlattenList then the new data wont appear while you read the iterator.

Java - Trying to create an Iterator within an Iterator

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

Iterator method?

I'm implementing a list interface with links but since "ListADT" implements the Iterable interface. So, I have to have a method that produces an iterator which I'm not sure how to do. I tried using it as it is now and when I created an object for the linkedlist, and then call the iterator() method, I get an overflow. I know the method is supposed to produce an Iterator object but not sure how.
import java.util.Iterator;
public class LinkedList<T> implements ListADT<T>
{
protected int count;
protected LinearNode <T> head, tail;
private int modCount;
public LinkedList()
{
count =0;
head = tail= null;
}
public T removeFirst()
{
T result = head.getElement();
head = head.getNext();
count--;
return result;
}
public T removeLast()
{
// THROW EMPTY EXCEPTION
T result;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while(!current.equals(tail))
{
previous = current;
current = current.getNext();
}
result = tail.getElement();
tail = previous;
tail.setNext(null);
count--;
return result;
}
public T remove(T element)
{
// throw exception
boolean found = false;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while (current != null && !found)
{
if(element.equals(current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
if (!found)
{
}
else if (current.equals(head))
{
head = current.getNext();
}
else if(current.equals(tail))
{
tail = previous;
tail.setNext(null);
}
else
previous.setNext(current.getNext());
}
count --;
return current.getElement();
}
public T first()
{
return head.getElement();
}
public T last()
{
return tail.getElement();
}
public boolean contains(T target)
{
boolean found = false;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while (current != null && !found)
{
if(target.equals(current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
}
return found;
}
public boolean isEmpty()
{
boolean result = false;
if( head == null && tail ==null)
{
result = true;
}
return result;
}
public int size()
{
return count;
}
public Iterator<T> iterator()
{
return this.iterator();
}
public String toString()
{
LinearNode <T> current = head;
String result ="";
String line = "";
int loopCount=0;
while(current != null)
{
loopCount++;
line = loopCount + "> " + (String) current.getElement() + "\n";
result = result + line;
current = current.getNext();
}
return result;
}
}
Your problem
You're getting an overflow because the line this.iterator() in your function public Iterator<T> iterator(), calls, you guessed it public Iterator<T> iterator().
Approach 1: The lazy way
If you don't plan on using the iterator for this class, (this looks like a programming assignment) you can always do the super super lazy.
public Iterator<T> iterator() {
throw new UnsupportedOperationException("Pffffft you don't need no iterator");
}
This approach is listed here just for completeness. Seeing as your linked list has no other way to access a random element in the middle without removing everything in front or behind it, I recommend you:
DO NOT DO THIS
Approach 2: The Correct Way
The thing about iterators is that they do a specific subset of what a list does, namely hasNext(), next(), and remove(). If you're unsure what those three methods do, I suggest you take a look at http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html
You should create a public inner class.
public class LinkedList<T> implements ListADT<T> {
... stuff
private class MyIterator<T> implements Iterator<T> {
//It's best practice to explicitly store the head in the iterator
private LinearNode<T> head;
public MyIterator<T>(LinkedList<T>) {
...
}
#Override
public boolean hasNext() {
...
}
#Override
public T next() {
...
}
#Override
public void remove() {
...
}
}
public Iterator<T> iterator() {
return new MyIterator<T>(this);
}
}
Now if you're really clever, you can rewrite the rest of your code based on the iterator. Note:
DO THIS

Categories