Вы должны сначала сосредоточиться на правильности, а не на производительности.
Ваш второй метод
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);
}
}