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.
Related
I have generic class MyArray where private member is ArrayList, and inside is implemented iterator.
In Main is given some MyArray with strings and I want to delete all "test" from it... Problem is in iterator which method remove doesn't work
Here is how class looks like:
public class MyArray<E> {
private ArrayList<E> list;
public MyArray() {
list = new ArrayList<E>();
}
public int length() { return list.size(); }
public E at(int pos) { return list.get(pos); }
public void add(E val) { list.add(val); }
public void remove(int pos) { list.remove(pos); }
public class MyIterator implements Iterator<E>{
int index;
#Override
public boolean hasNext() {
return index < list.size();
}
#Override
public E next() {
if (!hasNext())
throw new NoSuchElementException("no next value");
E tmp = list.get(index);
index++;
return tmp;
}
}
public Iterator<E> iterator() {
return new MyIterator();
}
public static void main(String[] args) {
MyArray<String> b = new MyArray<String>();
b.add("This");
b.add("is");
b.add("test");
b.add("please");
b.add("delete");
b.add("all");
b.add("test");
Iterator<String> iter = b.iterator();
while(iter.hasNext())
System.out.println(iter.next());
for(Iterator<String> i = b.iterator(); i.hasNext(); ) {
String tmp = i.next();
if (tmp.equals("test"))
i.remove();
}
Iterator<String> ite = b.iterator();
while(ite.hasNext())
System.out.println(ite.next());
}
}
Exception that I get is:
Exception in thread "main" java.lang.UnsupportedOperationException: remove
at java.util.Iterator.remove(Unknown Source)
at cas1.MyArray.main(MyArray.java:71)
You need to override remove() in your Iterator.
However, it'd be easiest to make your iterator() method return list.iterator(), rather than implementing it yourself:
public Iterator<E> iterator() {
return list.iterator();
}
Iterator in an interface, and you need to implement each of the Iterator methods in MyIterator that you intend to call.
MyIterator that you defined doesn't override Iterator.remove() and
the remove() defined in the Iterator interface is defined as a default method that throws UnsupportedOperationException :
default void remove() {
throw new UnsupportedOperationException("remove");
}
So override it simply to remove effectively the iterated element.
You can rely on ArrayList.Itr code :
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
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 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. 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.
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