java - 在列表中插入/更新元素的最快方法
问题描述
我想替换提供的列表中的一个对象,或者如果不在此列表中,则添加它。我需要最快的方法来执行此插入/更新。
我有两个版本。哪个更快或者你知道更快的方法吗?
版本 1:
void update(List<Task> orderedTask, Task task) {
int idx = Collections.binarySearch(orderedTask, task);
if (idx >= 0) {
orderedTask.remove(idx);
orderedTask.add(idx, task);
} else {
orderedTask.add(-idx - 1, task);
}
}
版本 2:
void update2(List<Task> orderedTask, Task task) {
var idx = orderedTask.indexOf(task);
if(idx >= -1) {
orderedTask.remove(idx);
orderedTask.add(idx, task);
}
else {
orderedTask.add(-idx - 1, task);
}
}
我猜,java流并不比上面的方法快..
解决方案
您应该首先关注正确性而不是性能。
你第二种方法
void update2(List<Task> orderedTask, Task task) {
var idx = orderedTask.indexOf(task);
if(idx >= -1) {
orderedTask.remove(idx);
orderedTask.add(idx, task);
}
else {
orderedTask.add(-idx - 1, task);
}
}
已损坏,由于某些未知原因,您将idx >= 0
第一个变体的条件更改为,因此当列表中没有匹配元素时idx >= -1
,代码将尝试更改无效索引处的元素。-1
当您使用 修复此问题时idx >= 0
,您将面临找不到匹配元素时indexOf
总是返回的问题-1
,这不允许派生插入位置。该公式-idx - 1
仅适用于在其合同中指定它的搜索方法,例如binarySearch
,但不适用于indexOf
。
由于indexOf
返回-1
不在列表中的元素,因此公式将始终计算为零,因此您始终在列表的开头插入新元素。如果您的合同是要保持列表排序,那么您就没有履行它。除此之外,总是在开头插入对于ArrayList
.
如果您的合同是您收到一个排序列表并且必须保持排序,那么这binarySearch
是履行合同的唯一方法,而且它比其他方法更有效indexOf
。但是当您在处理 时关心性能时ArrayList
,您不应该使用orderedTask.remove(idx); orderedTask.add(idx, task);
来替换元素。remove(int index)
必须复制后备数组中的所有剩余元素,而add(int index, …)
必须将它们复制回其原始位置。只需使用该set
方法即可。
void update(List<Task> orderedTask, Task task) {
int idx = Collections.binarySearch(orderedTask, task);
if (idx >= 0) {
orderedTask.set(idx, task);
} else {
orderedTask.add(-idx - 1, task);
}
}
推荐阅读
- python - 如何循环一个输入而不是重新启动整个程序?
- node.js - Mysql插入带有来自嵌套值的动态值
- rust - 使用 Rc 时的终身问题
> 实现二叉搜索树 - c++ - 如何将 constexpr 字符串数组作为参数传递?
- gdb - 如何将 ELF 文件的内容转储到特定地址?
- html - 如何将元素放置在输入字段的左侧?
- python - ImportError:无法从部分初始化的模块导入名称“twiml”
- python - Python:从父包子类化一个类有什么问题?
- javascript - Highcharts- Javascript- 默认情况下如何显示所有图例系列的累积计数,以及图例中的链接系列
- powershell - 从 URL 静默下载的 Powershell 脚本