首页 > 解决方案 > 使用流对其他对象应用更改

问题描述

我正在通过尝试不同的示例来了解 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

// 带终端操作

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

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

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

标签: javajava-stream

解决方案


我认为值得注意的是,您未填写的主要原因HashMap是因为您的代码已放入lambda 表达式的主体中。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)


推荐阅读