Java8 Stream 的最佳实践

java8stream提供了对于集合类的流失处理,其具有以下特点:

Lazy Evaluation(长度可以无限)

只能使用一次

内部迭代

Lazy Evaluation类似函数式中的LazyList,只有在需要时才去求值。减少了内存消耗,Java中可以用Iterator模拟。只有在进行终端操作时,stream才会执行。但是这个延迟计算不能保证流中的某个值单独延迟,需要时单独分配资源。

内部迭代的意思是我们告诉程序要实现的功能,迭代由程序自己控制。如filter时,我们只提供Predicate,而不是自己写for循环,至于程序自己是如何实现过滤数据的,我们并不关心。可能随着stream类库的迭代,实现效率会逐步提升。PS:新版本的Java类库String终于可以直接拼串了 😂,而且性能很好。

使用Stream的原则:

可读性、bugfree、短

// 读入数据,笔试用
Scanner sc = new Scanner(System.in);
String ss = sc.nextLine();
int[] nums = Arrays.stream(ss.split("\\s")).mapToInt(Integer::valueOf).toArray();

// flatMap只使用一次
// 这个例子来自于On Java 8
// 字符串打散,注意不要打散成char
// 常见的模式(方法返回流)
public static Stream stream(String filePath) throws Exception {
    return Files.lines(Paths.get(filePath))
    .skip(1) // First (comment) line
    .flatMap(line ->
    Pattern.compile("\\W+").splitAsStream(line));
}

// 一对多关系,保存到数据库,命令式编程需要两层for循环
List roles = users.stream().flatMap(user -> user.getRoles().stream()).collect(toList());
saveBatch(roles);

// 生成随机数组
int[] nums = new Random().ints(0, 100).limit(10).toArray();

// optional流的处理
stream1.filter(Optional::isPresent).map(Optional::get).collect(toList());
stream2.map(opt -> opt.orElse(defaultValue)).collect(toList());

// forEach
stream3.forEach(System.out::println);

// 生成Map,这种最终操作我后面会发文章详细分析Collectors工具类
Map idToUserMap = users.stream().collect(toMap(User::getId, it -> it));

// 获取角色到用户的映射(一对多)
HashMultiMap roleIdToUsersMap = userVos.stream().collect(toMultiMap(UserVo::getRoleId, UserVo::getUser, HashMultimap::create));

// 分组
Map> usersByLevelMap = users.collect(groupingBy(User::getLevel));

// 字符串拼接
subscriptions.stream().map(Object::toString).collect(joining(",", "(", ")"));

// 参数校验
boolean validated = request.getResources().stream().allMatch(authorities::contains);
if (!validated) throw ...

IntStream::sum, max, min, average, count...

// 教学意义
质数流,完全数流...

比如你需要一个字符串匹配算法,需要自己实现一些特殊功能,先写出暴力匹配,之后再优化。

比如我想获取一个前十名的排行榜,我不必在自己编写优先队列,或者使用其他类库。当需要优化时,再考虑优化。

// 至少我们可以确定:使用stream的内部迭代中时间复杂度最多是nlogn。
Comparator compScore = Comparator.comparingDouble(User::getScore).reversed();
List top10 = users.stream().sorted(compScore).limit(10).collect(toList());

毕竟Java不是纯函数式的语言,还要前向兼容,所以只能部分利用函数式的思想。以下这些做法在开发中应该避免。

Original: https://www.cnblogs.com/dahua-dijkstra/p/16249879.html
Author: 大华dijkstra
Title: Java8 Stream 的最佳实践

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/713665/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球