List forEach基础操作
介绍
该forEach()
方法是Stream
接口的一部分,用于执行由定义的指定操作Consumer
。
的Consumer
接口表示需要一个参数作为输入的任何操作,并且没有输出。这种行为是可以接受的,因为该forEach()
方法用于通过副作用而不是显式的返回类型来更改程序的状态。
因此,最佳的目标候选对象Consumers
是lambda函数和方法参考。值得注意的是,它forEach()
可以在任何一个 上使用Collection
。
List中的forEach()
该forEach()
方法是一个终端操作,这意味着在我们调用此方法后,该流及其所有集成转换将被实现。也就是说,它们将“获得实质”,而不是被流化。
让我们生成一个小列表:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
传统上,您可以编写一个for-each循环来遍历它:
for (Integer element : list) {
System.out.print(element + " ");
}
这将打印:
1 2 3
另外,我们可以在forEach()
上使用方法Stream
:
list.stream().forEach((k) -> {
System.out.print(k + " ");
});
这还会输出:
1 2 3
我们可以通过方法参考来简化此操作:
list.stream().forEach(System.out::println);
Map上的forEach()
forEach()
如果我们要避免链接许多流方法,则该方法非常有用。让我们生成包含一些电影及其各自的IMDB分数的地图:
Map<String, Double> map = new HashMap<String, Double>();
map.put("Forrest Gump", 8.8);
map.put("The Matrix", 8.7);
map.put("The Hunt", 8.3);
map.put("Monty Python's Life of Brian", 8.1);
map.put("Who's Singin' Over There?", 8.9);
现在,让我们打印出得分高于的每部电影的值8.4
:
map.entrySet()
.stream()
.filter(entry -> entry.getValue() > 8.4)
.forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));
结果是:
Forrest Gump: 8.8
The Matrix: 8.7
Who's Singin' Over There?: 8.9
在这里,我们将a转换Map
为Set
via entrySet()
,进行流处理,并根据得分进行过滤,最后通过a将其打印出来forEach()
。不必将其基于的返回filter()
,我们可以将逻辑基于副作用,并跳过该filter()
方法:
map.entrySet()
.stream()
.forEach(entry -> {
if (entry.getValue() > 8.4) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
);
结果是:
Forrest Gump: 8.8
The Matrix: 8.7
Who's Singin' Over There?: 8.9
最后,我们可以从开头开始就省略stream()
和filter()
方法forEach()
:
map.forEach((k, v) -> {
if (v > 8.4) {
System.out.println(k + ": " + v);
}
});
结果是:
Forrest Gump: 8.8
The Matrix: 8.7
Who's Singin' Over There?: 8.9
Set上的forEach()
让我们看一下如何在更具体的上下文中使用该forEach
方法Set
。首先,让我们定义一个代表Employee
公司的类:
public class Employee {
private String name;
private double workedHours;
private double dedicationScore;
// Constructor, Getters and Setters
public void calculateDedication() {
dedicationScore = workedHours*1.5;
}
public void receiveReward() {
System.out.println(String
.format("%s just got a reward for being a dedicated worker!", name));
}
}
假设我们是经理,我们将挑选出一些加班的员工,并奖励他们辛勤的工作。首先,让我们做一个Set
:
Set<Employee> employees = new HashSet<Employee>();
employees.add(new Employee(“Vladimir”, 60));
employees.add(new Employee(“John”, 25));
employees.add(new Employee(“David”, 40));
employees.add(new Employee(“Darinka”, 60));
然后,让我们计算每个员工的奉献分数:
employees.stream().forEach(Employee::calculateDedication);
现在,每个员工都有一个奉献分数,让我们删除分数太低的员工:
Set<Employee> regular = employees.stream()
.filter(employee -> employee.getDedicationScore() <= 60)
.collect(Collectors.toSet());
employees.removeAll(regular);
最后,让我们感谢员工的辛勤工作:
employees.stream().forEach(employee -> employee.receiveReward());
为了清楚起见,让我们打印出幸运工人的姓名:
System.out.println(“Awarded employees:”);
employees.stream().map(employee -> employee.getName()).forEach(employee -> System.out.println(employee));
运行上面的代码后,我们得到以下输出:
Vladimir just got a reward for being a dedicated worker!
Darinka just got a reward for being a dedicated worker!
Awarded employees:
Vladimir
Darinka
副作用与返回值
每个命令的重点是从头到尾计算表达式。中间的一切都是副作用。在这种情况下,这意味着更改状态,流或变量而不返回任何值。
让我们看一下另一个列表上的区别:
List<Integer> targetList = Arrays.asList(1, -2, 3, -4, 5, 6, -7);
此方法基于的返回值ArrayList
:
long result1 = targetList
.stream()
.filter(integer -> integer > 0)
.count();
System.out.println("Result: " + result1);
结果是:
Result: 4
现在,我们将不再对程序的逻辑基于返回类型,而是forEach()
对流执行a并将结果添加到中AtomicInteger
(流同时运行):
AtomicInteger result2 = new AtomicInteger();
targetList.stream().forEach(integer -> {
if (integer > 0)
result2.addAndGet(1);
});
System.out.println("Result: " + result2);
结论
该forEach()
方法是一种非常实用的方法,可用于以功能性方法遍历Java中的集合。
在某些情况下,它们可以大大简化代码并提高清晰度和简洁性。在这篇文章中,我们已经讨论了使用的基本知识forEach()
,然后覆盖的方法的例子上List
,Map
和Set
。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!