nanpakal
nanpakal

Reputation: 1021

How peek and map works in streams

I am trying to understand how different peek and map in java 8 streams.I have tried the following

public static void main(String[] args) {
        List<String> arr = new  ArrayList<String>();
        arr.add("A");
        arr.add("B");

        List<String> a = arr.stream().peek(t->t.toLowerCase()).collect(Collectors.toList());
        System.out.println(a);
    }

The above code is not changing the alphabets to lower case.But when i try the following

  public static void main(String[] args) {
        List<String> arr = new  ArrayList<String>();
        arr.add("A");
        arr.add("B");

        List<String> a = arr.stream().map(t->t.toLowerCase()).collect(Collectors.toList());
        System.out.println(a);
    }

The alphabets are converted to smaller case.My doubt here is if i use both map and peek like below

 public static void main(String[] args) {
        List<String> arr = new  ArrayList<String>();
        arr.add("A");
        arr.add("B");

        List<String> a = arr.stream().map(t->t.toLowerCase()).peek(t->toUpper()).collect(Collectors.toList());
        System.out.println(a);
    }

    public static  Function<String, String> toUpper(){
        return t->{
            return t.toUpperCase();
        };
    }

The map method converts A,B to lower and Peek does nothing.So if there is any calculation involved while streaming cant i make use of peek?Can someone explain

MOdified code

static  List<Employee> e = new  ArrayList<>();
public static void main(String[] args) {
    List<String> arr = new  ArrayList<String>();
    arr.add("Pavan");
    arr.add("Kumar");


    System.out.println("Size of emp"+e.size());
    List<String> a = arr.stream().map(t->t.toLowerCase()).peek(t->populateEmp()).collect(Collectors.toList());
    System.out.println("Size of emp"+e.size());
    System.out.println(a);
}

public static  Function<String, Employee> populateEmp(){
    Employee ee = new  Employee();
    return t->{
        System.out.println(t);
        ee.setName(t);
        e.add(ee);
        return ee;
    };
}

This is still not adding the Emp to list

Upvotes: 3

Views: 8533

Answers (1)

Beri
Beri

Reputation: 11610

Peek expects a Consumer, so if you are using toLowerCase() you are creating a new String, which is put into void. You may modify this object inside of a consumer, but String is immutable, so peek has no effect.

When you use map, then you expect to pass a Function or UnaryOperator, that receives single object and returns single object. So new String that is lower-cased is returned.

In both cases, objects are not cloned. So you could modify an object that is mutable inside of a peek function, but that is just the wrong way to do it:) Try passing a Date, then you can set hours inside a peek function because it's mutable.

In short:

  • use map to transform model to another model
  • use peek, to do something that consumes this object, but does not modify it (send a notification, print model, etc)

UPDATE:

public static Function<String, Employee> populateEmp(){
        Employee ee = new  Employee();
        System.out.print("I am executed");
        return t->{
            System.out.print("I am not");
            return null;
        };
    }

Try with this code. In your update, you are passing a consumer, that ignores passed argument, and you execute populateEmp() method, which returns a function, that adds to a map transformed object. But you NEVER execute this function, tus-> list is empty:)

In non-lambda word it looks like this:

for(String value: arr){
     populateEmp(); // execute method but you do nothing with this Function.
}

So replace your peek with this:

.peek(t->populateEmp().apply(t))

Upvotes: 8

Related Questions