I have an assignment I am having a hard time completing. It is a two part lab which demonstrates the LinkedList and Queue classes. I have to use the offer() method and an iterator to complete the part I am having issues with. I wrote a class called BasketBallPlayer and added several objects of that type to a linkedList using add. Then I used an iterator to list those objects. However, when I use the offer() method, I am unable to list the objects with my code. This is the snippet which throws a concurrent modification exception
LinkedList<BasketBallPlayer> list =
new LinkedList<BasketBallPlayer>();
Iterator listIterator = list.iterator();
list.offer(kyrie);
list.offer(kat) ;
list.offer(julius);
list.offer(kawhi) ;
list.offer(devin);
while(listIterator.hasNext())
System.out.println(listIterator.next());
This is the entire class from that snippet.
import java.util.Iterator;
public class Queue {
public static void main (String[] args)
{
BasketBallPlayer kyrie = new BasketBallPlayer(
"Kyrie Irving", 1, "Cavaliers");
BasketBallPlayer kat = new BasketBallPlayer(
"Karl Anthony Towns", 5, "Timberwolves");
BasketBallPlayer julius = new BasketBallPlayer(
"Julius Randle", "Power Forward", "Lakers");
BasketBallPlayer kawhi = new BasketBallPlayer(
"Kawhi Leanord", "Small Forward", "Spurs");
BasketBallPlayer devin = new BasketBallPlayer(
"Devin Booker", "Shooting Guard", "Suns");
System.out.println(kyrie);
LinkedList<BasketBallPlayer> list =
new LinkedList<BasketBallPlayer>();
Iterator listIterator = list.iterator();
list.offer(kyrie);
list.offer(kat) ;
list.offer(julius);
list.offer(kawhi) ;
list.offer(devin);
Iterator iterator = list.iterator();
while(iterator.hasNext())
{
Object player = listIterator.next();
System.out.println(player);
}
System.out.println("Which player is first?");
System.out.println(list.peek());
for(Object player: list)
{
System.out.println(list.getFirst());
list.poll();
}
}
}
lastly, the BasketballPlayer class. This class contains part 1 of the assignment. Here I demonstrate linkedList methods. This part works. I am unsure why the iterator in part 1 is not throwing exceptions while the iterator in part 2 is despite being used almost exactly the same. Can anyone educate me on how to correct my mistake?
import java.util.Locale;
import java.util.LinkedList;
import java.util.ListIterator;
public class BasketBallPlayer
{
private String name = "" , position = ""; String team = "";
private int positionNumber = 0;
public BasketBallPlayer()
{
name = "noName";
position = "noPosition";
team = "noTeam";
positionNumber = 0;
}
public BasketBallPlayer(String playersName, int thePositionNumber,
String theTeam)
{
setName(playersName); setPositionNumber(thePositionNumber);
setTeam(theTeam);
}
public BasketBallPlayer(String playersName, String playersPosition,
String theTeam)
{
setName(playersName);
setPosition(playersPosition);
setTeam(theTeam
);
}
public void setName(String theName)
{
this.name = theName;
}
public void setTeam(String theTeam)
{
this.team = theTeam;
}
public void setPosition(String playerPosition)
{
this.position = playerPosition;
if(playerPosition.contains("oint"))
this.positionNumber = 1;
else if(playerPosition.contains("hoot"))
this.positionNumber = 2;
else if(playerPosition.contains("mall"))
this.positionNumber = 3;
else if(playerPosition.contains("ower"))
this.positionNumber = 4;
else if(playerPosition.contains("enter"))
this.positionNumber = 5;
}
public void setPositionNumber(int thePositionNumber)
{
this.positionNumber = thePositionNumber;
switch(thePositionNumber){
case 1: setPosition("Point Guard");
break;
case 2: setPosition("Shooting Guard");
break;
case 3: setPosition("Small Forward");
break;
case 4: setPosition("Power Forward");
break;
case 5: setPosition("Center");
break;
}
}
public String getName()
{
return name;
}
public String getPosition()
{
return position;
}
public int getPositionNumber()
{
return positionNumber;
}
public String getTeam()
{
return team;
}
public boolean equals(Object other)
{
BasketBallPlayer objectToCompare;
if(other != null && other.getClass() == getClass())
objectToCompare = (BasketBallPlayer) other;
else
return false;
return(
(getPositionNumber() == objectToCompare.getPositionNumber()) &&
(getName() == objectToCompare.getName()) &&
getTeam() == objectToCompare.getTeam()) ;
}
public String toString()
{
if(getTeam().equals("Retired"))
return getName() + " is retired.";
else
return getName()+ " plays for the " + getTeam();
}
public static void main (String[] args)
{
// five basketball player objects
BasketBallPlayer kobe = new BasketBallPlayer("Kobe Bryant",
"Shooting Guard", "Retired");
BasketBallPlayer ben = new BasketBallPlayer(
"Ben Wallace", 5, "Retired");
BasketBallPlayer otto = new BasketBallPlayer("Otto Porter", 3,
"Wizards");
BasketBallPlayer andre = new BasketBallPlayer("Andre Drummond",
"Center", "Pistons");
BasketBallPlayer thomas = new BasketBallPlayer("Isaiah Thomas",
1, "Celtics");
BasketBallPlayer isaiah = new BasketBallPlayer("Isaiah Thomas",
"Point Guard", "Pistons");
// initialize LinkedList and add three players
LinkedList list = new LinkedList();
list.add(kobe); list.add(otto);
list.add(thomas);
// display the first one
System.out.println("First player on the list");
System.out.println(list.peek());
System.out.println();
System.out.println(kobe.getName() +
" is retired so let's remove him.");
// remove object at index 0
list.remove(0);
System.out.println();
// add andre to the top of the list
list.addFirst(andre);
// add ben to the end
list.addLast(ben);
System.out.println("New first player on the list");
System.out.println(list.peek());
// first create an Object[] which acts as a BasketBallPlayer[]
System.out.println(
"Any other retired players? Printing entire list:");
// using toArray()
Object[] other = list.toArray();
for(Object player: other)
// display each player in the array
System.out.println(player);
// demonstrate contains()
if(list.contains(ben))
list.remove(ben);
System.out.println();
System.out.println("Let's remove the retired player");
System.out.println("Is " + ben.getName() +
" still on the list?");
if(list.contains(ben))
System.out.println(ben.getName() + " is still on the list");
else
{
System.out.println(ben.getName() + " is not on the list");
System.out.println("How many players after removing? "
+ list.size());
}
System.out.println();
System.out.println(otto.getName() + " is " +
// demonstrate indexOf()
(list.indexOf(otto) + 1) + " on the list");
// create an iterator
ListIterator listIterator = list.listIterator();
System.out.println("Printing list using iterator:");
// print out the list using the iterator
while(listIterator.hasNext())
{
Object player = listIterator.next();
System.out.println(player);
}
}
One problem with the standard collections in java (and also in C#) is that you may not modify them while iterating over them.
If no extra steps are taken, and if you are unlucky, you may get no exception, just erratic program behavior. To remedy this, java does actually take an extra step: iterators actually check to make sure that you do not modify the collection while iterating, and throw a ConcurrentModificationException
if you do so, as soon as possible after you do so.
This feature is called "fail-fast" iterators, that's a term you can look up.
So, from the moment you instantiate an iterator, until the moment you stop using it, you may not modify the collection from which the iterator was created.
Can you spot the place in your code where you do that?
Also, regarding what your professor said: either you did not understand what your professor said, or what they said is wrong. Iterators that offer means of modifying the collection while iterating do actually work. For example, you can do iterator.remove()
to remove the current element. That works, because if you modify the collection via the iterator, then the iterator is in charge, so it can take whatever measures are necessary to prevent data corruption. What does not work, is modifying the collection by invoking any mutator methods directly on the collection itself while an iterator is active on the collection, because in that case the iterator has no knowledge of the fact that the collection is being modified at the moment that the collection is modified. The iterator throws a ConcurrentModificationException
later, when it gets invoked to do anything, and it finds out that the collection had been modified in the mean time.