【问题标题】:Java - position of first element satisfying a predicateJava - 满足谓词的第一个元素的位置
【发布时间】:2015-01-29 18:54:01
【问题描述】:

我正在编写一个有序队列。在顶部有高优先级的元素,从最旧的 最新的排序。中间部分中优先级元素和底部低优先级元素部分相同。

当我想对一个新元素进行排序时,我通常可以参考列表的最后一个元素。如果最后一个元素具有更高或相同的优先级,我的新元素将被放置在所有元素之后。

现在,在最后一个元素的优先级低于我的新元素的情况下,我必须找到一种方法来遍历列表并找到谓词“优先级低于新元素的第一个元素"适用。那么我的新元素应该在那个位置。

我正在使用 compareTo 来比较两个元素。

我是一个完全的初学者,我很难找到解决这个问题的方法。

非常感谢每一个帮助。

提前谢谢你

我尝试了类似的方法:

public Queue<T> queue;

public OrderedQueue() {
    queue = new LinkedList<T>();
}

public void enqueue(T newitem) {
    int sss;
    if (isEmpty()) {
        ((LinkedList<T>) queue).add(newitem);
    }
    else if (newitem instanceof BulkParcel) {
        ((LinkedList<T>) queue).addLast(newitem);
    }
    else if (newitem instanceof StandardParcel || newitem instanceof PriorityParcel) {
            if (newitem.compareTo(((LinkedList<T>) queue).getLast()) == 0) {
                ((LinkedList<T>) queue).addLast(newitem);
            }
            else if (newitem.compareTo(((LinkedList<T>) queue).getLast()) < 0) {
                ((LinkedList<T>) queue).addLast(newitem);
            }
            else
                for (Iterator<T> it = queue.iterator(); it.hasNext();) {
                sss = newitem.compareTo(it.next());
                ((LinkedList<T>) queue).add((((LinkedList<T>) queue).indexOf(sss==-1)), newitem);
                }
    }
}

我能够完成我想要的。 这是我的新代码,供所有仍然感兴趣的人使用。

public void enqueue(T newitem) {
    int pos = -1;
    int compVal = 2;
    if (isEmpty()) {
        ((LinkedList<T>) queue).add(newitem);
    }
    else if (newitem.compareTo(((LinkedList<T>) queue).getLast()) == 0 
            || newitem.compareTo(((LinkedList<T>) queue).getLast()) < 0) {
            ((LinkedList<T>) queue).addLast(newitem);
    }
    else {
            for (Iterator<T> it = queue.iterator(); it.hasNext() && compVal != 1;) {
                compVal = newitem.compareTo(it.next());
                pos = pos + 1;
            }
        ((LinkedList<T>) queue).add(pos, newitem);
    }

}

我有一个自写的方法“compareTo”,对于 a.compareTo(b);,如果 a 小于 b(这里将是优先级),则返回 -1,如果它们相等则返回 0,并且如果 a 大于 b,则为 1。

感谢所有帮助和详细解答! :)

【问题讨论】:

  • 您的回复似乎不适合 cmets,请将其添加到原始问题中?
  • 在您的问题下使用edit 选项添加新信息。无法在注释中正确格式化代码。
  • 另外,这是学校的问题吗?如果是这样,问题需要特殊处理,我们需要问题的文本。
  • 这正是@MeetTitan 所说的LinkedHashMap,它是HashMap+LinkedList 的组合。您可以查看文档。

标签: java list queue predicate


【解决方案1】:

您正在查看插入排序。它几乎肯定在你的教科书中有所描述......虽然你已经明白了。


Queue 表示特定的东西;它用于将元素放入并让队列决定将它们放在哪里。 (例如在列表的末尾)。由于您想在特定位置插入,因此您需要List。如果您不想重复,则需要OrderedSet。将字段声明为最合适的字段并避免强制转换。

在任何情况下,您都应注意确保您使用的图书馆馆藏不会绕开您的教师设定的学习目标。

根据讲师对您的要求,您可以使用其中的一种,只需几行代码即可完成。或者它们可能都被禁止,你必须自己破解它。找出答案!


我有一些建议可以让您更轻松地理解自己的代码。例如,采取这一行:

if (newitem.compareTo(((LinkedList<T>) queue).getLast()) == 0) {

相同
if (lastItemIsEqualTo(newItem)) {

如果添加以下辅助方法

private boolean lastItemIsEqualTo(T newItem) {
     return newItem.compareTo(((LinkedList<T>) queue).getLast()) == 0;
}

向前推进,您可能会得到:

        if (lastItemIsEqualTo(newItem)) {
            stuff...
        }
        else if (lastItemIsLessThan(newItem) {
            stuff...
        }
        else for (Iterator<T> it = queue.iterator(); it.hasNext();) {
            otherStuff...
        }

相当于:

        if (lastItemIsLessThanOrEqualTo(newItem)) {
            stuff...
        }
        else for (Iterator<T> it = queue.iterator(); it.hasNext();) {
            otherStuff...
        }

但你也可以用 if 语句说出你真正想要完成的事情:

        if (entireListComesBefore(newItem)) {
            stuff...
        }
        else for (Iterator<T> it = queue.iterator(); it.hasNext();) {
            otherStuff...
        }

StandardParcelBulkParcel。有必要上两节课吗?例如,如果 BulkParcelStandardParcel 相同,只有一个项目,您可以只使用 Parcel,但有如下内容:

public boolean isABulkParcel() {
    return parcel.size() > 1;
}

并且具有对两者都通用的算法。那么你就不需要instanceofinstanceof 的用途很少,没有更好的解决方案。


sss = newitem.compareTo(it.next());
queue.add(queue.indexOf(sss==-1), newitem);

sss 毫无意义。您在这里有一个逻辑错误,如果您的变量名称更有意义,您会很快看到它。看:

boolean newItemGoesBeforeNextItem = newitem.compareTo(it.next()) == -1;
queue.add(queue.indexOf(newItemGoesBeforeNextItem), newitem);

现在你看到最后一行的问题了吗?那是boolean,而不是数字索引。它会自动转换为对象Boolean(注意大写)。因此它尝试在列表中搜索该布尔对象,但从未找到它。它基本上是这样做的:

queue.indexOf(new Boolean(sss == 1))

这真是一件大事。如果你不明白,花点时间仔细看一下。

【讨论】:

    【解决方案2】:

    您的代码中有很多错误,我建议您在解决此问题之前先修复:

    1. 为什么你不断地将queue 转换为LinkedList?无论如何,您调用的许多方法都是为Queue 实现的。但如果您特别需要 List 方法,则应将其声明为 List
    2. queue 应该是 private
    3. instanceof 通常表明你的类结构有问题。在您的情况下,您几乎可以肯定地使用名为 Parcel 的抽象类或接口声明您的类和队列,其中各种包是实现或扩展。
    4. 您的比较器应该是Parcel 的自然顺序(即实例本身实现compareTo),或者您应该实现自己的比较器来封装您的优先级定义。它不应该嵌入到您的 enqueue 方法中。例如,如果包裹的优先级发生变化会发生什么?理想情况下,您希望能够使用已定义的比较器。
    5. Java 中有自然排序的集合类。实现比较器后,最简单的解决方案是将其中之一与允许您指定自己的比较器的构造函数一起使用。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 2020-05-12
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-23
      相关资源
      最近更新 更多