窥视和地图如何在流中工作

时间:2016-07-13 07:16:06

标签: java java-stream

我试图了解java 8 stream中的peek和map的不同之处。我试过以下

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);
    }

上面的代码没有将字母改为小写。但是当我尝试以下

  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);
    }

字母表被转换为更小的情况。我怀疑这里是否同时使用地图和下面的方式

 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();
        };
    }

map方法将A,B转换为lower,Peek不执行任何操作。所以如果在流式传输时涉及到任何计算,我可以使用peek吗?有人可以解释吗

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;
    };
}

这仍然没有将Emp添加到列表

1 个答案:

答案 0 :(得分:5)

Peek期望一个 Consumer ,所以如果你使用toLowerCase(),你将创建一个新的String,它将被置于无效状态。您可以在使用者中修改此对象,但String是不可变的,因此peek无效。

当您使用地图时,您希望传递接收单个对象的FunctionUnaryOperator,并返回单个对象。所以返回了新的字符串,它是情人的。

在这两种情况下都不会克隆对象。所以你可以在一个peek函数中修改一个可变的对象,但这只是错误的方法:)尝试传递一个Date,然后你可以在一个peek函数中设置几个小时,因为它是可变的。

简而言之:

  • 使用map将模型转换为其他模型
  • 使用peek,做一些消耗这个对象的东西,但是不会修改它(发送通知,打印模型等)

更新:

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;
        };
    }

尝试使用此代码。在您的更新中,您将传递一个忽略传递参数的使用者,并执行populateEmp()方法,该方法返回一个函数,该函数将添加到地图转换对象中。但你从不执行此功能,tus-&gt;列表为空:)

在非lambda字中,它看起来像这样:

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

所以用这个代替你:

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