何时使用map和forEach

时间:2019-08-14 19:10:41

标签: java java-stream

我正在学习Java 8,遇到了一种情况。我必须在哪里遍历字符串列表,然后将它们转换为upperCase。可能的解决方案是流式处理列表。在Intellij的许多建议中,以下两项似乎很有用。

list.stream()
.map(String::toUpperCase)

list.stream().
forEach(p -> p.toUpperCase())

我对要使用哪个建议以及所有建议的用例感到困惑。我可以就所有建议使用哪种方法以及如何理解获得帮助吗?

2 个答案:

答案 0 :(得分:6)

除非您以terminal operation结束管道,例如Stream.map(),否则

forEach()将永远不会运行。但是在toUpperCase()中调用forEach()也不会做任何事情,因为字符串是不可变的。 String.toUpperCase()不会更改字符串;它会返回一个新的。

如果只想就地更新列表,则可以使用

list.replaceAll(String::toUpperCase);

实际上用传递的函数的结果替换每个元素。

如果要将结果显示在新列表中,请使用map()代码段和收集器:

List<String> list2 = list.stream()
        .map(String::toUpperCase)
        .collect(Collectors.toList());

答案 1 :(得分:1)

P_ID P_Name Text 0 1 J J SMITH \n[SPORTS FAN]\nHere 1 2 J J SMITH \n[SPORTS FAN]\nHere is 2 3 J J SMITH \n[BASEBALL]\nTHIS SOUNDS right 3 5 J J SMITH \n[BASEBALL]\nRARELY IS a fanatic 4 8 MARY HYDER \n[SPORTS FAN]\nReally Big big fan 5 9 MARY HYDER \n[SPORTS FAN]\nRARELY IS a fan 6 11 MARY HYDER \n[BASEBALL]\nRARELY IS a fan 是一种终端操作,可通过副作用而有所作为。 forEach是一种非终端操作,可以将一个元素直接映射到另一个元素。例如,这是map的规范用法:

forEach

这将在流的每个元素上调用等效于stream.forEach(System.out::println); 的元素。但是,此后流将关闭,此后将无法在System.out.println(element);上执行任何操作。另一方面,stream可以这样使用:

map

在这种情况下,streamOfObjects.map(Object::toString).collect(Collectors.toList()); 中的每个对象都映射到通过调用streamOfObjects创建的字符串。然后,使用收集器将toString产生的字符串流收集到一个列表中。

在任何情况下,如@shmosel所建议,建议在此用例中使用map

关于如何理解自动完成功能提供的建议,我会强烈建议阅读相关类的JavaDocs。