Enumeration is throwing concurrentModification Exception. why? - java

Enumeration is Fail-safe. Fail-safe iterators will work on the cloning of the original collection. then why it is throwing concurrentModificationException? please clarify.
Please find my code:
public static void main(String[] args) {
Vector<String> v=new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");
Enumeration en=(Enumeration) Collections.enumeration(v);
while(en.hasMoreElements())
{
String value=(String) en.nextElement();
System.out.println(value);
v.remove(value);//modifying the collection
}
}
Find the error message below
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.Vector$Itr.checkForComodification(Unknown Source)
at java.util.Vector$Itr.next(Unknown Source)
at java.util.Collections$2.nextElement(Unknown Source)
at valar.org.src.EnumerationTest.main(EnumerationTest.java:24)

Collections.enumeration(Collection) will create an iterator from the collection passed as parameter :
public static <T> Enumeration<T> enumeration(final Collection<T> c) {
return new Enumeration<T>() {
private final Iterator<T> i = c.iterator();
public boolean hasMoreElements() {
return i.hasNext();
}
public T nextElement() {
return i.next();
}
};
}
It means that the iterator is backed to the collection which you remove element in the iterator loop and you cannot remove an element of the collection on which you iterate with the iterator.
You should create a copy of the Vector you pass in the enumeration() invocation :
Enumeration<String> en = Collections.enumeration(new Vector<String>(v));
And as a side note, you should favor List interface and ArrayList implementation over Vector (that is synchronized) and declare generics collection that spares cast and increase the type safety of the code.
So it would give this code (I left the Vector use as it is maybe a not modifiable constraint but I specified the generics as it is often simpler to add even in a legacy code):
Vector<String> v = new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");
Enumeration<String> en = Collections.enumeration(new Vector<String>(v));
while (en.hasMoreElements()) {
String value = (String) en.nextElement();
System.out.println(value);
v.remove(value);// modifying the collection
}

Your Enumeration uses an Iterator internally. While iterating over the elements, you can't use the vector itself to remove items. You have to use the iterator. But you don't have access to it. Create an iterator instead:
public static void main(String[] args) {
final Vector<String> v = new Vector<String>();
v.add("Amit");
v.add("Raj");
// Use an Iterator to remove the value you are iterating over
final Iterator<String> iterator = v.iterator();
while (iterator.hasNext()) {
final String value = iterator.next();
System.out.println(value);
iterator.remove();
}
}
Though Vector is practically deprecated anyways. You should propably use a List instead:
The imports for the correct Lists (don't use the awt.List for this):
import java.util.ArrayList;
import java.util.List;
The changed code:
public static void main(String[] args) {
final List<String> v = new ArrayList<>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
final Iterator<String> iterator = v.iterator();
while (iterator.hasNext()) {
final String value = iterator.next();
System.out.println(value);
iterator.remove();
}
}
Also note you can use the interface as Type which is generally preferred to using the implementation.
Edit:
Looking at your example, maybe what you really need is a queue:
public static void main(String[] args) {
final Queue<String> v = new LinkedList<>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
System.out.println("Size: " + v.size());
for (String element = v.poll(); element != null; element = v.poll()) {
System.out.println(element);
}
System.out.println("Size: " + v.size());
}
Output:
Size: 3
Amit
Raj
Pathak
Size: 0
This works the same as your example. For more info on Collections see The official Collections Java Trail

Enumeration is Fail-safe.
Correct. (Allowing for some language difficulties.)
Fail-safe iterators will work on the cloning of the original collection.
Correct. (Allowing for some language difficulties.)
then why it is throwing concurrentModificationException?
Because there is no cloning involved.
Where is the cloning?

You are using Enumeration which is not supported removed method.Once you created a Enumeration then it test for checkForComodification .so when you do the remove from vector the modCount increases and expectedModCount not modified.
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
please modify your code using iterator
public static void main(String[] args) {
Vector<String> v = new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");
Iterator<String> it =v.iterator();
while (it.hasNext()) {
String value = it.next();
System.out.println(value);
it.remove();
}
}

Related

How to remove and set from List<String> in java?

In java I have this function:
public List<String> seperatekeys(String text) {
String[] keys = text.split("and");
List<String> words = Arrays.asList(keys);
ListIterator<String> iter = words.listIterator();
while (iter.hasNext()) {
String currentWord = iter.next().trim();
if (currentWord.equals("")) {
iter.remove();
} else {
iter.set(currentWord);
}
}
return words;
}
But when I do a remove(), it crashes saying unsupportedoperationerror.
Anyone know how to fix it?
Thanks
The issue is that Arrays#asList() returns an ArrayList implementation that inherits remove() from AbstractList. The implementation of remove() in AbstractList is this:
public E remove(int index) {
throw new UnsupportedOperationException();
}
And because the iterator uses the list's iterator to perform its remove() method, you end up with the exception.
You have a few solutions here. You can either pass the result of Arrays#asList() to an ArrayList constructor:
List<String> words = new ArrayList<>(Arrays.asList(keys));
Now, you can iterate over the resulting List and remove the elements you want.
Or, asMadProgrammer stated, you can take the opposite approach and iterate over the array and add the elements you want to keep:
List<String> words = new ArrayList<>();
for (String s : keys) {
String currentWord = s.trim();
if (!currentWord.equals("")) {
words.add(currentWord);
}
}

What is the optimal way to transverse a TreeSet from last node to first in java?

I already have a solution to traverse a TreeSet. My question is related to performance, is the way I implemented the optimal one? See my code example below.
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add("F");
ts.add("B");
ts.add("H");
ts.add("Z");
while (!ts.isEmpty())
{
String last = (String)ts.last();
System.out.println(last);
ts.remove(last);
}
// OUTPUT: Z H F B
}
Seems simple
TreeSet ts = new TreeSet();
Iterator i = ts.descendingIterator();
while(i.hasNext()) {
Object next = i.next();
}
or
for(Object e : ts.descendingSet()) {
}
for Java below 1.6 you can try
TreeSet tmp = new TreeSet(Collections.reverseOrder());
tmp.addAll(ts);
for(Object e : tmp) {
}
A JDK 5 compatible way: create a new new collection with the comparator reversed.
TreeSet<String> trev = new TreeSet<String>(Collections.reverseOrder());
trev.addAll(ts);
//now you can just iterate which the usual forward iterator.
Iterator i = trev.iterator();
while(i.hasNext()) {
String next = i.next();
}

