0

I have a map and I am iterating through it and modifying the values of the map using a for loop. I wanted to know if there is a way I can do it using Java 8 streams.

Here's my code:

Map<String,MyObject> myMap = getResultMap();
for (Map.Entry<String, MyObject> entry : myMap.entrySet()) {
    entry.getValue.setName(getName());
    entry.getValue.setId(getId());
    entry.getValue.setDept(getDept());
    entry.getValue.isValid(isValid();
    entry.getValue.setPipeLine(getPipeLine());
}

Basically, I wanted to stream the map values and set the values and get it as a new map.

smac89
  • 39,374
  • 15
  • 132
  • 179
Jeeppp
  • 1,553
  • 3
  • 17
  • 39
  • 2
    "*Modify a map using stream*" - Don't do/try this. You cannot modify streams. Streams are designed to be functional: if you have used them, they are gone. Furthermore, [side-effects in streams are discouraged (See paragraph "*side-effects*")](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html), so you should not try to modify the stream's underlying data structure. – Turing85 Aug 21 '19 at 20:57
  • You can create new map with updated entries as a result of your stream. But I;m not sure that it will be more readable then for-loop. – Ivan Aug 21 '19 at 21:00
  • You can technically do this, but shouldn't alter the collection you are streaming through as this can cause unexpected behaviors. You can use stream().map().collect() to build a new map. – purring pigeon Aug 21 '19 at 21:01
  • 1
    The question is ambiguous. The code you show doesn't create a new map; it modifies the values of the old map. Do you want to alter the `MyObject` instances or not? Do you want to modify the map so that new objects are associated with its keys? Do you want a new map with old values that have been modified? Or a new map with new values? – erickson Aug 21 '19 at 22:00

1 Answers1

0

You can just get a new Stream or a new Map as a result of stream operations but Stream cannot mutate data (but you can create a lambda that do anything you want). For instance, using your code example:

Map<String, MyObject> myMap = getResultMap();
Map<String, MyObject> newMap = myMap.entrySet().stream()
            .collect(Collectors.toMap(Map.Entry::getKey, entry ->
            {
                entry.getValue().setName(getName());
                entry.getValue().setId(getId());
                entry.getValue().setDept(getDept());
                entry.getValue().setValid(isValid());
                entry.getValue().setPipeLine(getPipeLine());
                return entry.getValue();
            }
            ));

But do not update shared mutable variables inside Stream! It can produce many problems.

It would be better to create new instances of MyObject class instead of modifying myMap:

Map<String, MyObject> newMap = myMap.entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry ->
                        {
                            MyObject myObject = new MyObject();
                            myObject.setName(getName());
                            myObject.setId(getId());
                            myObject.setDept(getDept());
                            myObject.setValid(isValid();
                            myObject.setPipeLine(getPipeLine());
                            return myObject;
                        }
                ));
Ihor Patsian
  • 1,288
  • 2
  • 15
  • 25