1

I have a container that tracks Hosts, Files, and parts of each file:

private static Map<String, Map<String, ArrayList<FileShard>>> globalFileShardMap = new HashMap<String, Map<String, ArrayList<FileShard>>>();

I want to put a new entry into this, and am doing so like:

 // filename and shard are known
 ArrayList<FileShard> initShard = new ArrayList<FileShard>();
 initShard.add(shard);

 Map<String, ArrayList<FileShard>> initMap = new HashMap<String, ArrayList<FileShard>>();
 initMap.put(filename,initShard);

 globalFileShardMap.put(Node.getLocal().getHostname(), initMap);

Is there a way to condense this to a single line, and pass in the new inner Map as a parameter to globalFileShardMap.put?

MrDuk
  • 16,578
  • 18
  • 74
  • 133

2 Answers2

1

In-line transformation would be -

globalFileShardMap.put(Node.getLocal().getHostname(), new HashMap<String, ArrayList<FileShard>>(){{
     put(filename, new ArrayList<FileShard>(){{add(shard);}});
}});
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
  • I'm not terribly well versed in java - what do `{{` and `}}` do? – MrDuk Nov 08 '15 at 05:24
  • 1
    This creates anonymous inner class with an instance initializer (also known as "double brace initialization") – Subhrajyoti Majumder Nov 08 '15 at 05:25
  • I suggest avoiding the extra class by using `Arrays.asList` for the list. After checking out the question again, you could actually just pass shards to the constructor of `ArrayList`. Overall you could avoid the extra classes by using the current class's initializer, rather than subclassing map and list. More on why you should try and avoid "double brance initialization" [here](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization) – Vince Nov 08 '15 at 05:48
  • Arrays.asList returns fixed-size list. Here in this case `List` with single element did not make much sense to me. Where `ArrayList` is much more flexible. – Subhrajyoti Majumder Nov 08 '15 at 06:02
1

Here is a way of doing it in one line without creating any anonymous classes.

globalFileShardMap.put(Node.getLocal().getHostname(), 
    new HashMap<>(Collections.singletonMap(filename, 
    new ArrayList<>(Collections.singletonList(shard)))));

This requires Java 7 for the diamond <>.

If you don't actually need a HashMap and an ArrayList (i.e. any old Map and List will do) you can just get rid of new HashMap<> and new ArrayList<>.

Paul Boddington
  • 37,127
  • 10
  • 65
  • 116