随着Java 8的发布,Lambda表达式和Stream API成为了Java应用程序开发的新标准,其中Stream API是所有新功能中最引人注目的。Stream API提供了一种流式编程模型,这种模型便于处理数据集合,尤其是Big Data。在Stream API中,.stream().map是最常见的用法之一,这篇文章将详细介绍.map的用法及相关问题。
一、streammap方法
在Java 8中,Stream API是Java API提供的一种新的API,用于处理集合类数据,它不同于常见的操作List,而是允许您从数据流中过滤,映射和归纳数据。.stream()方法将一个集合类转换为一个数据流。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream();
使用map方法对流中的元素进行修改:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
List<String> filtered = strings.stream().map(String::toUpperCase).collect(Collectors.toList());
filtered.forEach(System.out::println);
在上面的示例中,我们使用.map()方法将字符串列表中的所有字符串转换为大写字母,并使用collect()方法将结果保存到另一个列表中。
二、streammap的并发问题
在处理大型数据集时,.map()方法可能会遇到并发问题。请考虑以下示例:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
List<String> filtered = strings.parallelStream().filter(string -> !string.isEmpty()).map(String::toUpperCase).collect(Collectors.toList());
filtered.forEach(System.out::println);
在这个示例中,我们使用parallelStream()方法实现并发处理,但是.map()方法中的代码是不等速的,这会导致输出结果的顺序与输入顺序不一致。接下来我们将进行进一步探讨。
三、streammap两个字段值
有时候我们需要同时修改流中的两个字段的值,例如:
employeeList.stream().map(e -> {
e.setSalary(e.getSalary() * 1.10);
e.setDoj(LocalDate.now());
return e;
}).collect(Collectors.toList());
在上述代码中,我们使用.map()方法将Employee对象列表中每个Employee对象的薪资增加了10%并将Date of Joining设置为今天。在这种情况下,.map()方法中使用的Lambda表达式需要一个返回Employee对象的语句。
四、streammap是什么意思
在Java 8中,.map()方法返回一个新的流对象,其中每个元素都根据指定的函数进行转换。.map()方法的使用非常灵活,它的参数可以是Lambda表达式或方法引用。
五、streammap中顺序错乱
在处理大型数据集时,.map()方法可能会遇到顺序问题。.map()方法中使用的Lambda表达式不等速时,它们的执行顺序将不同于输入顺序。下面是一段示例代码:
List<String> strings = Arrays.asList("one", "two", "three", "four", "five");
strings.parallelStream().map(item -> {
System.out.println(Thread.currentThread().getName() + " processing " + item);
return item.toUpperCase();
}).forEach(item -> System.out.println(item));
在这个示例中,使用了parallelStream()方法实现并发处理。在输出结果中,输入项的顺序被打乱了,因为在每个item的处理中都有一个随机的延迟时间。这种情况下,.forEach()方法并不会等待.map()处理完成,所以输出的顺序将是随机的。
六、streammap执行方法
在前面的示例中,我们使用.collect()方法将结果保存到另一个列表中,.collect()方法是一个收集器,可将数据流中的元素转换为包含指定结果类型的集合。
.toArray()方法是一个重载的.collect()方法,可以将数据转换为数组。在以下示例中,我们将结果保存到一个数组中:
String[] array = strings.stream().toArray(String[]::new);
这个数组中的顺序与原始列表的顺序相同。
七、streammap转成list
.toList()方法是Java 16中新增的方法,可将数据流转换为列表。在以下示例中,我们将结果保存到一个列表中:
List<String> list = strings.stream().map(String::toUpperCase).toList();
在这两种情况下,结果的顺序保持不变。
八、streammap的用法
在使用.map()方法时,Lambda表达式需要指定每个元素如何转换为另一个形式。下面是另一个示例,它将整数列表转换为字符串列表:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> digits = numbers.stream().map(n -> String.valueOf(n)).collect(Collectors.toList());
在这个示例中,我们对每个整数执行了一个转换,并将新的字符串值添加到另一个列表中。
九、streammap中取出list的值且过滤空
在以下示例中,我们将Employee对象列表中每个Employee的firstName和lastName组合成一个字符串并将结果添加到另一个列表中:
List<Employee> employeeList = Arrays.asList(
new Employee("Tom", "Scott", LocalDdate.of(2000, 1, 1), 40000),
new Employee("Mary", "Johnson", LocalDate.of(2001, 1, 1), 50000));
List<String> allNames = employeeList.stream()
.map(employee -> employee.getFirstName() + " " + employee.getLastName()) // mapping employee to a concatenated string to test strings
.filter(name -> !name.isEmpty())
.collect(Collectors.toList());
在这个示例中,我们使用.map()方法将每个Employee对象的firstName和lastName组合,然后使用.filter()方法过滤空字符串。最后,我们使用.collect()方法将过滤后的结果保存到另一个列表中。