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;
    }
}

相关文章

HashMap是Java中最常用的集合类框架,也是Java语言中非常典型...
在EffectiveJava中的第 36条中建议 用 EnumSet 替代位字段,...
介绍 注解是JDK1.5版本开始引入的一个特性,用于对代码进行说...
介绍 LinkedList同时实现了List接口和Deque接口,也就是说它...
介绍 TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对...
HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进...