8个必须知道的Stream API使用方法
作为一名java开发工程师,数组和集合在我的代码中随处可见。我经常使用集合或数组来处理数据,如过滤和对象转换。我相信大家对数组的数据处理已经非常熟悉了。
但是当数据处理比较复杂的时候,我们的代码就会非常长,难以理解。这个时候,我通常会把代码拆成方法,并给出有意义的方法名称,这样可以解决一部分问题。然而,在java8之后,官方有了一个更有效、更方便的解决方案:Stream API。
Stream是Java8中处理集合的关键抽象。它可以指定你要对集合进行的操作,并且可以进行非常复杂的操作,如搜索、过滤和映射数据。
使用Stream API对集合数据进行操作,类似于使用SQL进行数据库查询。也可以使用Stream API来执行并行操作。简而言之,Stream API提供了一种高效且易于使用的数据处理方式。
Stream具有以下特点:
- 它不是一个数据结构,不保存数据。
- 懒惰评估,在流的中间处理过程中,只记录操作,不立即执行,直到执行终止操作才会进行实际计算。
今天我将分享一些工作中常用的、非常有用的API。
列表到地图
在我们的工作中,经常会遇到列表或数组被转换为地图的场景。Collectors.toMap可以将List转换成Map。
代码如下:
public class ListToMap {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User(1, "Bob", 10));
users.add(new User(2, "David", 22));
users.add(new User(3, "Lance", 28));
/**
* list to map
* (k1, k2) ->k1 indicates that if there is a duplicate key, the first key is retained and the second key is discarded
*/
Map<String, User> userMap = users.stream().collect(Collectors.toMap(User::getUsername, user -> user, (k1, k2) -> k1));
userMap.values().forEach(user->System.out.println(user.getUsername()));
}
}
同样,还有Collectors.toList(),Collectors.toSet(),这意味着将相应的流转换为一个List或Set。
使用groupingBy进行分组
分组在执行聚合数据操作时经常使用,比如按国籍对用户进行分组。说到分组,相信大家都会想到SQL的group by。在Java8之前,我们可能需要这样做:
List<User> users = Arrays.asList(new User(1, "Bob", 10,"America"),new User(2, "Daivd", 22,"America"),new User(3, "Lance", 28,"England"));
Map<String, List<User>> result = new HashMap<>();
for (User user : users) {
String country = user.getCountry();
List<User> userList = result.get(country);
if (userList == null) {
userList = new ArrayList<>();
result.put(country, userList);
}
userList.add(user);
}
如果你使用groupingBy,只需要一行代码就可以了:
Map<String, List<User>> result=users.stream.collect(Collectors.groupingBy(User::getCountry));
使用限制和跳过的内存分页
有时我们在内存中聚合数据后,数据量可能太大,无法一次性将数据返回到前端。这个时候,就需要分页。Stream api提供了limit和skip来完美支持它。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
List<Integer> pageableList=list.stream.skip(3).limit(5).collect(Collectors.toList());
使用filter()来过滤元素
从集合中过滤掉不符合标准的元素。
//Get all students older than 18
List<Student> studentNames = students.stream().filter(student->student.getAge()>18).collect(Collectors.toList());
使用 sorted+Comparator 进行排序
在集合操作中,排序绝对是一个高频的操作。虽然有现成的集合工具进行排序,但Stream api整合了这一功能,形成了自己的功能生态,进一步提高了api的便利性。
List<User> users = Arrays.asList(new User(1, "Bob", 10,"America"),
new User(2, "Daivd", 22,"America"),new User(3, "Lance", 28,"England"));
List<User> sortedUsers = users.stream().sorted(Comparator.comparing(User::getAge))
.collect(Collectors.toList());
使用reduce进行聚合评估
Stream api也有一个非常有用的方法reduce()。使用reduce可以聚合集合中的所有元素,得到一个单一的值。最典型的情况是数组的总和。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
Optional<Integer> sum=list.stream().reduce((a,b)->a+b);
当然,你也可以使用reduce来执行其他的聚合操作,比如寻找一个数组的平均值。
使用map来转换类型
map操作是对流中的元素进行重新处理,形成一个新的流。这在开发中很有用,例如,我有一个用户的集合,但我只需要使用用户的名字和年龄,使用map方法就可以做到这点。
List<User> users = Arrays.asList(new User(1, "Bob", 10,"America"),new User(2, "Daivd", 22,"America"),new User(3, "Lance", 28,"England"));
List<UserVo> userVoList = users.stream().map(user->{
UserVo userVo = new UserVo();
userVo.setUsername(user.getUsername());
userVo.setAge(user.getAge());
return userVo;
}).collect(Collectors.toList());
flatMap
flatMap操作可以将同一类型的多个流合并为一个流。
List<User> users = Arrays.asList(new User(1, "Bob", 10,"America"),new User(2, "Daivd", 22,"America"),new User(3, "Lance", 28,"England"));
List<User> userList = Arrays.asList(new User(4,"James",23,"America"));
List<List<User>> list = Arrays.asList(users,userList);
List<User> result = list.stream().flatMap(s->s.stream()).collect(Collectors.toList());
最后
流API以声明的方式处理集合数据,可以极大地提高Java程序员的工作效率,使我们能够写出高效、干净、简洁的代码。
我希望每个人都能掌握Stream Api,写出优雅的代码。谢谢你的阅读!