13 Replies Latest reply on Feb 10, 2009 7:34 AM by doremifasollatido

    HashMap and For Loop

    807588
      I've looked at a bunch of examples on line and read through several forums but I can't seem to figure out what I am doing wrong. I am trying to print out the contents of my HashMap.

      I am mounting components as subcomponents and then trying to print them out.
      public class GreenComponent implements I_Component{
         private final HashMap<String, GreenComponent> _components = new HashMap<String, GreenComponent>();
      .
      .
      .
         public void mountSubcomponent_(final GreenComponent component){
            assert (component != null);
            _components.put(_id, component);
            component.setSupercomponent_(this);
         }
      .
      .
      .
      public String toXML_(){
             StringBuilder string = new StringBuilder("<GREEN-COMPONENT id=\"" + _id + "\">");
             for (String str : _components.keySet()){
                 string.append(_components.get(str).toXML_());
             }
             string.append("</GREEN-COMPONENT>");
             return string.toString();
         }
      The Error is that it seems to only print the first and the last component in the Map, nothing in between.

      Edited by: shays on Feb 9, 2009 8:33 PM
        • 1. Re: HashMap and For Loop
          796440
          I don't see where you're printing anything.

          If you mean that toString only returns the "first and last" elements in the map (maps don't have order, so first and last are meaningless), then it looks like that method should cover every element. However, since it's recursive, it's not always intuitive to follow what it does.

          Add print statements at every relevant step--in particular print out each element of the keySet inside that loop--so that you can see what's going on.
          • 2. Re: HashMap and For Loop
            807588
            You are correct I just put the string together and then print it elsewhere. I have tried putting in a println statement in the loop and it returns only the first element that I put into the HashMap.
            • 3. Re: HashMap and For Loop
              796440
              shays wrote:
              You are correct I just put the string together and then print it elsewhere. I have tried putting in a println statement in the loop and it returns only the first element that I put into the HashMap.
              So when you have this:
                for (String str : _components.keySet()){
                  System.out.println(str);
                  string.append(_components.get(str).
                }
              It only prints the first element? Then you only have one element in the map.
              • 4. Re: HashMap and For Loop
                807588
                Main()...
                GrA.mountSubcomponent_(GrB);
                GrA.mountSubcomponent_(GrC);
                GrA.mountSubcomponent_(GrD);
                System.out.println(GrA.toXML_());
                .
                .
                .
                public String toXML_(){
                       StringBuilder string = new StringBuilder("<GREEN-COMPONENT id=\"" + _id + "\">");
                       for (String str : _components.keySet()){
                           System.out.println(str);
                           string.append(_components.get(str).toXML_());
                       }
                       string.append("</GREEN-COMPONENT>");
                       return string.toString();
                Output:
                GrA
                <GREEN-COMPONENT id="GrA"><GREEN-COMPONENT id="GrD"></GREEN-COMPONENT></GREEN-COMPONENT>
                • 5. Re: HashMap and For Loop
                  807588
                  Its strange that it will only print GrA but then below it prints both GrA and GrD. I included the mountsubcomponent method above as well because I wasn't sure if I was overwriting the elements, but I am baffled.

                  Edited by: shays on Feb 9, 2009 9:02 PM
                  • 6. Re: HashMap and For Loop
                    doremifasollatido
                    shays wrote:
                    Its strange that it will only print GrA but then below it prints both GrA and GrD. I included the mountsubcomponent method above as well because I wasn't sure if I was overwriting the elements, but I am baffled.
                    In your original post, you have:
                       public void mountSubcomponent_(final GreenComponent component){
                          assert (component != null);
                          _components.put(_id, component); // SEE NOTE BELOW!
                          component.setSupercomponent_(this);
                       }
                    What is id? If it never changes, then the line that I marked with a comment will overwrite the value stored at key id with the new value of component. Thus, only the last component you mounted (i.e., last parameter passed to mountSubcomponent_) will be stored. If you need to store them all, you need to use a different key for each, or you need to use a java.util.List (e.g., ArrayList or LinkedList) or java.util.Set. Which you use (Map with different keys, List, or Set) depends on what your ultimate goal is.

                    By the way, what's with all the underscores? That's not a typical Java naming convention.
                    • 7. Re: HashMap and For Loop
                      doremifasollatido
                      Also, if you want to produce XML, it might be better if you used a proper XML API, instead of hand-coding the XML as text. I've seen lots of errors caused by trying to generate XML using normal text processing commands [i.e., just concatenating String values]. The XML often ends up being malformed, and special characters don't get escaped properly.
                      • 8. Re: HashMap and For Loop
                        807588
                        main() 
                           GreenComponent GrA = new GreenComponent("GrA");
                            GreenComponent GrB = new GreenComponent("GrB");
                            GreenComponent GrC = new GreenComponent("GrC");
                            GreenComponent GrD = new GreenComponent("GrD");
                        .
                        .
                        .
                        class GreenComponent()...
                        public GreenComponent(final String id){
                              assert (id != null);
                              if (id.isEmpty()){
                                 throw new RuntimeException("empty ID");
                              }
                              _id = id;
                           }
                        So I believe the id's should be seperate. The underscores just let me know which variables and methods belong in a class.
                        • 9. Re: HashMap and For Loop
                          doremifasollatido
                          Yes, that makes the id values look separate (id is NOT static, right? You'll have a problem if it is static.).

                          I just realized your problem. You need this--note the key:
                             public void mountSubcomponent_(final GreenComponent component){
                                assert (component != null);
                                // Use the parameter component's _id, not the _id of the "this" component.
                                _components.put(component._id, component); // Note the key!
                                component.setSupercomponent_(this);
                             }
                          ===
                          Another thought (not necessary, but should work slightly faster):
                          Also, instead of:
                                 for (String str : _components.keySet()){
                                     System.out.println(str);
                                     string.append(_components.get(str).toXML_());
                                 }
                          You could use the values, instead of the key set, since you don't actually use the keys except to print them:
                                 for (GreenComponent comp : _components.values()){
                                     string.append(comp.getValue().toXML_());
                                 }
                          Or, iterate over the _components.entrySet(), which gives you each of the key/value pairs in turn (get both the key and value in one shot).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
                          • 10. Re: HashMap and For Loop
                            807588
                            If I use the println statement at the end of mountsubcomponent i get
                            {GrA=cs263_lab03.GreenComponent@f72617}
                            {GrA=cs263_lab03.GreenComponent@1e5e2c3}
                            {GrA=cs263_lab03.GreenComponent@18a992f}
                            • 11. Re: HashMap and For Loop
                              doremifasollatido
                              shays wrote:
                              If I use the println statement at the end of mountsubcomponent i get
                              {GrA=cs263_lab03.GreenComponent@f72617}
                              {GrA=cs263_lab03.GreenComponent@1e5e2c3}
                              {GrA=cs263_lab03.GreenComponent@18a992f}
                              Sorry, I edited my post. But, that does show that I was right. You keep using the same key over and over (each of those {GrA=...} is from a separate call to mountSubcomponent_--you only have one value in the map, and that value keeps changing). Go back and read my edited post. You need to use component._id as the key in the call to put.
                              • 12. Re: HashMap and For Loop
                                807588
                                Perfect... works beautifully. You are a genius.
                                • 13. Re: HashMap and For Loop
                                  doremifasollatido
                                  You're welcome! And thanks for the compliment! :)