由于super.getBuffers() 的结果是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;
或
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);