Я хочу заменить один объект в пределах предоставленного списка или добавить его, если не уже в этом списке. Мне нужен самый быстрый путь для выполнения этой вставки / обновления.

У меня есть две версии. Что быстрее или вы знаете быстрее?

версия 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 Streams не быстрее, чем методы выше.

-3
nimo23 1 Окт 2019 в 10:13

1 ответ

Лучший ответ

Вы должны сначала сосредоточиться на правильности, а не на производительности.

Вы второй метод

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);
    }
}
2
Holger 1 Окт 2019 в 11:45