Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中实现元组的优先级队列,该队列使用两个不同类型的字段进行排序?_Java_Priority Queue_Comparator - Fatal编程技术网

如何在Java中实现元组的优先级队列,该队列使用两个不同类型的字段进行排序?

如何在Java中实现元组的优先级队列,该队列使用两个不同类型的字段进行排序?,java,priority-queue,comparator,Java,Priority Queue,Comparator,我创建了一个名为Thread的类,它有两个字段:int index和long start_time,如下所示: class Thread { public Thread(int index, long start_time) { this.index = index; this.start_time = start_time; } public int index; public long start_time; } Prior

我创建了一个名为Thread的类,它有两个字段:int index和long start_time,如下所示:

class Thread {
    public Thread(int index, long start_time) {
        this.index = index;
        this.start_time = start_time;
    }

    public int index;
    public long start_time;
}
PriorityQueue<Thread> worker = new PriorityQueue<>();
for (int i = 0; i < numWorkers;i++){
            worker.add(new Threads(i , 0));
}  
public int compare(Thread a, Thread b) {
    int c = Long.compare(a.start_time, b.start_time);
    return c == 0
                  ? Integer.compare(a.index, b.index) // compare index, if start_time is the same
                  : c; // if start_times are different, use the result of comparing the 2 fields
}
Comparator<Thread> comparator = Comparator.comparingLong(thread -> thread.start_time)
                                          .thenComparingInt(thread -> thread.index);
之后,我创建了一个线程优先级队列,如下所示:

class Thread {
    public Thread(int index, long start_time) {
        this.index = index;
        this.start_time = start_time;
    }

    public int index;
    public long start_time;
}
PriorityQueue<Thread> worker = new PriorityQueue<>();
for (int i = 0; i < numWorkers;i++){
            worker.add(new Threads(i , 0));
}  
public int compare(Thread a, Thread b) {
    int c = Long.compare(a.start_time, b.start_time);
    return c == 0
                  ? Integer.compare(a.index, b.index) // compare index, if start_time is the same
                  : c; // if start_times are different, use the result of comparing the 2 fields
}
Comparator<Thread> comparator = Comparator.comparingLong(thread -> thread.start_time)
                                          .thenComparingInt(thread -> thread.index);
PriorityQueue worker=new PriorityQueue();
因此,我将为这个队列提供n个线程,这些线程的数目从0到n-1。它们都以0作为开始时间,如下所示:

class Thread {
    public Thread(int index, long start_time) {
        this.index = index;
        this.start_time = start_time;
    }

    public int index;
    public long start_time;
}
PriorityQueue<Thread> worker = new PriorityQueue<>();
for (int i = 0; i < numWorkers;i++){
            worker.add(new Threads(i , 0));
}  
public int compare(Thread a, Thread b) {
    int c = Long.compare(a.start_time, b.start_time);
    return c == 0
                  ? Integer.compare(a.index, b.index) // compare index, if start_time is the same
                  : c; // if start_times are different, use the result of comparing the 2 fields
}
Comparator<Thread> comparator = Comparator.comparingLong(thread -> thread.start_time)
                                          .thenComparingInt(thread -> thread.index);
