由于结果super.getBuffers()
is List<ByteBuffer>
,你可以迭代它两次。
List<ByteBuffer> buffers = super.getBuffers();
if (buffers.stream().allMatch(b -> b.position() > 0)) {
return OutgoingMessageStatus.FULLY_SENT;
} else if (buffers.stream().noneMatch(b -> b.position() > 0)) {
return OutgoingMessageStatus.WAS_NOT_SENT;
} else {
return OutgoingMessageStatus.PARTIALLY_SENT;
}
请注意,这仍然不需要在所有情况下迭代所有元素。allMatch
一旦遇到不匹配的元素就返回,noneMatch
一旦遇到匹配的元素就返回。所以在PARTIALLY_SENT
在这种情况下,有可能在没有考虑所有要素的情况下得出结论。
另一种选择是
List<ByteBuffer> buffers = super.getBuffers();
if(buffers.isEmpty()) return OutgoingMessageStatus.FULLY_SENT;
Predicate<ByteBuffer> p = b -> b.position() > 0;
boolean sent = p.test(buffers.get(0));
if(!sent) p = p.negate();
return buffers.stream().skip(1).allMatch(p)? sent?
OutgoingMessageStatus.FULLY_SENT:
OutgoingMessageStatus.WAS_NOT_SENT:
OutgoingMessageStatus.PARTIALLY_SENT;
}
第一个元素的状态决定了我们必须检查哪个条件。一旦出现矛盾因素,allMatch
立即返回,我们有一个PARTIALLY_SENT
情况。否则,所有元素都像第一个元素一样匹配,这意味着“全部发送”或“无发送”。
对空列表的预检查会产生与原始代码相同的行为,并确保get(0)
永远不会破裂。
如果您确实有一个 Stream 而不是可以多次迭代的源,则没有简单的捷径解决方案,因为这需要有状态谓词。然而,有一些简单的解决方案可以处理所有元素。
Map<Boolean,Long> result=getBuffers().stream()
.collect(Collectors.partitioningBy(b -> b.position() > 0, Collectors.counting()));
return
result.getOrDefault(false, 0L)==0?
OutgoingMessageStatus.FULLY_SENT:
result.getOrDefault(true, 0L)==0?
OutgoingMessageStatus.WAS_NOT_SENT:
OutgoingMessageStatus.PARTIALLY_SENT;
or
return super.getBuffers().stream()
.map(b -> b.position() > 0?
OutgoingMessageStatus.FULLY_SENT: OutgoingMessageStatus.WAS_NOT_SENT)
.reduce((a,b) -> a==b? a: OutgoingMessageStatus.PARTIALLY_SENT)
.orElse(OutgoingMessageStatus.FULLY_SENT);