how to remove duplicate array elements using hashmap in java

How to remove duplicate elements in an array using HashMap without using hashset in java...Below code describes removal of duplicates in array..
Now i need to write using hashmap for generating key and value pairs
import java.util.*;
class TestArray{
public static void main(String arg[])
{
ArrayList<String> wordDulicate = new ArrayList<String>();
wordDulicate.add("chennai");
wordDulicate.add("bangalore");
wordDulicate.add("hyderabad");
wordDulicate.add("delhi");
wordDulicate.add("bangalore");
wordDulicate.add("mumbai");
wordDulicate.add("mumbai");
wordDulicate.add("goa");
wordDulicate.add("calcutta");
wordDulicate.add("hyderabad");
ArrayList<String> nonDupList = new ArrayList<String>();
Iterator<String> dupIter = wordDulicate.iterator();
while(dupIter.hasNext())
{
String dupWord = dupIter.next();
if(nonDupList.contains(dupWord))
{
dupIter.remove();
}else
{
nonDupList.add(dupWord);
}
}
System.out.println(nonDupList);
}
}
A HashSet is implemented in terms of a HashMap anyway. If you specifically want to use a HashMap, use it the same way as HashSet does: use a dummy constant new Object() as the map value everywhere.
Well a HashMap will prevent you from entering duplicate keys, the same way as HashSet. Actually, many implementations of HashSet just use a HashMap under the hood.
So you can do:
HashMap<String, String> map = new HashMap<String, String>();
for (String s : WordDuplicate)
map.put( s, s );
Now you can access the key/values just like a HashMap.
import java.util.HashSet;
import java.util.Stack;
public class stackdupes {
public static void main(String[] args) {
Stack<Integer> st = new Stack<Integer>();
int[] arr= {1,2,3,3,4,5,5,7};
HashSet<Integer> set = new HashSet<Integer>();
for (int i=0;i<arr.length;i++) {
if(set.add(arr[i]) == true)
st.push(arr[i]);
}
System.out.println(st);
}
}

Recursive method in composite pattern

