List forEach基础操作

介绍

forEach()方法是Stream接口的一部分,用于执行由定义的指定操作Consumer

Consumer接口表示需要一个参数作为输入的任何操作,并且没有输出。这种行为是可以接受的,因为该forEach() 方法用于通过副作用而不是显式的返回类型来更改程序的状态。

因此,最佳的目标候选对象Consumers是lambda函数和方法参考。值得注意的是,它forEach()可以在任何一个 上使用Collection

List中的forEach()

forEach()方法是一个终端操作,这意味着在我们调用此方法后,该流及其所有集成转换将被实现。也就是说,它们将“获得实质”,而不是被流化。

让我们生成一个小列表:

List list = new ArrayList();
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 map = new HashMap();
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转换MapSetvia 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 employees = new HashSet();

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 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 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(),然后覆盖的方法的例子上ListMapSet

你可能感兴趣的:(list,数据结构)