I have the following code:
mostRecentMessageSentDate = messageInfoList
.stream()
.findFirst().orElse(new MessageInfo())
.getSentDate();
unprocessedMessagesCount = messageInfoList
.stream()
.filter(messageInfo -> messageInfo.getProcessedDate() == null)
.count();
hasAttachment = messageInfoList
.stream()
.anyMatch(messageInfo -> messageInfo.getAttachmentCount() > 0);
如您所见,我流式传输相同的列表3次,因为我想找到3个不同的值。如果我在For-Each循环中执行此操作,则只需循环一次。
从性能上讲,使用for循环进行这样的操作是否更好,以便只循环一次?我发现流更易读。
编辑:我进行了一些测试:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
List<Integer> integerList = populateList();
System.out.println("Stream time: " + timeStream(integerList));
System.out.println("Loop time: " + timeLoop(integerList));
}
private static List<Integer> populateList() {
return IntStream.range(0, 10000000)
.boxed()
.collect(Collectors.toList());
}
private static long timeStream(List<Integer> integerList) {
long start = System.currentTimeMillis();
Integer first = integerList
.stream()
.findFirst().orElse(0);
long containsNumbersGreaterThan10000 = integerList
.stream()
.filter(i -> i > 10000)
.count();
boolean has10000 = integerList
.stream()
.anyMatch(i -> i == 10000);
long end = System.currentTimeMillis();
System.out.println("first: " + first);
System.out.println("containsNumbersGreaterThan10000: " + containsNumbersGreaterThan10000);
System.out.println("has10000: " + has10000);
return end - start;
}
private static long timeLoop(List<Integer> integerList) {
long start = System.currentTimeMillis();
Integer first = 0;
boolean has10000 = false;
int count = 0;
long containsNumbersGreaterThan10000 = 0L;
for (Integer i : integerList) {
if (count == 0) {
first = i;
}
if (i > 10000) {
containsNumbersGreaterThan10000++;
}
if (!has10000 && i == 10000) {
has10000 = true;
}
count++;
}
long end = System.currentTimeMillis();
System.out.println("first: " + first);
System.out.println("containsNumbersGreaterThan10000: " + containsNumbersGreaterThan10000);
System.out.println("has10000: " + has10000);
return end - start;
}
}
正如预期的那样,for循环始终比流(streams)更快。
first: 0
containsNumbersGreaterThan10000: 9989999
has10000: true
Stream time: 57
first: 0
containsNumbersGreaterThan10000: 9989999
has10000: true
Loop time: 38
但是从未有显著的差异。
findFirst可能不是一个好的例子,因为如果流为空,它只会退出,但我想知道它是否有影响。
我希望能够从一个流中进行多个计算。IntSummaryStatistics并不能完全满足我的需求。我想我会听从@florian-schaetz的建议,更注重可读性,即使这只会带来微小的性能提升。
IntSummaryStatistics
和Collectors.summarizingInt
,它们可以做类似的事情,在流上一次收集三个不同的信息。但是,除非你的列表非常大,否则这可能不值得。 - David Conrad