使用流将更改应用于其他对象

时间:2019-03-29 09:53:08

标签: java java-stream

我通过尝试不同的示例来学习Java 8流API。我试图使用流.map()方法从ArrayList形成HashMap。 (我知道.groupingBy方法,但是我试图理解流操作的底​​层逻辑。)当我运行代码而不调用forEach()方法(或任何终端操作)时,更改未应用于我的HashMap <>和它保持为空。但是调用终端操作可以保护我所做的更改。我当时认为终端操作仅用于返回非流值和结束流。谁能解释为什么会这样?

主类{

    public static void main(String[] args) {

    // Create a list of arrays then form a HasMap based on entries of list
    List<String[]> list3 = new ArrayList<String[]>();
    String[] entry1 = {"a","b","c"};
    String[] entry2 = {"d","e","f"};
    String[] entry3 = {"g","h","i"};
    list3.add(entry1);
    list3.add(entry2);
    list3.add(entry3);

    // hashmap
    HashMap<String, String[]> map1 = new HashMap<String, String[]>();

    // streamize the list to form hashmap
    list3.stream()
         .map(entry ->  {
                            String key = entry[0];
                            String[] value = {entry[1],entry[2]};
                            map1.put(key, value);
                            // must return a String[]
                            return entry;
                        })
         // CHANGES ARE ONLY APPLIED WHEN TERMINAL OPERATIONS CALLED ???
         .forEach(entry -> {});

    // print elements
    for (Map.Entry<String,String[]> entry : map1.entrySet()) {
        System.out.println(entry);
    }

}

//没有终端操作

                              //Empty

//使用终端op

a = [Ljava.lang.String; @ 7921b0a2

d = [Ljava.lang.String; @ 174d20a

g = [Ljava.lang.String; @ 66d2e7d9

1 个答案:

答案 0 :(得分:0)

我认为值得指出的是,您的HashMap未填充的主要原因是因为您的代码已放入lambda expression的正文中。 Lambda类似于匿名内部类:

jbutton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent event) {
        doSomething();
    }
});

如果定义这样的内容,方法doSomething()不会立即执行,相反,addActionListener方法会将ActionListener实例作为实例变量存储在某个地方,因此可以使用它后来。这意味着您实际上仅定义了一个方法,但尚未调用它。

map接口的Stream方法(无论您使用的是哪种实现)都接受Function的实例,它只是一个定义。它仅将此Function存储在某个位置,但不执行lambda表达式的主体。

Stream实现很懒。在绝对没有必要之前,它的作用是不执行任何操作。只有当呼叫者实际上需要某些结果(即收集)时,这种情况才会出现。

调用终端操作后,然后 Stream实现实际上将应用所有必要的转换和过滤步骤,并返回某种形式的结果。

相关


注意:流操作不应有副作用。这意味着您应该避免做类似map1.put(key, value)的事情。