Java-8 – sum and max values in a single iteration

I have a list of custom callrecord objects

public class CallRecord {

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

    private RecordType recordType;
.
.
.
}

There are two logical conditions, and the output of each is:

>Maximum seqnum, sum (duration) > maximum seqnum, sum (duration), maximum causeoutput

According to my understanding, stream max(),Collectors. Summarizingint () and others will require multiple iterations of the above results I also met thread suggested custom collectors, but I'm not sure

Here is the simple pre Java 8 code provided for this purpose:

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

}

Solution

It's unreasonable for you to expect everything to be done in one iteration You should first consider simplicity and improve performance if necessary, but sticking to a single iteration is neither

Performance depends on too many factors to predict in advance The process of iteration (through ordinary sets) itself is not necessarily an expensive operation, and may even benefit from a simpler loop body, so that multiple iterations have direct operations, which is more effective than a single traversal attempt to perform all operations The only way to find out is to use actual operation for measurement

Converting an operation to a stream operation simplifies the code if you use it directly, that is

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

If you are still uncomfortable with the fact of multiple iterations, you can try to write a custom collector and perform all operations at the same time, but the result will not be better than your loop, both in readability and efficiency

However, I'd rather avoid code duplication than try to do everything in a loop, that is

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;
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>