当前位置: 首页 > 知识库问答 >
问题:

从单例中整平流(可选)

瞿博易
2023-03-14

这个问题与Java8mapflatmap有关,它们同时存在于streamoptional中。值得注意的是,C#有一个类似的构造,名为selectmany

我已经了解了这两种方法,特别是在streams中,您可以使用flatmap集合 > 获取集合 ,这是我想要的。

在我的示例中,我有一个嵌套的类结构(来自一个我无法控制的DTD),我想在其中计算一个值的和。我不会因为懒惰而修改班名。

class DatiTelematico {
    private Adempimento adempimento;
}

class Adempimento {
    private List<DatiNegozio> datiNegozio;
}

class DatiNegozio {
    private List<Negozio> negozio;
}

class Negozio {
    private List<Tassazione> tassazione;
}

class Tassazione {
    private BigDecimal importo;
}

给定DatiTeleMatico类的可选实例,我希望从telematico join adempimento join datiNegozio join negozio join Tassazione中sum(importo)。

我所能做的最好的方法是使用嵌套的lambdas和简单的map方法

optionalTelematico.map(DatiTelematico::getAdempimento)
  .map(Adempimento::getDatiNegozio)
  .map(l -> l.stream().map(DatiNegozio::getNegozio)
             .map(n -> n.stream()
                        .map(Negozio::getTassazione)
                        .map(t -> t.stream()
                                   .map(Tassazione::getImporto)
                                   .reduce(BigDecimal.ZERO,
                                           BigDecimal::add))
                        .reduce(BigDecimal.ZERO, BigDecimal::add))
             .reduce(BigDecimal.ZERO, BigDecimal::add))
  .orElse(BigDecimal.ZERO));

我试着开始写一些

但我得到一个编译器错误

Method binding must be directly contained in a class (OTJLD A.3.1).

如何灵活地从可选 (单例)切换到要求和的集合?我这样问是为了增加我对Java lambda的了解。


共有1个答案

楚瑞
2023-03-14

optionalstream实际上都只表示一个数据片段--如果是optional,则该数据片段可能不存在或存在,如果是stream,则可能在之前或之后有其他数据片段,但目前我们只有这一段。

现在,

map方法本质上是optionalstream的一种类型转换:映射采用一个函数i->r,应用该函数可以使转换optional->optional (或stream->stream )。

FlatMap方法是一种转换,它可以:

  • 将可选值转换为另一个可选值(可能为空)。这意味着函数类型i->可选
  • 将流中的每个项转换为另一个流(其中有0..n个元素)。这意味着函数类型i->stream 。注意,对于streams,此操作可以更改stream中包含的元素的数量(但它不会改变一次处理一个stream元素的事实)。

在您的特定情况下,通过将转换为optional,您可以直接获得最多optional <list > :

Optional<List<DatiNegozio>> optDatiNegozio = optionalDatiTelematico
  .map(DatiTelematico::getAdempimento) // Optional<Adempimento>
  .map(Adempimento::getDatiNegozio);

您可以通过轻松地将每个列表 转换为可选的 求和和访问元素:

static Optional<BigDecimal> sumImporto(List<DatiNegozio> datiNegozio) {

  return datiNegozio.stream() // Stream<DatiNegozio>
    .map(DatiNegozio::getNegozio)                 // Stream<List<Negozio>>

    // unroll stream of collections into a stream of collection elements
    .flatMap(List::stream)                        // Stream<Negozio>
    .map(Negozio::getTassazione)                  // Stream<List<Tassazione>>

    // again, unroll stream of collections into a stream of collection elements
    .flatMap(List::stream)
    .map(Tassazione::getImporto)                  // Stream<BigDecimal>

    // last thing we need to do is just reduce
    .reduce(BigDecimal::add);
  }

如您所见,第二个片段允许您将列表 转换为可选的 。在此之后,您有两个选项(文体选择):

>

  • reduce的一个变体产生bigdecimal而不是可选的 :

    .reduce(BigDecimal.ZERO,BigDecimal::Add);//它产生的是具体类型,而不是可选类型,因为即使在流中没有元素的情况下,我们至少可以返回我们开始的值-ZERO

    您可以使用第二个代码段生成可在flatmap中使用的函数--使用可选的:

    OptionalDatiTeleMatico.Map(DatiTeleMatico::GetAdemPimento).Map(AdemPimento::GetDateInegoZio).FlatMap(Example::SumImporto)//对来自第二个代码段的方法的引用.Orelse(BigDecimal.Zero);//如果我们在任何时候都有Optional.Empty该怎么办

  •  类似资料:
    • 我有一个场景,我需要定期调用一个应用编程接口来检查结果。我使用来创建一个调用应用编程接口的间隔函数。 然而,我有背压的问题。在我下面的例子中,间隔中的每个记号都会创建一个新的单曲。理想的效果是仅在调用尚未进行时调用API 我可以使用过滤器变量来解决这个问题: 但是它看起来像一个黑客解决方案。我已经厌倦了在函数之后应用,但是它没有效果。 有什么建议吗?

    • 主要内容:PHP - 在表单中确保输入值,PHP - 完整表单实例,实例本章节将介绍如何让用户在点击"提交(submit)"按钮提交数据前保证所有字段正确输入。 PHP - 在表单中确保输入值 在用户点击提交按钮后,为确保字段值是否输入正确,我们在HTML的input元素中插添加PHP脚本, 各字段名为: name, email, 和 website。 在备注中的 textarea 字段中,我们将脚本放于 <textarea> 和 </textarea> 标签之间。

    • 我正在使用与Spring Boot Activiti Starter集成的Activiti 5 REST API接口,我正在尝试完成一个流程实例。我能够实例化流程定义,遍历流程实例任务并完成其中的每一项。它可以正常工作,直到流程结束,没有剩余的挂起任务。我希望流程实例能够完成,即completed:true,因为我有一个结束事件(terminateEventDefinition),但事实并非如此。

    • 6.4.3 Xacro_完整使用流程示例 需求描述: 使用 Xacro 优化 URDF 版的小车底盘模型实现 结果演示: 1.编写 Xacro 文件 <!-- 使用 xacro 优化 URDF 版的小车底盘实现: 实现思路: 1.将一些常量、变量封装为 xacro:property 比如:PI 值、小车底盘半径、离地间距、车轮半径、宽度 .... 2.

    • 问题内容: 在python或标准库中的某个地方是否存在整数平方根?我希望它是准确的(即返回一个整数),如果没有解决办法,可以吠叫。 此刻,我滚动了自己的幼稚: 但这很丑陋,我不太相信大整数。我可以遍历正方形,如果超出了该值,则放弃,但是我认为做这样的事情有点慢。另外我想我可能正在重新发明轮子,像这样的东西肯定已经存在于python中了… 问题答案: 牛顿的方法在整数上工作得很好: 这将返回的最大整

    • python或标准库中是否有整数平方根?我希望它是精确的(即返回一个整数),如果没有解决方案,就吠叫。 此刻我卷起了我自己天真的一个: 但是它很难看,而且我不相信它是大整数。我可以遍历这些方块,如果超过了这个值就放弃,但我认为这样做会有点慢。而且我想我可能会重新发明轮子,像这样的东西肯定已经存在于python中了。。。