【问题标题】:Java- Reordering the priority of items in the listJava-重新排序列表中项目的优先级
【发布时间】:2016-03-14 10:08:04
【问题描述】:

我有这样的事情:

    public class TestItem {

        double priority;
        String name;
        String phoneNumber;

        //getter setters
        .
        .
        .

        //action
        public void moveOrder(TestItem before, TestItem after) {

        }
    }

我想通过在所需项目之间拖动列表来实现列表的重新排序。 假设这是我的清单。

    TestItem 1 (priority = 1)
    TestItem 2 (priority = 2)
    TestItem 3 (priority = 3)
    TestItem 4 (priority = 4)
    TestItem 5 (priority = 5)

如果我想在 1 和 2 之间移动 TestItem 4,它会变成这样:

    TestItem 1 (priority = 1)
    TestItem 4 (priority = 1.5)
    TestItem 2 (priority = 2)
    TestItem 3 (priority = 3)

    TestItem 5 (priority = 5)

TestItem 4 的顺序是 1 和 2 的平均值。 我的问题是当我继续重新排序时,订单的价值变小了。

我还不知道如何在达到某个值时进行更正。 也许我应该再次检索所有列表?是否有关于像这样实现的东西的参考?

非常感谢任何建议或参考。

【问题讨论】:

  • 你读过Collections.sort()Comparator 吗? docs.oracle.com/javase/6/docs/api/java/util/…
  • 你说的“订单价值变小”和“当它达到某个值时如何纠正”是什么意思?目前尚不清楚您所描述的内容是“不正确”的。
  • 当最后一项将在循环中移动到位置 1(从 0 开始的索引)时,优先级将是 1.5、1.25、1.125,... 很快就会精确地解决问题。 ..
  • 是的,我就是这个意思。

标签: java reorderlist


【解决方案1】:

如果您正在寻找一种对数组进行排序的方法,则选择排序是一种可行的简单解决方案。 https://en.wikipedia.org/wiki/Selection_sort

只要确保你重新分配优先级,而不是索引

public void moveOrder(TestItem before, TestItem after) {
    this.priority = (before.priority + after.priority) / 2.0;
}

希望这会有所帮助, 肖恩

【讨论】:

    【解决方案2】:

    这取决于你真正想要达到的目标。

    除法和乘法一样糟糕,你会发现它更容易溢出......

    TestItem 1 (priority = 1)
    TestItem 2 (priority = 2)
    TestItem 3 (priority = 3)
    TestItem 4 (priority = 4) // move this between 1 and 2
    TestItem 5 (priority = 5)
    

    如果和是奇数,全部乘以2,就会得到

       TestItem 1 (priority = 2) // *2
    -> TestItem 4 (priority = 3) // (2+4)/2
       TestItem 2 (priority = 4) // *2
       TestItem 3 (priority = 6) // *2
       //TestItem 4 (priority = 4) original position
       TestItem 5 (priority = 10) // *2
    

    但是您需要访问列表中的所有项目,如果可以这样做,只需为新位置之后的项目增加优先级

       TestItem 1 (priority = 1)
    -> TestItem 4 (priority = 2) // 1 + 1
       TestItem 2 (priority = 3)
       TestItem 3 (priority = 4)
       //TestItem 4 (priority = 4) original position
       TestItem 5 (priority = 5) // prev. priority + 1
    

    【讨论】:

    • 我实际上是在尽量避免访问我列表中的所有项目。并从phabricator's 那里得到了那种实现,但我对他如何纠正它感到困惑。
    • 如果可能的话做一些测试,也许他没有;-) 你的列表中的预期项目数是多少?如果是 1000 秒,我不会太在意 ;-)
    • 不好,因为移动次数受限于 2 的幂,适合优先级类型 -double,因此在最坏的情况下最多可以支持 32 次移动。
    【解决方案3】:

    我会使用Priority Queue 及其removeadd 方法。

    编辑

    如果您需要在任何时间点保留对特定元素的引用,那么将电话号码作为键的Hashmap 并将对相应优先级队列元素的引用作为值将起到神奇的作用.当您需要重新排序时,您从 UI 中选择 3 个元素(我猜),然后通过 Hashmap 查找在 O(1) 中找到它们,最后,您拥有所需的所有优先级。您将需要修改要移动的元素的优先级。您无需担心更新 HashMap 中的引用 - 它会一直更新。

    示例: List=x,y,z 您需要在 y 和 z 之间移动 x,因此列表看起来像 y,x,z。 您可以通过使用他们的电话号码进行 Hashmap 查找来找到 x、y 和 z。那么 x 的新优先级为:

    p(x)=p(z)-p(y)/2.0

    我假设所有优先级都是积极的doubles。现在您的“列表”已重新排序。

    祝你好运!

    【讨论】:

    • 优先队列中没有索引,只有最小/最大元素,你想如何将元素移动到第三个位置?
    • 按优先级。如果要在列表中的 y 和 z 之间移动 x,则 p(x)=p(z)-p(y)/2.0
    • 你不需要基于问题。你只需要知道优先级。
    • 哦,来吧,你不需要的问题,因为它在列表中很简单,但是如果你说“让我们使用优先队列”,你也必须解决这个问题......
    • '来吧'什么?我不明白你在说什么。
    猜你喜欢
    • 2014-08-05
    • 2021-10-05
    • 2014-01-04
    • 1970-01-01
    • 2012-02-24
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    相关资源
    最近更新 更多