0

So it turns out I was working (I'm not a Senior Developer yet as you can see) while out of the blue I realized something was wrong with my code. A Hashmap receives "true" instead of receiving an ArrayList with one object in its first position. As a matter of example you can see what I'm talking about as follows:

    Product item = new Product(); 
    Map rMap = new HashMap();        
    rMap.put("productsList", new ArrayList().add(item));

After certain lines of code, and coding helperMethods I attempted to retrieve that "productsList" from the map but I couldn't do so, I didn't know why so after debugging it I found out that when the PUT was done, there was no such a list, just a Boolean value. The way I retrieved it was as follows:

       if (rMap.containsKey("productsList")) {
           // This IF statement was being skipped because of the Boolean
           if (rMap.get("productsList") instanceof ArrayList) {   
               List<Product> pr = (List) rMap.get("productsList");                
           }
      }

On the other hand I've got this (which is way more clear) and woks as expected:

    Product item = new Product();
    Map rMap = new HashMap();
    List < Product > myList = new ArrayList();
    myList.add(item);

    rMap.put("productsList", myList);

What could be done in order to reduce those two lines of code where a List is created and a Object is set to the list? It's not a big deal of course, it's just I want to make my coding clearer and staightforward.

3 Answers3

1

You can use Arrays#asList method like this

map.put("productList", Arrays.asList(item1, item2, item3));

Also I would like to suggest you to use generics, you will get type-safety in exchange.

Map<String, List<String>> rMap = new HashMap<String, List<String>>();
rMapu.put("productList", Arrays.asList("item1", "item2"));
Petr Mensik
  • 26,874
  • 17
  • 90
  • 115
  • 1
    Maybe worth pointing that there list has a fixed size which may or may not be OK. – assylias Oct 12 '14 at 22:54
  • @PetrMensik Very thoughtful and professional response. Thanks! Althought I'd like to say that I don't use generics because whenever I use it "netbeans" throws a comment saying it's not neccesary but now I see not everything is correct, I'll certainly follow what you both pointed out. –  Oct 12 '14 at 22:58
  • 1
    Well, NetBeans is just an IDE and hints doesn't always have to be accurate:-) Anyway, best practice in Java is to use generics anywhere you can - also only this way the IDE or the compiler can tell if you are putting object of right type into your collection. – Petr Mensik Oct 12 '14 at 23:02
  • Great pieces of advice in order to code as it must be. Generics will be used from now on by me, thanks. –  Oct 12 '14 at 23:11
0

You could use Arrays#asList instead of new ArrayList().add(item), however that returns a fixed size list which may not be what you want.

Another way would be to use Map#computeIfAbsent like this to create and add a new list of the type you want to the map and then add the item to the list when it is returned.

Product item = new Product(); 
Map<String, List<Product>> rMap = new HashMap<>();        
rMap.computeIfAbsent("key", s -> new ArrayList<>()).add(item);
Alex - GlassEditor.com
  • 14,957
  • 5
  • 49
  • 49
  • 1
    Yes, I'm not sure for how long after it is released I should continue to state the version of Java that my answer requires. – Alex - GlassEditor.com Oct 12 '14 at 23:07
  • Haven't work with Java 8 yet, though as far as I know the use of the operator "->" is only valid in that version. It's good to know everything is being improved among versions- –  Oct 12 '14 at 23:09
  • Right, Java 8 is around for a while and I guess that most people are able to recognize lambda:) But still, most of the tutorials and examples are in Java 6 or 7 so it's more than possible that many OPs are using old JDK. – Petr Mensik Oct 12 '14 at 23:09
0

Another way is to use double brace initialization syntax:

rMap.put("productsList", new ArrayList() {{ add(item); /*may be other code*/ }});

But it has some side effect (compiler needs make an additional class).

To begin of your question. By design, standard Java collection classes has no methods that modify collection and return modified object (like StringBuilder.append). So this initialization is quite clean:

List<Product> myList = new ArrayList();
myList.add(item);
rMap.put("productsList", myList);
Community
  • 1
  • 1
And390
  • 1,550
  • 2
  • 16
  • 22
  • I'm interested on this solution you've come up with so I have already coded it. However, the compiler raises a hint about assigning a final modifier to my "item" object, if it is added, it does work otherwise it does not. . . why ? Is there a reason why that modifier must be used? –  Oct 13 '14 at 00:59
  • 1
    @rickHdz Yes, i forgot about it. It needs final modifier on "item" and other local method variables. Because code inside braces is anonymous class code. It is a Java restriction, anonymous class has access to final local variables and outer class members. Generally, it's a little more exotic method, but sometimes it can help to make code clearer. – And390 Oct 13 '14 at 21:09