微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java-8 – 单次迭代中的sum和max值

我有一个自定义CallRecord对象的列表

public class CallRecord {

    private String callId;
    private String aNum;
    private String bNum;
    private int seqNum;
    private byte causeForOutput;
    private int duration;

    private recordtype recordtype;
.
.
.
}

有两个逻辑条件,每个的输出是:

>最高seqNum,总和(持续时间)
>最高seqNum,总和(持续时间),最高causeForOutput

根据我的理解,Stream.max(),Collectors.summarizingInt()等将要求对上述结果进行多次迭代.我也遇到了thread建议定制收藏家,但我不确定.

下面是为此目的提供的简单的Java 8之前的代码

if (...) {

    for (CallRecord currentRecord : completeCallRecords) {
        highestSeqNum = currentRecord.getSeqNum() > highestSeqNum ? currentRecord.getSeqNum() : highestSeqNum;
        sumOfDuration += currentRecord.getDuration();
    }

} else {
    byte highestCauseForOutput = 0;

    for (CallRecord currentRecord : completeCallRecords) {
        highestSeqNum = currentRecord.getSeqNum() > highestSeqNum ? currentRecord.getSeqNum() : highestSeqNum;
        sumOfDuration += currentRecord.getDuration();

        highestCauseForOutput = currentRecord.getCauseForOutput() > highestCauseForOutput ? currentRecord.getCauseForOutput() : highestCauseForOutput;
        }

}

解决方法

你希望在一次迭代中完成所有事情是不合理的.你应该首先考虑简单性,必要时要提高性能,但坚持单次迭代既不是.

性能取决于太多因素,无法提前做出预测.迭代(通过普通集合)本身的过程不一定是一个昂贵的操作,甚至可能从一个更简单的循环体中受益,使得多次遍历具有直接操作比单次遍历尝试执行所有操作更有效一旦.找出的唯一方法是使用实​​际操作进行测量.

将操作转换为Stream操作可以简化代码,如果您直接使用它,即

int highestSeqNum=
  completeCallRecords.stream().mapToInt(CallRecord::getSeqNum).max().orElse(-1);
int sumOfDuration=
  completeCallRecords.stream().mapToInt(CallRecord::getDuration).sum();
if(!condition) {
  byte highestCauseForOutput = (byte)
    completeCallRecords.stream().mapToInt(CallRecord::getCauseForOutput).max().orElse(0);
}

如果您仍然对多次迭代这一事实感到不舒服,您可以尝试编写一个自定义收集器,同时执行所有操作,但结果不会比您的循环更好,无论是在可读性还是效率方面.

不过,我宁愿避免代码重复而不是试图在一个循环中完成所有事情,即

for(CallRecord currentRecord : completeCallRecords) {
    int nextSeqNum = currentRecord.getSeqNum();
    highestSeqNum = nextSeqNum > highestSeqNum ? nextSeqNum : highestSeqNum;
    sumOfDuration += currentRecord.getDuration();
}
if(!condition) {
    byte highestCauseForOutput = 0;
    for(CallRecord currentRecord : completeCallRecords) {
        byte next = currentRecord.getCauseForOutput();
        highestCauseForOutput = next > highestCauseForOutput? next: highestCauseForOutput;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