Java Stream API实战:List对象属性聚合计算(求和、最大、最小、平均值)
1. 项目概述与核心价值在日常的Java开发中尤其是处理业务数据报表、统计分析或是数据清洗时我们经常面对一个非常具体的场景手头有一个包含多个对象的List集合我们需要快速地对这些对象中的某个数值属性进行一系列聚合计算比如求和、求最大值、求最小值、计算平均值。想象一下你从数据库查询出了一批订单数据每个订单对象都有amount金额属性现在需要生成一份销售简报展示总销售额、最高单笔订单、最低单笔订单以及平均订单金额。如果手动写循环去累加、比较代码不仅冗长而且容易出错特别是当这类需求遍布代码各处时。这就是Stream API大显身手的地方。自从Java 8引入Stream以来它彻底改变了我们处理集合数据的方式。对于上面提到的聚合计算Stream提供了一套声明式、链式调用的解决方案能够用极其简洁、易读的一行或几行代码完成过去需要十多行循环才能搞定的事情。更重要的是它的内部优化如并行流能在处理大数据集时带来性能提升。今天我们就来彻底拆解如何利用Stream优雅地实现对一个List中对象某个属性的求和、最大、最小、平均值计算。无论你是正在准备面试被“Java八股文”中的Stream问题所困扰还是在实际开发中想寻找更高效的代码写法这篇内容都将为你提供可直接“抄作业”的详细方案和避坑指南。2. 核心思路与Stream基础构建在动手写代码之前我们得先搞清楚两个核心概念数据源和归约操作。我们的数据源是一个ListT其中T是我们自定义的对象类型。归约操作则是将一个流中的元素组合起来生成一个单一的值比如sum、max、min、average这正是我们需要的。2.1 定义数据模型与准备测试数据一切计算始于明确的数据结构。我们以一个简单的Product产品类为例它包含我们待计算的数值属性price价格和stock库存。import java.util.ArrayList; import java.util.List; public class Product { private String name; private double price; // 用于计算求和、最大、最小、平均值的属性 private int stock; // 另一个数值属性用于演示不同属性的计算 // 全参构造函数、Getter/Setter、toString方法省略实际开发中请使用Lombok或手动生成 public Product(String name, double price, int stock) { this.name name; this.price price; this.stock stock; } // ... 省略 getter 和 setter }接下来我们初始化一个ListProduct作为测试数据。真实场景中这个List可能来自数据库查询、文件读取或API响应。ListProduct products new ArrayList(); products.add(new Product(Laptop, 999.99, 10)); products.add(new Product(Mouse, 25.50, 50)); products.add(new Product(Keyboard, 75.00, 30)); products.add(new Product(Monitor, 299.99, 15)); products.add(new Product(USB Cable, 12.99, 100));这个列表包含了5个产品它们的price属性值各不相同非常适合演示各种聚合操作。2.2 Stream操作的核心三步曲使用Stream进行聚合计算通常遵循一个清晰的模式我把它称为“三步曲”获取流Stream 从数据源这里是products列表调用.stream()方法将其转换为一个流。如果想利用多核优势对于线程安全的数据源或只读操作可以考虑使用.parallelStream()。映射Map 这是关键一步。我们需要告诉Stream到底要对对象的哪个属性进行计算。通过.mapToDouble()、.mapToInt()或.mapToLong()方法并传入一个方法引用如Product::getPrice我们将一个StreamProduct映射为一个DoubleStream、IntStream或LongStream。这种特化流Primitive Stream专门用于处理基本数据类型避免了装箱/拆箱开销并且直接提供了我们需要的sum()、average()等方法。归约Reduce 在特化流上调用最终的聚合方法如.sum()、.max()、.min()。对于.average()它返回一个OptionalDouble需要进一步处理。理解这个流程后续的所有操作都是在这个框架下的具体实现。3. 四种聚合计算的详细实现与解析现在我们进入实战环节分别实现求和、最大值、最小值和平均值。我会为每种计算提供代码、输出结果并解释其中的注意事项和原理。3.1 求和Sum求和是最直接的需求。我们计算所有产品价格的总和。double totalPrice products.stream() .mapToDouble(Product::getPrice) // 映射为DoubleStream .sum(); // 归约求和 System.out.println(产品总价: totalPrice); // 输出: 产品总价: 1413.47原理解析与注意事项mapToDouble(Product::getPrice)这里使用了方法引用它等价于Lambda表达式p - p.getPrice()。它遍历流中的每个Product对象提取其price属性值并生成一个新的DoubleStream。.sum()DoubleStream的终端操作对流中的所有double元素进行求和。如果流为空sum()返回0.0。注意点确保你映射的属性是数值类型double,int,long。如果属性是BigDecimal金融计算常用则不能直接用mapToDouble而需要使用.map(Product::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add)这是另一个重要的模式。3.2 求最大值Max与最小值Min求最大值和最小值逻辑相似它们都返回一个Optional对象。// 求最高价格 OptionalDouble maxPriceOpt products.stream() .mapToDouble(Product::getPrice) .max(); // 返回OptionalDouble if (maxPriceOpt.isPresent()) { System.out.println(最高产品价格: maxPriceOpt.getAsDouble()); } else { System.out.println(列表为空无最高价格。); } // 输出: 最高产品价格: 999.99 // 求最低价格 OptionalDouble minPriceOpt products.stream() .mapToDouble(Product::getPrice) .min(); // 返回OptionalDouble minPriceOpt.ifPresent(minPrice - System.out.println(最低产品价格: minPrice) ); // 输出: 最低产品价格: 12.99原理解析与注意事项max()和min()这两个是终端操作返回OptionalDouble。这是因为如果流为空不存在最大或最小值返回Optional可以安全地避免NoSuchElementException。Optional的处理这是新手最容易踩坑的地方。直接调用getAsDouble()在Optional为空时会抛出异常。因此必须先使用isPresent()判断或者使用更函数式的ifPresent()方法。在Java 9还可以使用orElse()或orElseThrow()提供默认值或异常。性能提示在一次流遍历中同时求最大和最小值标准库没有直接方法。你可以使用Collectors.summarizingDouble我们会在后面介绍。如果非要一次遍历可以手动使用reduce但代码会复杂些通常不推荐。3.3 求平均值Average平均值计算需要稍多一步处理因为它返回的也是OptionalDouble。OptionalDouble averagePriceOpt products.stream() .mapToDouble(Product::getPrice) .average(); // 返回OptionalDouble // 方式一安全地处理Optional averagePriceOpt.ifPresent(avg - System.out.println(产品平均价格: avg) ); // 方式二提供默认值例如当列表为空时 double averagePrice averagePriceOpt.orElse(0.0); System.out.println(产品平均价格 (带默认值): averagePrice); // 输出: 产品平均价格: 282.694 // 输出: 产品平均价格 (带默认值): 282.694原理解析与注意事项.average()计算流中元素的算术平均值。同样空流会导致无平均值所以返回OptionalDouble。精度问题平均值是double类型可能存在浮点数精度问题。对于要求精确计算的场景如货币应考虑使用BigDecimal进行计算。可以用Stream收集BigDecimal属性然后进行除法运算。除零问题这是从热词“求平均值出现div0怎么办”联想到的关键点。Stream的average()方法在流为空时返回一个空的Optional而不是抛出ArithmeticException。这实际上是一种更安全的设计。但如果你自己用sum() / count()手动计算就必须检查count是否为0。因此强烈建议直接使用average()方法而非手动计算。4. 高阶技巧与综合应用掌握了基本操作后我们来看看如何更高效、更优雅地解决复杂问题。4.1 一次性获取所有统计信息Collectors.summarizingDouble如果你需要同时获得总和、数量、平均值、最大值和最小值写多个流遍历是低效的。Collectors.summarizingDouble以及summarizingInt,summarizingLong就是为此而生。DoubleSummaryStatistics stats products.stream() .collect(Collectors.summarizingDouble(Product::getPrice)); System.out.println( 价格统计摘要 ); System.out.println(数量Count: stats.getCount()); System.out.println(总和Sum: stats.getSum()); System.out.println(最小值Min: stats.getMin()); System.out.println(最大值Max: stats.getMax()); System.out.println(平均值Average: stats.getAverage()); // 输出: // 价格统计摘要 // 数量Count: 5 // 总和Sum: 1413.47 // 最小值Min: 12.99 // 最大值Max: 999.99 // 平均值Average: 282.694实操心得 这是处理聚合统计的“瑞士军刀”。在需要生成数据摘要报告时特别有用。它只遍历一次流性能优于分别调用多个终端操作。DoubleSummaryStatistics对象本身也提供了方便的combine方法可以合并多个统计结果这在并行处理或分块计算时非常有用。4.2 处理空集合与Null值的防御性编程在实际企业开发中数据源不可能总是完美的。List可能为null对象属性也可能为null。// 场景1List本身可能为null ListProduct productList possiblyGetListFromExternalService(); double safeTotal Optional.ofNullable(productList) // 用Optional包装可能为null的List .orElseGet(Collections::emptyList) // 如果为null则替换为空列表 .stream() .mapToDouble(Product::getPrice) .sum(); System.out.println(安全的总和: safeTotal); // 场景2List中的对象属性可能为null ListProduct productsWithNulls new ArrayList(); productsWithNulls.add(new Product(Item1, 10.0, 1)); productsWithNulls.add(new Product(Item2, null, 2)); // 假设price允许为null productsWithNulls.add(new Product(Item3, 30.0, 3)); // 错误的做法会抛出NullPointerException // double sumError productsWithNulls.stream().mapToDouble(Product::getPrice).sum(); // 正确的做法在映射前过滤掉null值 double sumSafe productsWithNulls.stream() .map(Product::getPrice) // 先映射为Double对象流可能包含null .filter(Objects::nonNull) // 关键过滤掉null .mapToDouble(Double::doubleValue) // 将非null的Double转为double .sum(); System.out.println(过滤null后的总和: sumSafe); // 输出: 40.0避坑指南 这是体现代码健壮性的关键。永远不要假设输入数据是完美的。对于来源不可控的集合使用Optional.ofNullable().orElse()进行保护。对于对象内部的null属性必须在map之后、进行数值计算之前使用filter将其排除。否则一个null就会导致整个流处理链崩溃。4.3 按条件分组后聚合这是更复杂的业务场景。例如我们想按产品类别假设Product有category属性分组然后分别计算每个类别的销售总额。// 假设Product新增了category属性 ListProduct productsWithCategory ... // 初始化数据 MapString, Double totalPriceByCategory productsWithCategory.stream() .collect(Collectors.groupingBy( Product::getCategory, // 分组依据类别 Collectors.summingDouble(Product::getPrice) // 下游收集器对每组的价格求和 )); totalPriceByCategory.forEach((category, total) - System.out.println(类别[ category ] 总销售额: total) );思路扩展groupingBy结合不同的下游收集器summingDouble,averagingDouble,maxBy,minBy,summarizingDouble可以实现极其强大的数据分析能力几乎可以应对所有基于分组的聚合查询需求在很多场景下可以替代简单的SQL分组查询。5. 性能考量、常见问题与排查技巧5.1 并行流Parallel Stream的使用与陷阱对于非常大的List例如数十万、百万级以上可以考虑使用并行流来加速计算。double parallelSum products.parallelStream() // 使用parallelStream .mapToDouble(Product::getPrice) .sum();注意事项开销并行流有线程创建、任务分解和结果合并的开销。对于小数据集比如几千条顺序流.stream()通常更快。线程安全确保你的数据源是线程安全的如ArrayList在只读情况下是安全的或者中间操作和终端操作没有共享的可变状态。例如在map函数中修改一个外部的共享变量是危险的。顺序敏感性findFirst、limit等操作在并行流中性能可能下降因为顺序难以保证。但对于sum、average、max等归约操作并行流效果通常很好。实践建议不要盲目使用并行流。先使用顺序流如果性能成为瓶颈再考虑在充分测试的基础上尝试并行流。可以使用System.currentTimeMillis()进行简单的性能对比测试。5.2 常见问题排查速查表在实际编码和调试中你可能会遇到以下问题问题现象可能原因解决方案编译错误Cannot resolve method mapToDouble流中的元素不是对象流或者方法引用不正确。确保stream()调用在List上且mapToDouble内的方法引用返回数值类型double,int,long。运行时错误NullPointerException1.List本身为null。2.List中的对象为null。3. 对象待提取的属性为null。1. 使用Optional.ofNullable(list).orElseGet(Collections::emptyList)保护。2. 使用filter(Objects::nonNull)过滤空对象。3. 在map后使用filter过滤属性null值见4.2节。结果不对或为01. 使用了错误的属性Getter方法。2. 流操作顺序错误提前执行了limit或filter。3. 整数除法导致精度丢失如用IntStream计算平均值。1. 检查方法引用是否正确指向目标属性。2. 检查操作链确保map在filter之前如果需要基于属性过滤。3. 计算平均值时优先使用DoubleStream和average()方法或先将int转为double。Optional直接调用get()报错流为空导致max(),min(),average()返回空的Optional直接get抛出NoSuchElementException。始终安全地处理Optional使用ifPresent()、orElse(defaultValue)或isPresent()判断。并行流结果非预期存在共享可变状态导致数据竞争Race Condition。检查Lambda表达式或方法引用中是否引用了外部非线程安全的变量并进行了修改。确保操作为无状态Stateless和互不干扰Non-interfering。5.3 关于热词中一些错误的理解浏览提供的热词我发现了一些常见的困惑点这里集中澄清error: value for list -form must have 1 elements 这看起来像是某个框架如Spring的配置绑定错误与Java核心的List和Stream操作无关。可能是YAML或Properties配置文件中对List类型的属性赋值格式不正确。java: you aren‘t using a compiler supported by lombok 这是Lombok注解处理器的配置问题。Lombok通过在编译时修改AST抽象语法树来生成Getter/Setter等方法。如果IDE或构建工具Maven/Gradle没有正确配置Lombok注解处理器就会出现此错误。确保你的IDE安装了Lombok插件并且构建脚本中包含了Lombok依赖。stream disconnected before completion 这一系列错误明显与网络流、WebSocket或某些API客户端如OpenAI API相关并非Java 8的Stream API。这是概念上的混淆。Java的Stream是用于处理集合数据的抽象而热词中的stream指的是数据流如HTTP流、视频流。在排查问题时首先要明确你面对的是哪种“Stream”。6. 完整工具类示例与总结最后我将这些知识点封装成一个实用的工具类方便在项目中复用。import java.util.*; import java.util.function.Function; import java.util.function.ToDoubleFunction; import java.util.stream.Collectors; public class AggregateUtils { /** * 对List中对象的某个Double属性求和 * param list 对象列表 * param mapper 提取Double属性的函数 * param T 对象类型 * return 属性值的总和列表为空或null时返回0.0 */ public static T double sum(ListT list, ToDoubleFunction? super T mapper) { return Optional.ofNullable(list) .orElseGet(Collections::emptyList) .stream() .mapToDouble(mapper) .sum(); } /** * 对List中对象的某个Double属性求最大值 * param list 对象列表 * param mapper 提取Double属性的函数 * param T 对象类型 * return OptionalDouble包含最大值如果存在 */ public static T OptionalDouble max(ListT list, ToDoubleFunction? super T mapper) { return Optional.ofNullable(list) .orElseGet(Collections::emptyList) .stream() .mapToDouble(mapper) .max(); } /** * 对List中对象的某个Double属性求最小值 * param list 对象列表 * param mapper 提取Double属性的函数 * param T 对象类型 * return OptionalDouble包含最小值如果存在 */ public static T OptionalDouble min(ListT list, ToDoubleFunction? super T mapper) { return Optional.ofNullable(list) .orElseGet(Collections::emptyList) .stream() .mapToDouble(mapper) .min(); } /** * 对List中对象的某个Double属性求平均值 * param list 对象列表 * param mapper 提取Double属性的函数 * param T 对象类型 * return OptionalDouble包含平均值如果存在 */ public static T OptionalDouble average(ListT list, ToDoubleFunction? super T mapper) { return Optional.ofNullable(list) .orElseGet(Collections::emptyList) .stream() .mapToDouble(mapper) .average(); } /** * 获取List中对象某个Double属性的统计摘要 * param list 对象列表 * param mapper 提取Double属性的函数 * param T 对象类型 * return DoubleSummaryStatistics 统计对象 */ public static T DoubleSummaryStatistics summarize(ListT list, ToDoubleFunction? super T mapper) { return Optional.ofNullable(list) .orElseGet(Collections::emptyList) .stream() .collect(Collectors.summarizingDouble(mapper)); } // 类似地可以重载提供针对Int和Long类型的方法summingInt, summarizingInt等 }使用这个工具类之前的计算可以简化为double total AggregateUtils.sum(products, Product::getPrice); OptionalDouble maxPrice AggregateUtils.max(products, Product::getPrice); DoubleSummaryStatistics stats AggregateUtils.summarize(products, Product::getPrice);这个工具类内部处理了null集合的问题对外提供了安全、一致的API。在实际项目中这样的工具类能极大减少重复代码并统一错误处理逻辑。回顾整个过程从最基础的mapToDouble().sum()到处理空值和并发的注意事项再到封装成健壮的工具类核心思想始终是利用Stream的声明式编程特性将“做什么”与“怎么做”分离写出更简洁、更易读、更易维护的集合处理代码。当你下次再遇到需要对List中的属性进行聚合计算时希望这些代码片段和思路能成为你顺手拈来的利器。

相关新闻

VisualCppRedist AIO 完整指南:如何一键修复 Visual C++ 运行库缺失问题

VisualCppRedist AIO 完整指南:如何一键修复 Visual C++ 运行库缺失问题

VisualCppRedist AIO 完整指南:如何一键修复 Visual C 运行库缺失问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 一、那个让人抓狂的周五晚上 …

2026/10/3 13:18:02 阅读更多 →
银河麒麟系统Samba共享文件夹配置:跨平台文件共享实战指南

银河麒麟系统Samba共享文件夹配置:跨平台文件共享实战指南

1. 项目概述:为什么要在银河麒麟上折腾共享文件夹?如果你在单位或团队里用上了银河麒麟操作系统,大概率会碰到一个非常实际的需求:怎么方便地在几台电脑之间传文件?是插U盘来回拷贝,还是用聊天软件传来传去…

2026/10/11 16:41:02 阅读更多 →
Ubuntu网络端口查看与监控实用指南

Ubuntu网络端口查看与监控实用指南

1. Ubuntu网络端口查看全指南在Linux系统管理中,网络端口监控是每个运维人员必备的基础技能。当我们需要排查服务连通性问题、分析网络流量或检查安全风险时,第一件事往往就是确认哪些端口正在被使用。Ubuntu作为最流行的Linux发行版之一,提供…

2026/10/12 20:11:25 阅读更多 →

最新新闻

Python特殊语法全解析:从海象运算符到match与类型标注

Python特殊语法全解析:从海象运算符到match与类型标注

你写Python写了几年?有没有过这种时刻:读别人代码时,明明每个单词都认识,连在一起却要停下来反应半天——海象运算符、match语句、for-else分支、int | None这样的类型写法……这些就是Python里的“特殊语法”。最近总有读者问我同…

2026/10/16 5:01:28 阅读更多 →
TM1621段码屏驱动开发实战:三线串口时序、显存映射与按键扫描

TM1621段码屏驱动开发实战:三线串口时序、显存映射与按键扫描

简介:这是一款面向嵌入式开发者的TM1621数码管控制器C语言驱动,可直接用于智能家居面板、便携仪表、工业设备等需要七段数码管或点阵LED显示的场景,解决开发者通过软件控制显示数字、字符与符号的核心需求。整套资源以RAR格式压缩&#xff0c…

2026/10/16 5:01:28 阅读更多 →
SCD40二氧化碳传感器驱动开发:I2C与CRC8排坑实战

SCD40二氧化碳传感器驱动开发:I2C与CRC8排坑实战

简介:面向嵌入式开发者的SCD40二氧化碳传感器驱动资源,适用于智能家居、农业温室、办公楼宇等室内环境监测场景。资源基于STM32平台,提供完整的传感器驱动工程,集成了二氧化碳、温度、湿度三合一测量功能,重点解决I2C/…

2026/10/16 5:01:28 阅读更多 →
YouTube新手起步指南:完成胜过完美,绕开拖延陷阱顺利发布首个视频

YouTube新手起步指南:完成胜过完美,绕开拖延陷阱顺利发布首个视频

做YouTube这几年,我见过太多人卡在同一步:想拍一条完美的视频,结果几个月过去了,连一个镜头都没录。每次问起来,理由都差不多——设备还不够好、脚本还没打磨好、怕发出去被人骂、觉得同类内容已经有人做得很好自己没必…

2026/10/16 5:01:28 阅读更多 →
Agentic Harness Workflow:从能跑通的AI代码到可交付的工程

Agentic Harness Workflow:从能跑通的AI代码到可交付的工程

1. 为什么“能跑通的 AI 代码”离“能交付的工程”还差一大截很多人第一次用 AI 写代码,体验都差不多:丢一段需求进去,几秒钟吐出一整段函数,跑一下还真能过。于是很自然地产生一个错觉——AI Coding 已经能替代相当一部分开发工作…

2026/10/16 5:01:28 阅读更多 →
移动机器人路径规划实战:基于Dijkstra算法的栅格地图最优路径实现

移动机器人路径规划实战:基于Dijkstra算法的栅格地图最优路径实现

移动机器人路径规划这件事,只要做过的人都知道,最头疼的不是算法本身有多难,而是“原理懂了,代码跑不通”“代码通了,换张地图又挂了”这类问题。最近我在整理一个基于Dijkstra算法的移动机器人路径规划项目&#xff0…

2026/10/16 5:00:28 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →