我必须优化算法并发现我们有这样的循环
while (!floorQueues.values().stream().allMatch(List::isEmpty))
似乎在每次迭代中,它都会检查此映射中的所有列表是否为空。 地图中的数据是从这样的二维数组中获取的
int currentFloorNumber = 0;
for (int[] que : queues) {
List<Integer> list = Arrays.stream(que).boxed().collect(Collectors.toList());
floorQueues.put(currentFloorNumber, list);
currentFloorNumber++;
}
我认为如果在转换数据时考虑数组中元素的数量,然后检查从列表中删除了多少次作为结束循环的条件,那将是最佳选择
while (countOfDeltedElements < totalCountOfElements)
但是当我测试代码时,它的运行速度比以前慢。所以我想知道isEmpty是如何工作的 场景比我的解决方案要快。
答案 0 :(得分:2)
这可能取决于implements List
类的实现。
ArrayList
仅检查元素是否为0:
/**
* Returns <tt>true</tt> if this list contains no elements.
*
* @return <tt>true</tt> if this list contains no elements
*/
public boolean isEmpty() {
return size == 0;
}
答案 1 :(得分:2)
一个独特的非答案:Java性能和Java基准测试不能以这种方式工作。
您无法查看这5行源代码来了解确切的操作会在运行时发生。或更准确地说:您必须了解流是非常高级的又名 complex 。 Stream 代码可能在运行时创建大量对象,这些对象仅使用一次,然后被丢弃。为了评估真正的性能影响,您真的必须了解该代码在做什么。可能是:很多!
严肃的答案是:如果您真的需要了解发生了什么,那么您将需要:
无论如何,您都应该开始阅读here,以确保首先测量的数字有意义。
答案 2 :(得分:1)
通常,我们有两种方法检查列表是否为空list.length() > 0
或!list.isEmpty()
。
当我们使用list.length()
时,后端发生的事情将迭代/遍历到列表的末尾,如果列表中有大量元素,则到达末尾肯定会花费很长时间。另一方面,如果我们使用'list.isEmpty()',它将仅检查列表的第一个元素是否为(O(1)),并仅在该第一个索引上返回true / false,这显然是很快的。
从性能角度出发,我们应该始终将isEmpty()
用作最佳实践