Hey 🙂 This is my first post and my first approach at streams! I am trying to learn it by myself, but since its a new style of programming Im having a tough time 😀
So here’s my problem:
In the following Method I have a Map of <Long, Ingredient> as parameter.
(Ingredient has the String Attribute "name".)
I want to return an inverted Map of <String, Long>.
(The string being the Attribute "name" of the class Ingredient.)
Here is my solution using a for-loop (which worked)
public static Map<String, Long> focusOnNameAndInvert(Map<Long, Ingredient> articles) {
ArrayList<String> nameList = new ArrayList<>(articles.values().stream().map(Ingredient::getName).collect(Collectors.toList()));
ArrayList<Long> keyList = new ArrayList<>(articles.keySet());
Map<String, Long> nameAndInvertedMap = new HashMap<>();
for (int i = 0; i<nameList.size(); i++){
nameAndInvertedMap.put(nameList.get(i), keyList.get(i));
}
return nameAndInvertedMap;
}
Here is my approach on using streams (which I need help with)
The "<>" on the right side of initializing the HashMap is red underlined and says "Cannot infer arguments" (Using IntelliJ)
public static Map<String, Long> focusOnNameAndInvert(Map<Long, Ingredient> articles) {
Map<String, Long> nameAndInvertedMap = new HashMap<>(
articles.values().stream().map(Ingredient::getName),
articles.keySet().stream().map(articles::get));
return nameAndInvertedMap;
}
Thank you for all input, tips, critique and especially for your time!
Wishing you all a nice day 🙂
Stevan
>Solution :
Your method is not actually doing what you hoped. As you can see from the compiler error, there is no HashMap constructor which accepts a List of keys and a List of values. Besides, even if it did, you’re streaming the given Map (twice), then trying to swap the keys and the values in different streams and finally not even collecting the values of your streams. Streams are pipelines of operations lazily evaluated, if you do not add a terminal operation they are not even executed.
Here there is an official Oracle’s tutorial which sums up quite good the concept of streams and how they work:
https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#laziness
You can write what your method by streaming the entries of the given map and then collect them with the collect(Collectors.toMap()) terminal operation where each Ingredient‘s name is mapped as the key while the long keys as their value:
public static Map<String, Long> focusOnNameAndInvert(Map<Long, Ingredient> articles) {
return articles.entrySet().stream()
.collect(Collectors.toMap(entry -> entry.getValue().getName(), entry -> entry.getKey()));
}