为优先级较高的元素和其他优先级较低的元素排序优先队列
我有一个包含以下字段的实体类:id,orderNo。每个 实体必须存储在一个java优先级队列中。 id在1至3000之间的元素 具有更高的优先级,并且必须以 的升序存储,不存在于id> 3000的元素之上。具有> 3000的元素的元素 以高于优先级元素 的orderNo的升序存储与ids 1 - 3000)。为优先级较高的元素和其他优先级较低的元素排序优先队列
如:
(1st insertion to queue: id=4000 orderNo=1)
(2nd insertion to queue: id=5000 orderNo=2)
(3rd insertion to queue: id=100 orderNo=3)
(4th insertion to queue: id=50 orderNo=4)
预期排序顺序:
(id=100 orderNo=3)
(id=50 orderNo=4)
(id=4000 orderNo=1)
(id=5000 orderNo=2)
OrderEntity类:
public class OrderEntity implements Comparable<OrderEntity> {
private int id;
private int getOrderNo;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getOrderNo() {
return getOrderNo;
}
public void setOrderNo(int getOrderNo) {
this.getOrderNo = getOrderNo;
}
@Override
public int compareTo(OrderEntity arg0) {
if ((this.getId() >= 1 && this.getId() <= 3000) && (arg0.getId() >= 1 && arg0.getId() <= 3000)) {
if (this.getOrderNo() > arg0.getOrderNo()) {
return 1;
} else {
return 0;
}
} else if ((this.getId() <= 3000) && (arg0.getId() > 3000)) {
return 1;
} else if ((this.getId() > 3000) && (arg0.getId() <= 3000)) {
return 1;
} else if ((this.getId() > 3000) && (arg0.getId() > 3000)) {
if (this.getOrderNo() > arg0.getOrderNo()) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
}
订单处理器类:
public class OrderProcessor {
private static int count;
static Queue<OrderEntity> pq = new PriorityQueue<>();
public String createOrder(int id) {
OrderEntity orderEntity = new OrderEntity();
orderEntity.setId(id);
count = count + 1;
orderEntity.setOrderNo(count);
pq.add(orderEntity);
String res = "";
for (OrderEntity rd : pq) {
res = res + rd.getId() + " " + rd.getOrderNo() + "\n";
}
return res.trim();
}
}
在这种情况下,物体的自然排序与您的特殊要求不同,最好不要使用Comparable
,因为它可能在将来有其他用途。因此,剩下的解决方案是使用Comparator
,这很适合您的问题,因为您的OrderEntity
类不会依赖于此特殊比较。以下是显示解决方案的示例代码:
import java.util.Comparator;
import java.util.PriorityQueue;
public class OrderProcessor {
public static void main(String[] args) {
PriorityQueue<OrderEntity> q = new PriorityQueue<>(new OrderEntityComparator());
q.add(new OrderEntity(4000, 1));
q.add(new OrderEntity(5000, 2));
q.add(new OrderEntity(100, 3));
q.add(new OrderEntity(50, 4));
while(!q.isEmpty())
System.out.println(q.poll());
}
public static class OrderEntityComparator implements Comparator<OrderEntity> {
@Override
public int compare(OrderEntity o1, OrderEntity o2) {
if(o1.getId() <= 3000 && o2.getId() <= 3000)
return Integer.compare(o1.getOrderNo(), o2.getOrderNo());
if(o1.getId() > 3000 && o2.getId() > 3000)
return Integer.compare(o1.getOrderNo(), o2.getOrderNo());
if(o1.getId() <= 3000 && o2.getId() > 3000)
return -1;
return 1;
}
}
public static class OrderEntity {
private int id;
private int orderNo;
public OrderEntity(int id, int orderNo) {
this.id = id;
this.orderNo = orderNo;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getOrderNo() {
return orderNo;
}
public void setOrderNo(int orderNo) {
this.orderNo = orderNo;
}
@Override
public String toString() {
return "OrderEntity{" +
"id=" + id +
", orderNo=" + orderNo +
'}';
}
}
}
编辑:
如果你不想通过调用poll
方法删除元素,你必须在一个数组或列表的元素进行排序,这样的事情:
OrderEntity[] a = new OrderEntity[q.size()];
q.toArray(a);
Arrays.sort(a, new OrderEntityComparator());
for(OrderEntity entity : a)
System.out.println(entity);
事实上,在这种情况下,你不需要使用PriorityQueue
和一个简单的排序上的列表或数组将做的工作。
不工作。尝试使用以下输入:(100,1)(200,2)(4000,3)(300,4)。预期产出:(100,1)(200,2)(300,4)(4000,3)。实际输出:(100,1)(200,2)(4000,3)(300,4) –
@AshwinShirva您的预期输出是什么?我的输出是:(100,1)(200,2)(300,4)(4000,3) –
@AshwinShirva我运行了代码,输出与预期相同。你能检查我的代码吗? –
这是一个使用Java 8的解决方案,不需要任何复杂的比较器实现。我反对你提供的两个例子。诀窍是认识到有两组ID,那些< = 3000,以及上面的那些。如果您可以以某种方式对这两组中的数字进行归一化,那么您可以简单地使用规范化ID的自然排序,然后按顺序号自然排序。
public class Main {
private static Comparator<OrderEntity> orderEntityComparator =
Comparator.<OrderEntity, Integer>comparing(OrderEntity::getId,
comparingInt(id -> id/3000)
)
.thenComparingInt(OrderEntity::getOrderNo);
public static void main(String[] args) {
PriorityQueue<OrderEntity> queue = new PriorityQueue<>(orderEntityComparator);
queue.add(new OrderEntity(4000, 1));
queue.add(new OrderEntity(5000, 2));
queue.add(new OrderEntity(100, 3));
queue.add(new OrderEntity(50, 4));
// 100, 50, 4000, 5000
queue.clear();
queue.add(new OrderEntity(100, 1));
queue.add(new OrderEntity(200, 2));
queue.add(new OrderEntity(4000, 3));
queue.add(new OrderEntity(300, 4));
while (!queue.isEmpty()) {
System.out.println(queue.poll());
}
// 100, 200, 300, 4000
}
static class OrderEntity {
private int id;
private int orderNo;
public OrderEntity(int id, int orderNo) {
this.id = id;
this.orderNo = orderNo;
}
public int getId() {
return id;
}
public int getOrderNo() {
return orderNo;
}
@Override
public String toString() {
return String.format("(id=%d, orderNo=%d)", id, orderNo);
}
}
}
而你的问题是......? –
我的问题是,我无法通过上述实现获得此序列。想知道我出错的地方。 –
一个问题是你的'compareTo'方法,如果第一项不大于第二项,则返回0(意味着相等)。 “compareTo”应该返回-1,0或1,具体取决于第一项是小于,等于还是大于第二项。通常,您使用'Integer.compare'来检查。 –