12

How can I convert this:

return this.subjects.entrySet()
            .stream()
            .collect(Collectors.toMap(e -> getArtistryCopy(e.getKey()), Map.Entry::getValue));

To return a LinkedHashMap instead of a map?

If you need to know, this.subjects is a LinkedHashMap<AbstractArtistries, ArrayList<AbstractCommand>>. AbstractArtistry and command are two custom objects I made. I need the order to be maintained.

getArtistryCopy() returns a copy of an AbstractArtistry (which is the key).

John Lexus
  • 3,576
  • 3
  • 15
  • 33

1 Answers1

17

You can use the overload of Collectors.toMap that accepts a Supplier for the Map. It also takes a merge function that how to resolve collisions between duplicate keys.

return this.subjects.entrySet()
        .stream()
        .collect(Collectors.toMap(e -> getArtistryCopy(e.getKey()), 
                                  Map.Entry::getValue,
                                  (val1, val2) -> yourMergeResultHere,
                                  LinkedHashMap::new));
rgettman
  • 176,041
  • 30
  • 275
  • 357
  • 4
    A simple merge function is just `(a, b) -> b`, which overwrites the previous value, as if by `Map.put`. Since the OP is mapping the keys, though, I think they should probably think about what they actually want to do with a merge. (I think `(a, b) -> b)` might be the behavior people would expect by default, [when actually `toMap(Function, Function)` throws if it encounters a duplicate key](https://ideone.com/DP6e8E).) – Radiodef Apr 04 '18 at 00:57
  • 1
    @Radiodef That's reasonable. For my answer, the merge function was just an afterthought, because the only overload of `toMap` that took a `Supplier` was one that also took a merge function. – rgettman Apr 04 '18 at 00:59