Hi i have a components class which can contain components and composite and i am writing a method to calculate the sum total of all the tax in its components.This class is part of a composite pattern code.The problem is my method which is recursive is not working properly i am having a stack overflow but for testing my method i only have two objects in my array list.
public class Nobles extends RiruritaniaSubjects
{
ArrayList vassalsanddukes = new ArrayList();
public void calculateTaxDueByComponents(){
Iterator iterator = vassalsanddukes.iterator();
while(iterator.hasNext()){
RiruritaniaSubjects vassalandduke=(RiruritaniaSubjects) iterator.next();
totalTaxdue+=vassalandduke.getTaxDue();
calculateTaxDueByComponents();
}
}
}
RiruritaniaSubjects is an abstract class and i have my other composite class extend it.I have edited the code and the stack overflow has stopped but my other problem is it seems to not add on the tax due if a component contains a component.
public void calculateTaxDueByComponents(){
Iterator iterator = vassalsanddukes.iterator();
while(iterator.hasNext()){
RiruritaniaSubjects vassalandduke=(RiruritaniaSubjects) iterator.next();
totalTaxdue+=vassalandduke.getTaxDue();
vassalandduke.calculateTaxDueByComponents();
}
}
I have decided to post snippets of different parts of my code.The problem i am having now is for e.g i have a noble A then a noble b , then a noble c.If i add noble c to noble b b.add(C). and i add b to a,a.add(B), my calculate Totaltaxdue() is not updating my tax due with the inner noble c.
public class Nobles extends RiruritaniaSubjects {
ArrayList vassalsanddukes = new ArrayList();
public void calculateTaxDueByComponents(){
Iterator iterator = vassalsanddukes.iterator();
while(iterator.hasNext()){
RiruritaniaSubjects vassalandduke=(RiruritaniaSubjects) iterator.next();
totalTaxdue+=vassalandduke.getTaxDue();
System.out.println(vassalandduke.getTaxDue());
vassalandduke.calculateTaxDueByComponents();
}
}
public double getTotalTaxDue(){
calculateTaxDueByComponents();
return totalTaxdue;
}
public class Prince {
Land land;
ArrayList allprinceSubjects = new ArrayList();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
RiruritaniaSubjects allsubjects = new Nobles();
RiruritaniaSubjects allsubject3 = new Nobles();
RiruritaniaSubjects allsubject4 = new Nobles();
allsubject4.add(allsubject3, 10);
allsubjects.add(allsubject4, 10);
System.out.println(allsubjects.getTotalTaxDue());
}
}
By my own workings the output should be 7 because it should be 3.5 for each noble but i am getting 3.5 as the output which is wrong.
You're calling the calculateTaxDueByComponents method on this rather than to call it on your subcomponents.
Moreover, the calculateTaxDueByComponents is a void method. It doesn't return anything. So it's impossible to add its result (since it doesn't have any) to the tax due by the current component. Your method should probably look like this:
public int calculateTaxDueByComponents() {
int taxDueByThisComponent = getTaxDue();
int taxDueByThisComponentAndAllItsSubComponentsRecursively = taxDueByThisComponent;
Iterator iterator = vassalsanddukes.iterator();
while(iterator.hasNext()){
RiruritaniaSubjects vassalandduke=(RiruritaniaSubjects) iterator.next();
taxDueByThisComponentAndAllItsSubComponentsRecursively += vassalandduke.calculateTaxDueByComponents();
}
return taxDueByThisComponentAndAllItsSubComponentsRecursively;
}
Side note: your code would be more readable and more type-safe if you used generic collections: List<RiruritaniaSubjects> rather than List.
You are calling the method from with the method, leading to an infinite loop! Just remove that call:
public void calculateTaxDueByComponents(){
Iterator iterator = vassalsanddukes.iterator();
while(iterator.hasNext()){
RiruritaniaSubjects vassalandduke=(RiruritaniaSubjects) iterator.next();
totalTaxdue+=vassalandduke.getTaxDue();
// calculateTaxDueByComponents(); DON't DO THIS!
}
}
I will assume that calculateTaxDueByComponents belongs to RirutaniaSubjects.
You are certainly going to have a stack overflow because you are calling it on this. Probably you want to do:
public void calculateTaxDueByComponents(){
Iterator iterator = vassalsanddukes.iterator();
int totalTaxDue = getTaxDue();
while(iterator.hasNext()){
RiruritaniaSubjects vassalandduke=(RiruritaniaSubjects) iterator.next();
totalTaxdue+=vassalandduke.calculateTaxDueByComponents();
}
}

Iterating through a list in reverse order in java

I'm migrating a piece of code to make use of generics. One argument for doing so is that the for loop is much cleaner than keeping track of indexes, or using an explicit iterator.
In about half the cases, the list (an ArrayList) is being iterated in reverse order by using an index today.
Can someone suggest a cleaner way of doing this (since I dislike the indexed for loop when working with collections), though it does work?
for (int i = nodes.size() - 1; i >= 0; i--) {
final Node each = (Node) nodes.get(i);
...
}
Note: I can't add any new dependencies outside the JDK.
Try this:
// Substitute appropriate type.
ArrayList<...> a = new ArrayList<...>();
// Add elements to list.
// Generate an iterator. Start just after the last element.
ListIterator li = a.listIterator(a.size());
// Iterate in reverse.
while(li.hasPrevious()) {
System.out.println(li.previous());
}
Guava offers Lists#reverse(List) and ImmutableList#reverse(). As in most cases for Guava, the former delegates to the latter if the argument is an ImmutableList, so you can use the former in all cases. These do not create new copies of the list but just "reversed views" of it.
Example
List reversed = ImmutableList.copyOf(myList).reverse();
I don't think it's possible using the for loop syntax. The only thing I can suggest is to do something like:
Collections.reverse(list);
for (Object o : list) {
...
}
... but I wouldn't say this is "cleaner" given that it's going to be less efficient.
Option 1: Have you thought about reversing the List with Collections#reverse() and then using foreach?
Of course, you may also want to refactor your code such that the list is ordered correctly so you don't have to reverse it, which uses extra space/time.
EDIT:
Option 2: Alternatively, could you use a Deque instead of an ArrayList? It will allow you to iterate forwards and backwards
EDIT:
Option 3: As others have suggested, you could write an Iterator that will go through the list in reverse, here is an example:
import java.util.Iterator;
import java.util.List;
public class ReverseIterator<T> implements Iterator<T>, Iterable<T> {
private final List<T> list;
private int position;
public ReverseIterator(List<T> list) {
this.list = list;
this.position = list.size() - 1;
}
#Override
public Iterator<T> iterator() {
return this;
}
#Override
public boolean hasNext() {
return position >= 0;
}
#Override
public T next() {
return list.get(position--);
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
for (String s : new ReverseIterator<String>(list)) {
System.out.println(s);
}
You could use the concrete class LinkedList instead of the general interface List. Then you have a descendingIterator for iterating with the reverse direction.
LinkedList<String > linkedList;
for( Iterator<String > it = linkedList.descendingIterator(); it.hasNext(); ) {
String text = it.next();
}
Don't know why there is no descendingIterator with ArrayList...
This is an old question, but it's lacking a java8-friendly answer. Here are some ways of reverse-iterating the list, with the help of the Streaming API:
List<Integer> list = new ArrayList<Integer>(Arrays.asList(1, 3, 3, 7, 5));
list.stream().forEach(System.out::println); // 1 3 3 7 5
int size = list.size();
ListIterator<Integer> it = list.listIterator(size);
Stream.generate(it::previous).limit(size)
.forEach(System.out::println); // 5 7 3 3 1
ListIterator<Integer> it2 = list.listIterator(size);
Stream.iterate(it2.previous(), i -> it2.previous()).limit(size)
.forEach(System.out::println); // 5 7 3 3 1
// If list is RandomAccess (i.e. an ArrayList)
IntStream.range(0, size).map(i -> size - i - 1).map(list::get)
.forEach(System.out::println); // 5 7 3 3 1
// If list is RandomAccess (i.e. an ArrayList), less efficient due to sorting
IntStream.range(0, size).boxed().sorted(Comparator.reverseOrder())
.map(list::get).forEach(System.out::println); // 5 7 3 3 1
Here is an (untested) implementation of a ReverseIterable. When iterator() is called it creates and returns a private ReverseIterator implementation, which simply maps calls to hasNext() to hasPrevious() and calls to next() are mapped to previous(). It means you could iterate over an ArrayList in reverse as follows:
ArrayList<String> l = ...
for (String s : new ReverseIterable(l)) {
System.err.println(s);
}
Class Definition
public class ReverseIterable<T> implements Iterable<T> {
private static class ReverseIterator<T> implements Iterator {
private final ListIterator<T> it;
public boolean hasNext() {
return it.hasPrevious();
}
public T next() {
return it.previous();
}
public void remove() {
it.remove();
}
}
private final ArrayList<T> l;
public ReverseIterable(ArrayList<T> l) {
this.l = l;
}
public Iterator<T> iterator() {
return new ReverseIterator(l.listIterator(l.size()));
}
}
If the lists are fairly small so that performance is not a real issue, one can use the reverse-metod of the Lists-class in Google Guava. Yields pretty for-each-code, and the original list stays the same. Also, the reversed list is backed by the original list, so any change to the original list will be reflected in the reversed one.
import com.google.common.collect.Lists;
[...]
final List<String> myList = Lists.newArrayList("one", "two", "three");
final List<String> myReverseList = Lists.reverse(myList);
System.out.println(myList);
System.out.println(myReverseList);
myList.add("four");
System.out.println(myList);
System.out.println(myReverseList);
Yields the following result:
[one, two, three]
[three, two, one]
[one, two, three, four]
[four, three, two, one]
Which means that reverse iteration of myList can be written as:
for (final String someString : Lists.reverse(myList)) {
//do something
}
You could use ReverseListIterator from Apache Commons-Collections:
https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/iterators/ReverseListIterator.html
Very simple Example:
List<String> list = new ArrayList<String>();
list.add("ravi");
list.add("kant");
list.add("soni");
// Iterate to disply : result will be as --- ravi kant soni
for (String name : list) {
...
}
//Now call this method
Collections.reverse(list);
// iterate and print index wise : result will be as --- soni kant ravi
for (String name : list) {
...
}
To have code which looks like this:
List<Item> items;
...
for (Item item : In.reverse(items))
{
...
}
Put this code into a file called "In.java":
import java.util.*;
public enum In {;
public static final <T> Iterable<T> reverse(final List<T> list) {
return new ListReverseIterable<T>(list);
}
class ListReverseIterable<T> implements Iterable<T> {
private final List<T> mList;
public ListReverseIterable(final List<T> list) {
mList = list;
}
public Iterator<T> iterator() {
return new Iterator<T>() {
final ListIterator<T> it = mList.listIterator(mList.size());
public boolean hasNext() {
return it.hasPrevious();
}
public T next() {
return it.previous();
}
public void remove() {
it.remove();
}
};
}
}
}
Create a custom reverseIterable.
Also found google collections reverse method.
How about using DeQue:
var queue = new ArrayDeque<>(list);
while (!queue.isEmpty()) {
var first = reversed ? queue.removeLast() : queue.removeFirst();
var second = reversed ? queue.peekLast() : queue.peekFirst();
if (second != null) {
//your code goes here
}
}
As has been suggested at least twice, you can use descendingIterator with a Deque, in particular with a LinkedList. If you want to use the for-each loop (i.e., have an Iterable), you can construct and use a wraper like this:
import java.util.*;
public class Main {
public static class ReverseIterating<T> implements Iterable<T> {
private final LinkedList<T> list;
public ReverseIterating(LinkedList<T> list) {
this.list = list;
}
#Override
public Iterator<T> iterator() {
return list.descendingIterator();
}
}
public static void main(String... args) {
LinkedList<String> list = new LinkedList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
for (String s : new ReverseIterating<String>(list)) {
System.out.println(s);
}
}
}
Valid for Java 9+
List<String> strList = List.of("a", "b", "c", "d", "e");
IntStream.iterate(strList.size() - 1, i -> i >= 0, i -> --i)
.mapToObj(strList::get)
.forEach(System.out::println);
Reason : "Don't know why there is no descendingIterator with ArrayList..."
Since array list doesnot keep the list in the same order as data has been added to list. So, never use Arraylist .
Linked list will keep the data in same order of ADD to list.
So , above in my example, i used ArrayList() in order to make user to twist their mind and make them to workout something from their side.
Instead of this
List<String> list = new ArrayList<String>();
USE:
List<String> list = new LinkedList<String>();
list.add("ravi");
list.add("kant");
list.add("soni");
// Iterate to disply : result will be as --- ravi kant soni
for (String name : list) {
...
}
//Now call this method
Collections.reverse(list);
// iterate and print index wise : result will be as --- soni kant ravi
for (String name : list) {
...
}

Categories