for(int i=0;i
稍后我会及时添加jobs,假设jobs是{4,3};如果Pqueue有2个元素(0,0)和(1,0),它将变成(0,4)和(1,3),因为poll()将选择0作为优先级(根据索引递增),但下次poll()将首先弹出(1,3),因为3小于4(因此它按开始时间对递增排序,但如果它们相等,则按索引对递增排序)

我只是在学习数据结构,使用Comparable和Comparator,所以这是我第一次使用它,但大多数示例都没有提到元组,或者它们只是按一个字段排序。我的实施理念是:

class threadComparator implements Comparator<Thread> {
    @Override
    public int compare(Thread a, Thread b) {
        if (a.start_time==b.start_time){
            return a.index - b.index;
        }
        return a.start_time - b.start_time;
    }
}
类threadComparator实现Comparator{
@凌驾
公共int比较(线程a、线程b){
如果(a.开始时间==b.开始时间){
返回a.index-b.index;
}
返回a.开始时间-b.开始时间;
}
}
根据我的IDE,我不能使用返回a.start\u time-b.start\u time(不兼容的类型需要int-find long)

我用它作为例子,但那个例子不使用长类型

最后,我应该在哪里包括这个threadComparator以在优先级队列中应用这个排序顺序?我认为:

PriorityQueue<Thread> worker = new PriorityQueue<>(new threadComparator);
PriorityQueue worker=newpriorityqueue(newthreadcomparator);
是这样吗?我应该在threadComparator类中实现比较器,还是仅在Thread类中实现比较器。
请不要吝啬,我已经在谷歌上搜索过了,但我找不到类似的例子。希望我的解释足够清楚。

您的路径基本正确,但对于比较器,您必须返回int值:

  • 如果左侧较小,则为负数
  • 如果它们相等,则为0
  • 如果右侧较小,则为正数
那就换一个吧

return a.start_time - b.start_time;

if(a.开始时间b.开始时间)
返回1;
返回0;

您的路径基本正确,但对于比较器,您必须返回int值:

  • 如果左侧较小,则为负数
  • 如果它们相等,则为0
  • 如果右侧较小,则为正数
那就换一个吧

return a.start_time - b.start_time;

if(a.开始时间b.开始时间)
返回1;
返回0;

2
long
值的减法属于
long
类型,因此无法返回

a.start_time - b.start_time
此外,请注意,如果允许负值

a.index - b.index

可能溢出并返回无效结果

最好像这样实现
比较

class Thread {
    public Thread(int index, long start_time) {
        this.index = index;
        this.start_time = start_time;
    }

    public int index;
    public long start_time;
}
PriorityQueue<Thread> worker = new PriorityQueue<>();
for (int i = 0; i < numWorkers;i++){
            worker.add(new Threads(i , 0));
}  
public int compare(Thread a, Thread b) {
    int c = Long.compare(a.start_time, b.start_time);
    return c == 0
                  ? Integer.compare(a.index, b.index) // compare index, if start_time is the same
                  : c; // if start_times are different, use the result of comparing the 2 fields
}
Comparator<Thread> comparator = Comparator.comparingLong(thread -> thread.start_time)
                                          .thenComparingInt(thread -> thread.index);
在java 8中,您还可以构造一个比较器,如下所示:

class Thread {
    public Thread(int index, long start_time) {
        this.index = index;
        this.start_time = start_time;
    }

    public int index;
    public long start_time;
}
PriorityQueue<Thread> worker = new PriorityQueue<>();
for (int i = 0; i < numWorkers;i++){
            worker.add(new Threads(i , 0));
}  
public int compare(Thread a, Thread b) {
    int c = Long.compare(a.start_time, b.start_time);
    return c == 0
                  ? Integer.compare(a.index, b.index) // compare index, if start_time is the same
                  : c; // if start_times are different, use the result of comparing the 2 fields
}
Comparator<Thread> comparator = Comparator.comparingLong(thread -> thread.start_time)
                                          .thenComparingInt(thread -> thread.index);
Comparator Comparator=Comparator.comparingLong(线程->线程.start\u时间)
.然后比较(线程->线程索引);

2
long
值的减法属于
long
类型,因此无法返回

a.start_time - b.start_time
此外,请注意,如果允许负值

a.index - b.index

可能溢出并返回无效结果

最好像这样实现
比较

class Thread {
    public Thread(int index, long start_time) {
        this.index = index;
        this.start_time = start_time;
    }

    public int index;
    public long start_time;
}
PriorityQueue<Thread> worker = new PriorityQueue<>();
for (int i = 0; i < numWorkers;i++){
            worker.add(new Threads(i , 0));
}  
public int compare(Thread a, Thread b) {
    int c = Long.compare(a.start_time, b.start_time);
    return c == 0
                  ? Integer.compare(a.index, b.index) // compare index, if start_time is the same
                  : c; // if start_times are different, use the result of comparing the 2 fields
}
Comparator<Thread> comparator = Comparator.comparingLong(thread -> thread.start_time)
                                          .thenComparingInt(thread -> thread.index);
在java 8中,您还可以构造一个比较器,如下所示:

class Thread {
    public Thread(int index, long start_time) {
        this.index = index;
        this.start_time = start_time;
    }

    public int index;
    public long start_time;
}
PriorityQueue<Thread> worker = new PriorityQueue<>();
for (int i = 0; i < numWorkers;i++){
            worker.add(new Threads(i , 0));
}  
public int compare(Thread a, Thread b) {
    int c = Long.compare(a.start_time, b.start_time);
    return c == 0
                  ? Integer.compare(a.index, b.index) // compare index, if start_time is the same
                  : c; // if start_times are different, use the result of comparing the 2 fields
}
Comparator<Thread> comparator = Comparator.comparingLong(thread -> thread.start_time)
                                          .thenComparingInt(thread -> thread.index);
Comparator Comparator=Comparator.comparingLong(线程->线程.start\u时间)
.然后比较(线程->线程索引);

我建议不要给你的类命名
线程
,如果这不仅仅是用来学习的代码;虽然它在技术上并不错误,但在更大的代码片段中,它很容易与
java.lang.Thread
混淆。是的,起初我认为它是一个禁止使用的类名称,因为使用Thread进行多线程(我有点不同意)但由于它允许我只在这个练习中使用,但我知道我应该使用其他类的名称,所以在我的练习中,我想不出一个合适的名称,称之为threads。在评论和归档它之前,我会将其更改为Worker。如果这不是用于学习的代码,我建议不要将类命名为
Thread
;虽然它在技术上并不错误,但在更大的代码片段中,它很容易与
java.lang.Thread
混淆。是的,起初我认为它是一个禁止使用的类名称,因为使用Thread进行多线程(我有点不同意)但由于它允许我只在这个练习中使用,但我知道我应该使用其他类的名称,所以在我的练习中,我想不出一个合适的名称,称之为threads。在评论和归档之前,我会将其更改为Worker。我的回答很好,但我无法理解您的回答,除非我阅读了另一个用外行术语解释的答案。我仍然不明白{?Integer.compare(a.index,b.index)}和{:c;}是如何工作的,我还没有学会lambdas。我将保存您的Java 8构造以备以后练习。@Nooblhu:这是一个十进制表达式(请参阅),是if(c==0){return Integer.compare(a.index,b.index);}else{return c;}的一种简短编写形式
在这种情况下,我的答案很好,但我无法理解你的答案,除非我读过另一个用外行术语解释的答案。我仍然不明白{?Integer.compare(a.index,b.index)}和{:c;}是如何工作的,我还没有学会lambdas。我会