【问题标题】:fastest way to insert/update element in the List在列表中插入/更新元素的最快方法
【发布时间】:2019-10-01 07:13:17
【问题描述】:

我想替换提供的列表中的一个对象,或者如果不在此列表中,则添加它。我需要最快的方式来执行此插入/更新。

我有两个版本。哪个更快或者你知道更快的方法吗?

版本 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 流并不比上面的方法快..

【问题讨论】:

  • 为什么不使用Set
  • 因为我必须保留订单。而且我不知道 LinkedHashSet 对于这种情况是否会更好..
  • LinkedHashMap 或 LinkedHashSet,它会保持顺序。列表搜索速度很慢,你需要做一个。
  • 那么update2 方法中的orders 是什么?可能是错字?
  • BinarySearch 比 indexOf() 快在这里检查:stackoverflow.com/questions/32495416/indexof-or-binary-search

标签: java collections java-stream


【解决方案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 &gt;= 0 更改为idx &gt;= -1,因此当没有匹配元素时,代码将尝试更改无效索引-1 处的元素列表。

当您使用idx &gt;= 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);
    }
}

【讨论】:

    猜你喜欢
    • 2017-03-03
    • 2021-05-20
    • 2011-06-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 2019-12-02
    相关资源
    最近更新 更多