Remove / add objects and avoid ConcurrentModificationException
              in 
             Programming Questions 
              •  
              7 months ago    
            
 
           
              I have a node layout which make together a map.
             
             
              On that map i use pathfinding to find routes.
             
             
              The format i used to load was not perfect so every node is on top of another node, for example in the image B, C and D will be on the same position.
             
             
              My goal is to keep only one of those 3 and relink the links.
             
             
              This is what the Node class looks like.
             
             - class Node implements Comparable<Node> {
 - int id;
 - float lon;
 - float lat;
 - // A*
 - float f = 0;
 - float g = 0;
 - float h = 0;
 - Node parent;
 - HashSet<Node> links = new HashSet<Node>();
 - Node() {
 - }
 - Node(float lon, float lat) {
 - this.id = idCount++;
 - this.lon = lon;
 - this.lat = lat;
 - }
 - Node(int id, float lon, float lat) {
 - this.id = id;
 - this.lon = lon;
 - this.lat = lat;
 - }
 - void linkToNode(Node n) {
 - links.add(n);
 - }
 - void reset() {
 - f = g = h = 0;
 - parent = null;
 - }
 - int compareTo(Node n) {
 - if(f < n.f) return -1;
 - if(f == n.f) return 0;
 - return 1;
 - }
 - }
 
             So to reform what i want:
            
            
             I want B and C removed and A and E connected to D (or anything like that).
            
            
             I either have a bug, or i get a ConcurrentModificationException or  a  IllegalStateException.
            
            
             Here i have 3 attempts (i have more attempts but those where the best / closest i guess).
            
            
             There is one ArrayList called nodes which hold all nodes. So the overlapping ones have to be removed from there, except one. And then every node has a hashSet called links, the ones that get removed from nodes shouldn't be present anymore in links.
            
            
             I hope this is enough to help.
            
            
             If not i will upload the files required to run my code later.
            
            - void mergeOverlappingNodes() {
 - for(int i = nodes.size()-1; i >= 0; i--) {
 - Node n = nodes.get(i);
 - for(Node linkedNode : n.links) {
 - if ( (n.lon == linkedNode.lon) && (n.lat == linkedNode.lat)) {
 - nodes.remove(linkedNode);
 - i--;
 - for(Node linkedNodeFromTheOneToRemove : linkedNode.links) {
 - linkedNodeFromTheOneToRemove.links.remove(linkedNode);
 - linkedNodeFromTheOneToRemove.links.add(n);
 - }
 - }
 - }
 - }
 - }
 
- void mergeOverlappingNodes() {
 - Iterator<Node> itr = nodes.iterator();
 - while(itr.hasNext()) {
 - Node n = itr.next();
 - boolean remove = false;
 - // check if the node can be removed
 - for(Node linkedNode : n.links) {
 - if ( (n.lon == linkedNode.lon) && (n.lat == linkedNode.lat)) {
 - remove = true;
 - break;
 - }
 - }
 - for(Node linkedNode : n.links) { //ConcurrentModificationException
 - linkedNode.links.remove(n);
 - }
 - for(Node linkedNode1 : n.links) {
 - for(Node linkedNode2 : n.links) {
 - linkedNode1.links.add(linkedNode2);
 - }
 - }
 - /*
 - for(Node aLinkedNodeFromTheOneToRemove : linkedNode.links) {
 - //if(aLinkedNodeFromTheOneToRemove == n) println("true");
 - aLinkedNodeFromTheOneToRemove.links.remove(linkedNode);
 - aLinkedNodeFromTheOneToRemove.links.add(n);
 - }
 - */
 - //linkedNode.links.add(n);
 - if(remove) itr.remove();
 - }
 - }
 
             One of the firsts, which has no error but a bug..
            
            - void mergeOverlappingNodesOld() {
 - Node theNode, otherNode;
 - for (int i = nodes.size()-1; i >= 0; i--) {
 - theNode = nodes.get(i);
 - ArrayList<Node> nodesOnTheSamePosition = new ArrayList<Node>();
 - // in this loop we find all nodes on the same position
 - // and add them to the ArrayList: nodesOnSamePosition
 - for (int j = nodes.size()-1; j >= 0; j--) {
 - otherNode = nodes.get(j);
 - if (theNode == otherNode) continue;
 - if ( (theNode.lon == otherNode.lon) && (theNode.lat == otherNode.lat)) {
 - nodesOnTheSamePosition.add(otherNode);
 - }
 - }
 - // now relink and remove
 - for(Node aNodeOnTheSamePosition : nodesOnTheSamePosition) {
 - for(Node linkedNode : aNodeOnTheSamePosition.links) {
 - theNode.links.add(linkedNode);
 - }
 - nodes.remove(aNodeOnTheSamePosition);
 - theNode.links.remove(aNodeOnTheSamePosition);
 - }
 - // added in attempt to bug fix
 - // now added above which in theory should work
 - /*
 - for(Node aNodeOnTheSamePosition : nodesOnTheSamePosition) {
 - theNode.links.remove(aNodeOnTheSamePosition);
 - }
 - */
 - // since nodes.size() is changed now we have to decrement i
 - i -= nodesOnTheSamePosition.size();
 - }
 - /*
 - Node node1, node2;
 - HashSet<Node> nodesToRemove = new HashSet<Node>();
 - //HashSet<Node> nodesNotToRemove = new HashSet<Node>();
 - for (int i = nodes.size()-1; i >= 0; i--) {
 - node1 = nodes.get(i);
 - for (int j = nodes.size()-1; j >= 0; j--) {
 - node2 = nodes.get(j);
 - if (node1 == node2) continue;
 - if (nodesToRemove.contains(node1)) continue;
 - if ( (node1.lon == node2.lon) && (node1.lat == node2.lat)) {
 - HashSet<Node> links = new HashSet<Node>(node1.links);
 - for (Node n : links) {
 - n.links.remove(node1);
 - n.links.add(node2);
 - // we have to remove them later else things go wrong
 - nodesToRemove.add(node1);
 - //nodesNotToRemove.add(node2);
 - }
 - }
 - }
 - }
 - // println(nodesToRemove.size());
 - Iterator<Node> itr = nodesToRemove.iterator();
 - while (itr.hasNext ()) {
 - Node nodeToRemove = itr.next();
 - //if(nodesNotToRemove.contains(nodeToRemove)) continue;
 - nodes.remove(nodeToRemove);
 - }
 - */
 - // check if correct
 - /*
 - for (Node n1 : nodes) {
 - for (Node n2 : nodes) {
 - if (n1 == n2) continue;
 - if ( (n1.lon == n2.lon) && (n1.lat == n2.lat)) {
 - println("my code is wrong...");
 - }
 - }
 - }
 - */
 - }
 
 
              
              1  
            
 
            