Page 1 of 2 12 LastLast
Results 1 to 20 of 22
  1. #1
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default foreach loop on ArrayList<Stack<String>>

    Hello

    I have decided to take it one small step at a time. Here's the code giving me errors:

    Java Code:
    for(Stack<String> s : paths)
    {
       if(s.peek() == n.getName())
       {
          p.push(n2.getName());
    	    					
          // Adding the stacked path [p] to the safe paths list [paths]
          paths.add(p);
    	    	    			
          // Now that the stacked path [p] has been stored, we need to clear, empty [p] for the next    path.
          p.clear();
       }
    }
    Where:

    Java Code:
    private ArrayList<Stack<String>> paths = new ArrayList<Stack<String>>();
    Right before the foreach loop executes I check paths (through debugger), and I can see that it does contain something. Yet I'm getting the error:

    No Exception Message - java.util.EmptyStackException
    I googled online how to do a Java foreach loop, and I can't see anything wrong with the Syntax. Indeed Eclipse doesn't complain about the syntax. ! What am I doing wrong ?

    PS. I believe you don't need to know what the variable [p] is because the code never gets to it.

    Thanks

  2. #2
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,618
    Rep Power
    25

    Default

    Java Code:
    s.peek() == n.getName(
    If these are objects like Strings, you should use the .equals() method to compare them. == is for primitives.

    When you get an error, please copy and paste the full text of the error message. It includes the line number where the error occurred.

    Add some printlns to show the contents of s each time around the loop.

  3. #3
    doWhile is offline Moderator
    Join Date
    Jul 2010
    Location
    California
    Posts
    1,641
    Rep Power
    7

    Default

    This won't result in the problem you seem to be seeing, but will potentially be a problem down the line: do not modify a List while iterating over that List (at least in this way - which uses an Iterator and could throw a ConcurrentModificationException when you modify the list). As an example, try running the following:

    Java Code:
    	public static void main(String[] args) throws Exception{
    		List<String> list = new ArrayList<String>();
    		
    		list.add("test");
    		for ( String s : list ){
    			list.add("temp");
    		}
           }
    Last edited by doWhile; 06-26-2011 at 11:10 PM.

  4. #4
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    Hi Norm.

    The full message is the following:



    Line 133 is the following line of code:

    Java Code:
    if(s.peek().equals(n.getName()))
    They both return String objects. I want to know if they are the same String (not that they have the same reference in memory).

    Thanks

  5. #5
    doWhile is offline Moderator
    Join Date
    Jul 2010
    Location
    California
    Posts
    1,641
    Rep Power
    7

    Default

    Right before the foreach loop executes I check paths (through debugger), and I can see that it does contain something.
    This exception isn't because paths is empty, it is because the stack you call the peek method on is empty. See the API for stack and this method

  6. #6
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,618
    Rep Power
    25

    Default

    Your post didn't show the values of s returned.
    Add some printlns to show the contents of s each time around the loop.

  7. #7
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    Quote Originally Posted by doWhile View Post
    This exception isn't because paths is empty, it is because the stack you call the peek method on is empty. See the API for stack and this method
    You are absolutely right. It is saying s is am empty Stack. But if that is the case, how do I tell it to:

    for each stack in path, do the following
    I thought my code did that, but apparently it isn't ! The variable [paths] is an ArrayList of Stack<String>'s. I know that Path has two Stacks, and these two stack are NOT empty.

  8. #8
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,618
    Rep Power
    25

    Default

    Add some printlns to show the contents of s each time around the loop.

  9. #9
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    Quote Originally Posted by Norm View Post
    Add some printlns to show the contents of s each time around the loop.
    Oops sorry Norm, forgot to mention you in my last reply. [s] would not print out anything, because it is saying it is empty.

  10. #10
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,618
    Rep Power
    25

    Default

    I thought you needed more evidence after:
    I know that Path has two Stacks, and these two stack are NOT empty.

  11. #11
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    LOL OK I'll go add a System.out.println(s); statement.

    Right, I've got the result back:

    []
    I'm guessing that's the sign of an Empty stack. !!

    Is the Syntax / Layout of my foreach loop correct ? Is it the right way for achieving the statement:

    for each stack in [paths], do the follwoing
    I'm confused.
    Last edited by Ciwan; 06-26-2011 at 11:38 PM.

  12. #12
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    After staring at the debugger like a Hawk, I figured out where the problem lies. You guys were right ! the Stack [s] was empty after all !!!!!!

    Here's where the problem lies.

    Java Code:
    // A variable called [neighbours]. It represents the neighoubrs of the current node in the loop
    ArrayList<Node<Adjustment>> neighbours = g.get(x);
            			
    // The Path [p] represented as a Stack. This will be inserted into our safe [paths] ArrayList later on.
    Stack<String> p = new Stack<String>();
            			
    // Iterating through the neighbours of the current node, and foreach building a path [p] from them. 
    for(Node<Adjustment> n : neighbours)
    {
         p.push(x.getName());
         p.push(n.getName());
            				
         // Adding the stacked path [p] to the safe paths list [paths]
         paths.add(p);
                			
         nodesUsed.add(n.getName());
                			
         // Now that the stacked path [p] has been stored, we need to clear, empty [p] for the next path.
         p.clear();
    }
    Notice the foreach loop. Each time it loops back around, my [paths] becomes zero-ed for some reason !!
    Last edited by Ciwan; 06-27-2011 at 12:32 AM.

  13. #13
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,618
    Rep Power
    25

    Default

    I'm guessing that's the sign of an Empty stack. !!
    You should put ids on printouts: ...println("s=" + s);
    If you have more than one printout you will need to have ids.

    This will remove p's contents: p.clear();
    You have stored a reference to p in another container: paths.add(p);
    You didn't copy the contents of p.
    There is only one p object, when it is cleared, all references will be to the one cleared object.

  14. #14
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    Hmm I got you now Norm.

    So how do I get around this issue ? Do I do something like:

    Java Code:
    paths.add(new Stack<String>(p));
    Thanks for the tip about the IDs for println.

  15. #15
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,618
    Rep Power
    25

    Default

    Set p to a new object, leaving the old one that p referred to safely referred to in the container. It was the value of p that was copied to the container and it will be safe there. p can now be set to a new object.

  16. #16
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    Quote Originally Posted by Norm View Post
    Set p to a new object, leaving the old one that p referred to safely referred to in the container.
    Do you mean like so:

    Java Code:
    // The Path [p] represented as a Stack. This will be inserted into our safe [paths] ArrayList later on.
    Stack<String> p = new Stack<String>();
            			
    // Iterating through the neighbours of the current node, and foreach building a path [p] from them. 
    for(Node<Adjustment> n : neighbours)
    {
         p.push(x.getName());
         p.push(n.getName());
            				
         // Adding the stacked path [p] to the safe paths list [paths]
         paths.add(new Stack<String>());
                			
         nodesUsed.add(n.getName());
                			
         // Now that the stacked path [p] has been stored, we need to assign it to a new object.
         p = new Stack<String>();
    }
    Cause that too only places empty stack in my [paths] variable !

  17. #17
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,618
    Rep Power
    25

    Default

    Java Code:
    // A variable called [neighbours]. It represents the neighoubrs of the current node in the loop
    ArrayList<Node<Adjustment>> neighbours = g.get(x);
            			
    // The Path [p] represented as a Stack. This will be inserted into our safe [paths] ArrayList later on.
    Stack<String> p = new Stack<String>();
            			
    // Iterating through the neighbours of the current node, and foreach building a path [p] from them. 
    for(Node<Adjustment> n : neighbours)
    {
         p.push(x.getName());
         p.push(n.getName());
            				
         // Adding the stacked path [p] to the safe paths list [paths]
         paths.add(p);
                			
         nodesUsed.add(n.getName());
                			
         // Now that the stacked path [p] has been stored, we need a new empty [p] for the next path.
         p[B] = new Stack<String>();[/B]
    }

  18. #18
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    Thank You Norm. It WORKED. I had forgotten that I changed the add line earlier Thank You So Much.

    Now however I am getting a new error, as the new error is again related to forloops and iterations, I won't bother with a new thread.

    Here's the code (you've seen earlier):

    Java Code:
    public void buildOnPaths(ArrayList<Node<Adjustment>> neighbours)
    {
        // The Path [p] represented as a Stack. This will be inserted into our safe [paths] ArrayList later on.
        Stack<String> p = new Stack<String>();
    		
        for(Node<Adjustment> n : neighbours)
        {
        	for(Node<Adjustment> n2 : g.get(n))
            {
        	    if(!nodesUsed.contains(n2.getName()))
        	    {
    	        [B]for(Stack<String> s : paths)[/B]
    	    	{
    	    	    if(s.peek().equals(n.getName()))
    	    	    {
    	    	        p.push(n2.getName());
    	    					
    	    		// Adding the stacked path [p] to the safe paths list [paths]
    	    	    	paths.add(p);
    	    	    			
    	    	    	// Now that the stacked path [p] has been stored, we need a new empty [p] for the next path.
    	    	    	p = new Stack<String>();
    	    	    }
    	    	}
        	    }
            }
        }
    }
    The error I am getting is:



    I have done a bit of google searching, and I found this:

    The most common way to encounter this (Error) is to remove elements from the collection while walking through the iterator.
    I am not removing elements, I am however adding them, which I think makes it a safe assumption that, that is the source of the error.

    I have gone ahead and bolded the code line where the error is. I am however unsure as to how I'd get over it.

  19. #19
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,618
    Rep Power
    25

    Default

    If your logic can handle the additional elements being added to the container, don't use an iterator,
    Use the old fashion for loop.

    With poor logic you could add an infinite number of elements to the container.

  20. #20
    Ciwan is offline Banned
    Join Date
    Dec 2008
    Location
    Earth
    Posts
    87
    Rep Power
    0

    Default

    Thank You Norm, for both, the advice about using the traditional for loop, and for the warning about adding infinite numbers of elements to the ArrayList.

    I believe I have sorted it out with the following:

    Java Code:
    public void buildOnPaths(ArrayList<Node<Adjustment>> neighbours)
        {
        	// The Path [p] represented as a Stack. This will be inserted into our safe [paths] ArrayList later on.
    		Stack<String> p = new Stack<String>();
    		
        	for(Node<Adjustment> n : neighbours)
        	{
        		for(Node<Adjustment> n2 : g.get(n))
            	{
        			// perhaps a check to see if the neighbour of the neighbour is an Exit node.
        			//TODO: Exit Node Check
        			
        			if(!nodesUsed.contains(n2.getName()))
        			{
        				// traditional for loop to iterate over each stack in [paths]
        				for(int i=0; i < paths.size(); i++)
        				{
        					if(paths.get(i).peek().equals(n.getName()))
        					{
        						// I now have hold of a path stack, e.g. [A, B]
        						Stack<String> tempStack = paths.get(i);
        						
        						// Adding the new Node to the Path, so the temporary stack path becomes >> [A, B, F]
        						tempStack.push(n2.getName());
    	    					
    	    					// Adding the temporary stacked path to the safe paths list [paths]
    	    	    			paths.add(tempStack);
        					}
        				}
        			}
            	}
        	}
        }
    The above code gives me the following stacks within my ArrayList<Stack<String>> called [paths].

    {[AB], [AC], [ABF], [ACD]}

    I believe what I need to do now is have the method use recursion, and this way I can have all the available paths ... I'm excited

Page 1 of 2 12 LastLast

Similar Threads

  1. Stack to an ArrayList<String>
    By Ciwan in forum New To Java
    Replies: 5
    Last Post: 05-22-2011, 09:00 PM
  2. Stack (collection) to int via String
    By aborgeld in forum New To Java
    Replies: 7
    Last Post: 04-07-2011, 06:16 PM
  3. Replies: 12
    Last Post: 11-26-2010, 09:33 AM
  4. Replies: 1
    Last Post: 11-04-2010, 07:53 PM
  5. Question regarding foreach loop...
    By theonlywalks in forum New To Java
    Replies: 2
    Last Post: 03-15-2008, 07:15 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •