如何在流上重用过滤器和映射的应用程序?

2024-01-25

我有一组从共享类型继承的域对象(即GroupRecord extends Record, RequestRecord extends Record)。子类型具有特定的属性(即GroupRecord::getCumulativeTime, RequestRecord::getResponseTime).

此外,作为解析日志文件的结果,我有一个具有混合子类型的记录列表。

List<Record> records = parseLog(...);

为了计算日志记录的统计信息,我想仅对与特定子类型匹配的记录子集应用数学函数,即仅对GroupRecords。因此我想要有一个特定子类型的过滤流。我知道我可以申请filter and map到子类型使用

records.stream()
       .filter(GroupRecord.class::isInstance)
       .map(GroupRecord.class::cast)
       .collect(...

在流上多次应用此过滤器和转换(特别是在针对不同计算多次对同一子类型执行此操作时)不仅很麻烦,而且会产生大量重复。

我目前的方法是使用TypeFilter

class TypeFilter<T>{

    private final Class<T> type;

    public TypeFilter(final Class<T> type) {
        this.type = type;
    }

    public Stream<T> filter(Stream<?> inStream) {
        return inStream.filter(type::isInstance).map(type::cast);
    }
}

应用于流:

TypeFilter<GroupRecord> groupFilter = new TypeFilter(GroupRecord.class); 

SomeStatsResult stats1 = groupFilter.filter(records.stream())
                                      .collect(...)
SomeStatsResult stats2 = groupFilter.filter(records.stream())
                                      .collect(...)

它有效,但我发现这种方法对于这样一个简单的任务来说有点太多了。因此我想知道,是否有更好的或者最好的方法是什么,以简洁和可读的方式使用流和函数使这种行为可重用?


这取决于您认为什么“更简洁和可读”。我本人认为您已经实施的方式就很好。

然而,确实有一种方法可以从使用它的地方稍微缩短一点,通过使用Stream.flatMap:

static <E, T> Function<E, Stream<T>> onlyTypes(Class<T> cls) {
  return el -> cls.isInstance(el) ? Stream.of((T) el) : Stream.empty();
}

它所做的是将每个原始流元素转换为Stream一个元素(如果该元素具有预期类型),或者为空Stream如果没有。

其用途是:

records.stream()
  .flatMap(onlyTypes(GroupRecord.class))
  .forEach(...);

这种方法有明显的权衡:

  • 您确实从管道定义中丢失了“过滤器”一词。这可能比原来的更令人困惑,所以也许是一个比原来更好的名字onlyTypes是需要的。
  • Stream对象相对重量级,创建太多对象可能会导致性能下降。但您不应该相信我在这里所说的话并在重负载下分析这两种变体。

Edit:

由于问题询问的是重用filter and map更笼统地说,我觉得这个答案还可以讨论更多的抽象。因此,要重用一般意义上的过滤器和映射,您需要以下内容:

static <E, R> Function<E, Stream<R>> filterAndMap(Predicate<? super E> filter, Function<? super E, R> mapper) {
   return e -> filter.test(e) ? Stream.of(mapper.apply(e)) : Stream.empty();
}

和原创的onlyTypes实施现在变成:

static <E, R> Function<E, Stream<R>> onlyTypes(Class<T> cls) {
  return filterAndMap(cls::isInstance, cls::cast);
}

但是,再次需要权衡:生成的平面映射器函数现在将保存捕获的两个对象(谓词和映射器),而不是单个对象Class上述实现中的对象。这也可能是过度抽象的情况,但这取决于您需要该代码的位置和原因。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在流上重用过滤器和映射的应用程序? 的相关文章

随机推荐

  • 带有 ASP.NET 网站的 NUnit

    我目前正在尝试升级我们工作中的构建服务器 从没有构建服务器到拥有一个 我正在使用 JetBrainsTeamCity http en wikipedia org wiki TeamCity 已经使用过锐锐 http en wikipedia
  • Angular2 和 TypeScript 导入 node_modules

    我有一个非常简单的 hello world Angular2 应用程序 我还做出了一个明显不合理的决定 即在我的开发项目和 Spring 后端的最终部署文件夹之间使用不同的目录结构 由于这种差异 我在 TypeScript 导入方面遇到了问
  • 从嵌套集生成 JSON(perl、sql、jquery)

    我在数据库中有内容页面 使用嵌套集 我需要通过 jQuery jsTree 插件显示它 需要返回带有如下数据的 JSON data node1Title children data subNode1Title children data s
  • 单击按钮上的 JFileChooser

    我有一个按钮 单击它我希望弹出 JFileChooser 我已经尝试过这个 JButton browse new JButton Browse add browse browse addActionListener new ClassBro
  • Azure Cosmos DB 检查字段中的数组是否包含在搜索数组中

    我有一个 Microsoft Azure CosmosDB MongoDB Api 数据库 我正在尝试获取其中一个数组字段完全包含在我的搜索数组中的所有文档 所以 我正在寻找的是 考虑到包含文档的集合测试 id 1 filters 1 2
  • Qt - 自定义小数点和千位分隔符

    如何将数字 双精度 转换为具有自定义小数点和千位分隔符的字符串 我见过 QLocale 但我不想选择本地化国家 地区 而是指定我自己的小数点和千位分隔符 Thanks Qt 不支持自定义区域设置 但仅处理组和小数点字符很简单 const Q
  • 查询对象 mongoose 的嵌套数组

    我想在嵌套对象中查找带有 Alexa 的名称 操场 https mongoplayground net p rqYQtf0liaX https mongoplayground net p rqYQtf0liaX item journal i
  • 类型“Object”上不存在属性“json”

    我正在尝试使用 Angular 2 HttpClient 通过 REST 获取数据 我正在关注这里的角度教程https angular io tutorial toh pt6 https angular io tutorial toh pt
  • Woocommerce REST API - 添加自定义路由

    我有一家 Woocommerce 商店 我正在使用 Woocommerce REST API 在另一个网站上列出产品等 它工作正常 不过 我缺少一些功能 我想知道是否可以通过自定义调用来扩展 API 通过阅读 Woocommerce 的源代
  • 如何自动增加詹金斯构建号?

    如何自动增加 jenkins 内部版本号或使用 shell 脚本 现在我正在使用配置选项执行相同的操作 并手动增加 我想自动完成 您所要求的 即在多个作业之间保持内部版本号相同 很简单不可能的在詹金斯 这是通过设计完成的 正如 Jenkin
  • 过滤多列 Pandas

    我有一个将 pandas 数据框作为输入的方法 def dfColumnFilter df columnFilter columnName Returns a filtered DataFrame Keyword arguments df
  • 如何从 python 程序发送信号?

    我有这段代码可以监听 USR1 信号 import signal import os import time def receive signal signum stack print Received signum signal sign
  • 用于同步数组访问的最快 x86 汇编代码? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 同步访问内存中数组的最快 x86 汇
  • PHP 中具有不透明度的径向渐变

    我需要创建一个具有不透明度的 PNG 径向渐变 我浏览过 GDLib 但看不到生成径向渐变的方法 有谁知道使用 GDlib 或任何其他 PHP 图形库的方法吗 我想最坏的情况我可以使用 GDLib 逐像素生成它 但是如何开始对此进行数学计算
  • SQLAlchemy 模型 Django 喜欢保存方法吗?

    我正在一个项目中使用 sqlalchemy 不过 我更习惯Django的ORM 我想知道在 sqlalchemy ORM 中是否有类似于 Django 模型的 save 方法 我可以重写该方法以在 提交 保存 时自动实施操作 您可以使用一些
  • 无法获取 SoftwareComponentInternal - Maven 发布插件项目 gradle 的未知属性“release”

    我有一个包含多个模块的 Android 项目 我想将它们发布到自托管 Maven 存储库 我之前将发布代码存在于各个模块中 并且一切正常 我现在正在尝试将发布代码移至项目中build gradle这样我就可以重用该代码 我的各个模块内的代码
  • 在 pandas 中组合两个时间序列

    如果这明显记录在某处 我深表歉意 但我很难发现它 我有两个带有一些重叠日期 索引的 TimeSeries 我想合并它们 我假设我必须指定从两个系列中的哪一个获取重叠日期的值 为了说明我有 s1 2008 09 15 100 2008 10
  • 数据 URI 的用途是什么?

    为什么资源有时会嵌入到数据 URI 中 而不是使用链接到服务器上作为文件存储的资源的常规 URI 1 减少服务器请求 数据 URI 可用于通过减少获取资源所需的 HTTP 请求数量来减少服务器负载并提高客户端性能 例如 这个 HTML im
  • 注册媒体维基需要管理员批准吗?

    我维护的一个 wiki 受到了垃圾邮件机器人的严重打击 我们没有很多用户 而且我不想让合法用户背负验证码 有没有一种简单的方法可以让管理员确认注册 我浏览了手册 但无法弄清楚如何操作 您可以创建一个新用户权限 例如 批准 允许管理员分配该权
  • 如何在流上重用过滤器和映射的应用程序?

    我有一组从共享类型继承的域对象 即GroupRecord extends Record RequestRecord extends Record 子类型具有特定的属性 即GroupRecord getCumulativeTime Reque