Using Iterator - java.util.ConcurrentModificationException - java

So, this returns me
java.util.ConcurrentModificationException
and points to System.out.println line
Iterator<Autor> it = autores.iterator();
// Declaring a class iterator
public void listarAutores() {
while (it.hasNext()) {
String aux = it.next().getNomeCompleto();
// Get string from Class Autor method
System.out.println(aux);
// Printing that string
}
}
Why it's happening and how can i fix it?

This can happen if you modify the collection between two calls to the method. For example:
listarAutores();
autores.add(anotherAuthor);
listarAutores();
You should create a new iterator in the method at every call or, even better, not use an iterator at all:
public void listarAutores() {
for (Author a : autores) {
String aux = a.getNomeCompleto();
// Get string from Class Autor method
System.out.println(aux);
// Printing that string
}
}

Move your Iterator into the method call. You probably modify the Set somewhere in between.

Related

Second calling of an method with iterator throws ConcurrentModificationException

What I try to do - call twice the a method on two different List:
Element P must be removed if isTranslation() is true.
Element P and the following element must be removed if the isTitle() is true;
I'm running the following code:
private List<P> nlPars; //initialised in constructor
private List<P> enPars; //initialised in constructor
public void build(){
...
removeHeaders(nlPars); //first time calling, no problem
removeHeaders(enPars); //second time calling, throws ConcurrentModificationException
...
}
calling this method:
#VisibleForTesting
void removeHeaders(final List<P> pars) {
pars.removeIf(p -> isTranslation(p));
for (final ListIterator<P> it = pars.listIterator(); it.hasNext(); ) {
if (isTitle(it.next())) {
it.remove();
if (it.hasNext()) {
it.next();
it.remove();
}
break;
}
}
}
I have no idea why. The debugger tells me that on the second time, the pars.listIterator() cannot be evaluated/throws ConcurrentModificationException.
I've been looking for hours now to fix this. Maybe someone can help!
Regards,
Bart
I solved it, the problem was not here. The problem was in the construction of enPars en nlPars. They were derived like nlPars = pars.subList(...). That's fine, but they are views on the pars list and the iterator is the same, hence the problem.
Changing it solved the issue:
enPars = new ArrayList<P>(pars.subList(0, i));

Creating a HashSet in one class, want to call/read in another class

I've got two classes in my program, in one I create a HashSet called 'words' and I need to be able to call from that HashSet in the other class, or otherwise copy the HashSet across. I'd prefer to do the former, it seems tidier, but either would be fine.
The code I have at the moment where I want/need to call the HashSet is such:
private void execute(String[] commands)
{
String basicCommand = commands[0];
//this is something I have used in a previous project to call from the HashSet
for (String word : words)
{
if(basicCommand.equals("circle")) {
makeACircle(commands);
}
if(basicCommand.equals(word))
{EMPTY FOR NOW}
else if(basicCommand.equals("help")) {
printHelp();
}
else {
System.out.println("Unknown command: " + basicCommand);
}
}
}`
And the code for my HashSet is:
public String[] getInput()
{
System.out.print("> "); // print prompt
String inputLine = reader.nextLine().trim().toLowerCase();
String[] wordArray = inputLine.split(" "); // split at spaces
// add words from array into hashset
for(String word : wordArray) {
words.add(word);
}
return wordArray;
}
(The HashSet 'words' is defined earlier in the class)
If HashSet is non-static
Create getHashSet() method in your class containing the HashSet. It returns a reference to the hashset.
Create a new instance of the class containing HashSet in the class where you wanna access this HashSet. Call instance.getHashSet();
if HashSet is static
(Its better to make it public as well..)
use ClassContainingHashSet.hashSet to get hashset.
EDIT :
public class MyFirstClass{
public static Set<YourType> mySet = new HashSet<yourType>();
}
class MySecondClass{
public void readHashSet()
{
HashSet<YourType> hs = MyFirstClass.mySet;
}
}
Note : This is not the exact code.. This is sample code.

ConcurrentModificationException for Java LinkedList

I have LinkedList of objects and an iterator. I know that this ConcurrentModificationException is thrown when you try to modify the list while running the iterator. But in my case, I don't understand where this modification is being done.
The iterator looks like this :
private static void insertTasks(Task t) {
if(eventQueue.size() == 0) {
eventQueue.addFirst(tsk);
return;
}
int pos = 0;
while (itr.hasNext()){
//The line below throws the exception
if (t.getArrivalTime() <= itr.next().getArrivalTime() )
{
break;
}
pos++;
}
}
I am calling this insertTasks method from another method as shown below :
tsk = null;
tsk = new Task(1,"P1",1,4.0f,1.5f,0.0f,8.0f);
insertTasks(tsk);
tsk = null;
tsk = new Task(0,"P0",2,5.0f,2.5f,1.0f,10.0f);
insertTasks(tsk);
The getArrivalTime in the Task objects looks like :
public float getArrivalTime() { return arrivalTime; }
My question is, where am I doing this modification ? The while loop where I run this iterator is not doing any modification. Does it ?
Am I missing something ?
I reckon the problem is that itr is a static field in your class and that's creating the issue, as you're adding an element to eventQueue in your second call to insertTasks().
Avoid static fields... program yourself to fear them and avoid them as much as you can :). They evil, and OO unfriendly.

How to print out all the elements of a List in Java?

I am trying to print out all the elements of a List, however it is printing the pointer of the Object rather than the value.
This is my printing code...
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
Could anyone please help me why it isn't printing the value of the elements.
The following is compact and avoids the loop in your example code (and gives you nice commas):
System.out.println(Arrays.toString(list.toArray()));
However, as others have pointed out, if you don't have sensible toString() methods implemented for the objects inside the list, you will get the object pointers (hash codes, in fact) you're observing. This is true whether they're in a list or not.
Since Java 8, List inherits a default "forEach" method which you can combine with the method reference "System.out::println" like this:
list.forEach(System.out::println);
Here is some example about getting print out the list component:
public class ListExample {
public static void main(String[] args) {
List<Model> models = new ArrayList<>();
// TODO: First create your model and add to models ArrayList, to prevent NullPointerException for trying this example
// Print the name from the list....
for(Model model : models) {
System.out.println(model.getName());
}
// Or like this...
for(int i = 0; i < models.size(); i++) {
System.out.println(models.get(i).getName());
}
}
}
class Model {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
System.out.println(list);//toString() is easy and good enough for debugging.
toString() of AbstractCollection will be clean and easy enough to do that. AbstractList is a subclass of AbstractCollection, so no need to for loop and no toArray() needed.
Returns a string representation of this collection. The string representation consists of a list of the collection's elements in the
order they are returned by its iterator, enclosed in square brackets
("[]"). Adjacent elements are separated by the characters ", " (comma
and space). Elements are converted to strings as by
String.valueOf(Object).
If you are using any custom object in your list, say Student , you need to override its toString() method(it is always good to override this method) to have a meaningful output
See the below example:
public class TestPrintElements {
public static void main(String[] args) {
//Element is String, Integer,or other primitive type
List<String> sList = new ArrayList<String>();
sList.add("string1");
sList.add("string2");
System.out.println(sList);
//Element is custom type
Student st1=new Student(15,"Tom");
Student st2=new Student(16,"Kate");
List<Student> stList=new ArrayList<Student>();
stList.add(st1);
stList.add(st2);
System.out.println(stList);
}
}
public class Student{
private int age;
private String name;
public Student(int age, String name){
this.age=age;
this.name=name;
}
#Override
public String toString(){
return "student "+name+", age:" +age;
}
}
output:
[string1, string2]
[student Tom age:15, student Kate age:16]
Use String.join()
for example:
System.out.print(String.join("\n", list));
The Java 8 Streams approach...
list.stream().forEach(System.out::println);
The objects in the list must have toString implemented for them to print something meaningful to screen.
Here's a quick test to see the differences:
public class Test {
public class T1 {
public Integer x;
}
public class T2 {
public Integer x;
#Override
public String toString() {
return x.toString();
}
}
public void run() {
T1 t1 = new T1();
t1.x = 5;
System.out.println(t1);
T2 t2 = new T2();
t2.x = 5;
System.out.println(t2);
}
public static void main(String[] args) {
new Test().run();
}
}
And when this executes, the results printed to screen are:
t1 = Test$T1#19821f
t2 = 5
Since T1 does not override the toString method, its instance t1 prints out as something that isn't very useful. On the other hand, T2 overrides toString, so we control what it prints when it is used in I/O, and we see something a little better on screen.
Or you could simply use the Apache Commons utilities:
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ArrayUtils.html#toString-java.lang.Object-
List<MyObject> myObjects = ...
System.out.println(ArrayUtils.toString(myObjects));
Consider a List<String> stringList which can be printed in many ways using Java 8 constructs:
stringList.forEach(System.out::println); // 1) Iterable.forEach
stringList.stream().forEach(System.out::println); // 2) Stream.forEach (order maintained generally but doc does not guarantee)
stringList.stream().forEachOrdered(System.out::println); // 3) Stream.forEachOrdered (order maintained always)
stringList.parallelStream().forEach(System.out::println); // 4) Parallel version of Stream.forEach (order not maintained)
stringList.parallelStream().forEachOrdered(System.out::println); // 5) Parallel version ofStream.forEachOrdered (order maintained always)
How are these approaches different from each other?
First Approach (Iterable.forEach)-
The iterator of the collection is generally used and that is designed to be fail-fast which means it will throw ConcurrentModificationException if the underlying collection is structurally modified during the iteration. As mentioned in the doc for ArrayList:
A structural modification is any operation that adds or deletes one or
more elements, or explicitly resizes the backing array; merely setting
the value of an element is not a structural modification.
So it means for ArrayList.forEach setting the value is allowed without any issue. And in case of concurrent collection e.g. ConcurrentLinkedQueue the iterator would be weakly-consistent which means the actions passed in forEach are allowed to make even structural changes without ConcurrentModificationExceptionexception being thrown. But here the modifications might or might not be visible in that iteration.
Second Approach (Stream.forEach)-
The order is undefined. Though it may not occur for sequential streams but the specification does not guarantee it. Also the action is required to be non-interfering in nature. As mentioned in doc:
The behavior of this operation is explicitly nondeterministic. For
parallel stream pipelines, this operation does not guarantee to
respect the encounter order of the stream, as doing so would sacrifice
the benefit of parallelism.
Third Approach (Stream.forEachOrdered)-
The action would be performed in the encounter order of the stream. So whenever order matters use forEachOrdered without a second thought. As mentioned in the doc:
Performs an action for each element of this stream, in the encounter
order of the stream if the stream has a defined encounter order.
While iterating over a synchronized collection the first approach would take the collection's lock once and would hold it across all the calls to action method, but in case of streams they use collection's spliterator, which does not lock and relies on the already established rules of non-interference. In case collection backing the stream is modified during iteration a ConcurrentModificationException would be thrown or inconsistent result may occur.
Fourth Approach (Parallel Stream.forEach)-
As already mentioned no guarantee to respect the encounter order as expected in case of parallel streams. It is possible that action is performed in different thread for different elements which can never be the case with forEachOrdered.
Fifth Approach (Parallel Stream.forEachOrdered)-
The forEachOrdered will process the elements in the order specified by the source irrespective of the fact whether stream is sequential or parallel. So it makes no sense to use this with parallel streams.
I have faced similar problems. My code:
List<Integer> leaveDatesList = new ArrayList<>();
.....inserted value in list.......
Way 1: printing a list in a for loop
for(int i=0;i<leaveDatesList.size();i++){
System.out.println(leaveDatesList.get(i));
}
Way 2: printing the list in a forEach, for loop
for(Integer leave : leaveDatesList){
System.out.println(leave);
}
Way 3: printing the list in java 8
leaveDatesList.forEach(System.out::println);
You haven't specified what kind of elements the list contains, if it is a primitive data type then you can print out the elements.
But if the elements are objects then as Kshitij Mehta mentioned you need to implement (override) the method "toString" within that object - if it is not already implemented - and let it return something meaning full from within the object, example:
class Person {
private String firstName;
private String lastName;
#Override
public String toString() {
return this.firstName + " " + this.lastName;
}
}
It depends on what type of objects stored in the List, and whether it has implementation for toString() method. System.out.println(list) should print all the standard java object types (String, Long, Integer etc). In case, if we are using custom object types, then we need to override toString() method of our custom object.
Example:
class Employee {
private String name;
private long id;
#Override
public String toString() {
return "name: " + this.name() +
", id: " + this.id();
}
}
Test:
class TestPrintList {
public static void main(String[] args) {
Employee employee1 =new Employee("test1", 123);
Employee employee2 =new Employee("test2", 453);
List<Employee> employees = new ArrayList(2);
employee.add(employee1);
employee.add(employee2);
System.out.println(employees);
}
}
For a list of array of String
list.forEach(s -> System.out.println(Arrays.toString((String[]) s )));
For loop to print the content of a list :
List<String> myList = new ArrayList<String>();
myList.add("AA");
myList.add("BB");
for ( String elem : myList ) {
System.out.println("Element : "+elem);
}
Result :
Element : AA
Element : BB
If you want to print in a single line (just for information) :
String strList = String.join(", ", myList);
System.out.println("Elements : "+strList);
Result :
Elements : AA, BB
System.out.println(list); works for me.
Here is a full example:
import java.util.List;
import java.util.ArrayList;
public class HelloWorld {
public static void main(String[] args) {
final List<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
System.out.println(list);
}
}
It will print [Hello, World].
list.stream().map(x -> x.getName()).forEach(System.out::println);
I wrote a dump function, which basicly prints out the public members of an object if it has not overriden toString(). One could easily expand it to call getters.
Javadoc:
Dumps an given Object to System.out, using the following rules:
If the Object is Iterable, all of its components are dumped.
If the Object or one of its superclasses overrides toString(), the "toString" is dumped
Else the method is called recursively for all public members of the Object
/**
* Dumps an given Object to System.out, using the following rules:<br>
* <ul>
* <li> If the Object is {#link Iterable}, all of its components are dumped.</li>
* <li> If the Object or one of its superclasses overrides {#link #toString()}, the "toString" is dumped</li>
* <li> Else the method is called recursively for all public members of the Object </li>
* </ul>
* #param input
* #throws Exception
*/
public static void dump(Object input) throws Exception{
dump(input, 0);
}
private static void dump(Object input, int depth) throws Exception{
if(input==null){
System.out.print("null\n"+indent(depth));
return;
}
Class<? extends Object> clazz = input.getClass();
System.out.print(clazz.getSimpleName()+" ");
if(input instanceof Iterable<?>){
for(Object o: ((Iterable<?>)input)){
System.out.print("\n"+indent(depth+1));
dump(o, depth+1);
}
}else if(clazz.getMethod("toString").getDeclaringClass().equals(Object.class)){
Field[] fields = clazz.getFields();
if(fields.length == 0){
System.out.print(input+"\n"+indent(depth));
}
System.out.print("\n"+indent(depth+1));
for(Field field: fields){
Object o = field.get(input);
String s = "|- "+field.getName()+": ";
System.out.print(s);
dump(o, depth+1);
}
}else{
System.out.print(input+"\n"+indent(depth));
}
}
private static String indent(int depth) {
StringBuilder sb = new StringBuilder();
for(int i=0; i<depth; i++)
sb.append(" ");
return sb.toString();
}
I happen to be working on this now...
List<Integer> a = Arrays.asList(1, 2, 3);
List<Integer> b = Arrays.asList(3, 4);
List<int[]> pairs = a.stream()
.flatMap(x -> b.stream().map(y -> new int[]{x, y}))
.collect(Collectors.toList());
Consumer<int[]> pretty = xs -> System.out.printf("\n(%d,%d)", xs[0], xs[1]);
pairs.forEach(pretty);
public static void main(String[] args) {
answer(10,60);
}
public static void answer(int m,int k){
AtomicInteger n = new AtomicInteger(m);
Stream<Integer> stream = Stream.generate(() -> n.incrementAndGet()).limit(k);
System.out.println(Arrays.toString(stream.toArray()));
}
try to override toString() method as you want that the element will be printend.
so the method to print can be this:
for(int i=0;i<list.size();i++){
System.out.println(list.get(i).toString());
}
Solusion of your problem for java 11 is:
String separator = ", ";
String toPrint = list.stream().map(o -> String.valueOf(o)).collect(Collectors.joining(separator));
System.out.println(toPrint);
You can try:
for 2D(or more)
System.out.println(Arrays.deepToString(list.toArray()));
for 1D
System.out.println(Arrays.toString(list.toArray()))
List<String> textList= messageList.stream()
.map(Message::getText)
.collect(Collectors.toList());
textList.stream().forEach(System.out::println);
public class Message {
String name;
String text;
public Message(String name, String text) {
this.name = name;
this.text = text;
}
public String getName() {
return name;
}
public String getText() {
return text;
}
}

NoElementException but I print the element and get the expected result

What I am trying to do is save a Move objects into a Vector called topMoves. There will be many Move objects which is why I create the object within the loop.
The pastPriceMap stores prices for stocks at some past time (in this case one minute ago). The currPriceMap stores price for stocks some time within the last second.
I get the following exception:
Exception in thread "Timer-0" java.util.NoSuchElementException
This is the line that is causing the problem:
amove.setInitPrice(pastPriceMap.get(iter.next()));
The code snippet is below. When I do the System.out.println statements I get the expected output:
Iterator<String> iter = sortedTopCodes.iterator();
while(iter.hasNext()){
System.out.println(currPriceMap.get(iter.next()));
System.out.println(pastPriceMap.get(iter.next()));
Move amove = new Move();
amove.setSecCode(iter.next());
amove.setPrice(currPriceMap.get(iter.next()));
amove.setInitPrice(pastPriceMap.get(iter.next()));
topMoves.add(amove);
}
return topMoves;
The Move class looks like this:
private String secCode;
private double price;
private double initPrice;
public String getSecCode() {
return secCode;
}
public void setSecCode(String secCode) {
this.secCode = secCode;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getInitPrice() {
return initPrice;
}
public void setInitPrice(double lastPrice) {
this.initPrice = lastPrice;
}
Short answer:
For each call to hasNext() there should be only one call to next()
In your code you have 5 next() with only one hasNext()
Here, read this: http://java.sun.com/javase/6/docs/api/java/util/Iterator.html
EDIT
Longer answer:
Basically an iterator is used to ... well iterate the elements of "something" tipically a collection but it could be anything ( granted that anything returns an Iterator ).
Since you may not know how many elements does that "anything" have, there must be a way to stop iterating right? ( if it was an array, you can tell by the length property, but the iterator is used to "encapsulate" the data structure used in the implementation ) Anyway.
The iterator API defines these two methods
-hasNext(): boolean
-next(): Object ( or <E> since Java 1.5 )
So the typical idiom is this:
while( iterator.hasNext() ) { // reads: while the iterator has next element
Object o = iterator.next(); // give me that element
}
What happens if the iterator has only two items?
while( iterator.hasNext() ) { // the first time will return true, so the next line will be executed.
Object o = iterator.next(); // give me that item. ( 1st element )
Object b = iterator.next(); // oops dangerous by may work ... ( 2nd element )
Object c = iterator.next(); // eeeerhhh... disaster: NoSuchElementException is thrown.
}
This is what is happening to you. You did not verify if the iterator has another element, you just retrieve it. If the iterator happens to have some elements, it may work for a while but there will be a time ( as you just saw ) when it fails.
By the way, DO NOT even think in catching NoSuchElementException. That's a runtime exception and it indicates that something in your code logic should be fixed.
See this answer to know more about the exceptions.
Here is a version using the new for loops:
for ( String secCode : secCodeList ) {
System.out.println(currPriceMap.get(secCode));
System.out.println(pastPriceMap.get(secCode));
Move amove = new Move();
amove.setSecCode(secCode);
amove.setPrice(currPriceMap.get(secCode));
amove.setInitPrice(pastPriceMap.get(secCode));
topMoves.add(amove);
}
in the older fashion :
String secCode = null;
for ( Iterator<String> it = secCodeList.iterator(); it.hasNext() ) {
secCode = it.next();
System.out.println(currPriceMap.get(secCode));
System.out.println(pastPriceMap.get(secCode));
Move amove = new Move();
amove.setSecCode(secCode);
amove.setPrice(currPriceMap.get(secCode));
amove.setInitPrice(pastPriceMap.get(secCode));
topMoves.add(amove);
}
// while there are more lines
while(scanner.hasNextLine())
{
final String line;
final String[] words;
// get the next line
line = scanner.nextLine();
// break the line up into the words (\\s+ should break it up via whitespace)
words = line.split("\\s");
if(words.length != 5)
{
throw new WhateverExceptionMakesSense(line + " must contain 5 words");
}
System.out.println(currPriceMap.get(words[0]));
System.out.println(pastPriceMap.get(words[1]));
Move amove = new Move();
amove.setSecCode(words[2]);
amove.setPrice(currPriceMap.get(words[3]));
amove.setInitPrice(pastPriceMap.get(words[4]));
topMoves.add(amove);
}

Categories

Resources