3

I have a HashMap that stores a custom Object and maps it to a certain ArrayList in a class. My class communicates with another class (think MVC style) and it passes a copy of that hashmap. So, in my "model", I would have:

public Map<AbstractArtistry, ArrayList<AbstractCommand>> getHashMap() { return new LinkedHashMap<AbstractArtistry, ArrayList<AbstractCommand>>(this.hashmap); } 

However, my "controller", when it gets that, can still edit the AbstractArtistries inside of the model's this.hashmap. To avoid this, do I have to create a new instance of an Abstract Artistry over and over, or is there a cleaner way to do this? Meaning, would I have to loop over model.hashmap.keySet(), create a new instance of every artistry, insert it into a new hashmap (and do the same for all the values), and then return that new hashmap? Or is there a cleaner way?

5
  • 3
    Are you saying your map's key type is mutable? That's asking for trouble... Commented Apr 3, 2018 at 1:31
  • @shmosel Too late to change the design now, but just for educational purposes, why? Commented Apr 3, 2018 at 1:33
  • See stackoverflow.com/questions/7842049/… Commented Apr 3, 2018 at 1:36
  • Wouldn't you also need to copy the lists? What about AbstractCommand? Commented Apr 3, 2018 at 1:39
  • Yeah, I would.. Damn, you are right, this design was bad. Commented Apr 3, 2018 at 1:44

1 Answer 1

1

You can use streams to copy the map and replace the keys with defensive copies:

this.hashmap.entrySet() .stream() .collect(Collectors.toMap(e -> createCopy(e.getKey()), Map.Entry::getValue)) 

If you need to copy the values as well, you can run them through a similar function:

ArrayList<AbstractCommand> copyList(ArrayList<AbstractCommand> list) { return list.stream() .map(c -> copyCommand(c)) .collect(Collectors.toCollection(ArrayList::new)); } 
Sign up to request clarification or add additional context in comments.

10 Comments

How do they all fit together so I could return a new hashmap?
@JohnLexus All of what? That snippet returns a map.
I am saying how do I combine the first and second snippets? The first snippet looks like it return a map with just keys and no values, while the second return a (map?) of the values, not with my AbstractArtistries as keys. Or am I reading this wrong (sorry new to Java)?
I've updated the second snippet to return ArrayList. But ideally you should be sticking to the List interface.
That's right. You would also have to create copyCommand(). Unless you don't need a deep copy, in which case you can just return new ArrayList<>(list).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.