写程序的时候,用多线程,想要实现根据线程中定义的一个权重值,来每次取出一个最小的,来操作。想来,貌似是优先级队列,因此就用PriorityQueue来实现咯
本来想偷懒,可惜写完测得时候就出问题了·~~
当然,也许是我对这个类不是很熟造成的疑问:1、PriorityQueue默认的排序是升序还是降序啊?
2、我在用PriorityQueue时,先new了一个实例,
PriorityQueue<TestThread> poolQueue=new PriorityQueue<TestThread>(5);
我想问下,这个对列能够使用自定义的Comparator?
3、我在向这个poolQueue中添加元素的时候~~~直接用的offer,所有new的TestThread的优先级初始都是一样的~~
可是我在offer第二个对象的时候就报错了·~~~
Exception in thread "main" java.lang.ClassCastException: TestThread cannot be cast to java.lang.Comparable
at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:595)
at java.util.PriorityQueue.siftUp(PriorityQueue.java:591)
at java.util.PriorityQueue.offer(PriorityQueue.java:291)
at cn.gov.cma.ncc.dcmpp.dispatch.server.util.PrioritySortUtil.main(PrioritySortUtil.java:58)
这错貌似是因为不能对对象直接排序,默认的Comparator不支持。第一次用这玩意·~~不太会,在此开贴求教!!
本来想偷懒,可惜写完测得时候就出问题了·~~
当然,也许是我对这个类不是很熟造成的疑问:1、PriorityQueue默认的排序是升序还是降序啊?
2、我在用PriorityQueue时,先new了一个实例,
PriorityQueue<TestThread> poolQueue=new PriorityQueue<TestThread>(5);
我想问下,这个对列能够使用自定义的Comparator?
3、我在向这个poolQueue中添加元素的时候~~~直接用的offer,所有new的TestThread的优先级初始都是一样的~~
可是我在offer第二个对象的时候就报错了·~~~
Exception in thread "main" java.lang.ClassCastException: TestThread cannot be cast to java.lang.Comparable
at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:595)
at java.util.PriorityQueue.siftUp(PriorityQueue.java:591)
at java.util.PriorityQueue.offer(PriorityQueue.java:291)
at cn.gov.cma.ncc.dcmpp.dispatch.server.util.PrioritySortUtil.main(PrioritySortUtil.java:58)
这错貌似是因为不能对对象直接排序,默认的Comparator不支持。第一次用这玩意·~~不太会,在此开贴求教!!
解决方案 »
- 如何将jre 和 一个swing 应用程序打包成一个 EXE 文件,这个EXE不是安装的,是双击EXE然后,就能运行swing
- 有人编过java作函数图像的小应用程序吗?
- 有了解软通动力的没?
- 线程的run()方法执行完毕后该如何重新start()?
- 有关ResultSet中的refreshRow()问题
- JAVA连接数据库
- 求点拨一个Java Swing的问题.
- 请问各位大哥﹐谁可以提供thinking in java 3rd edition & core java I,II的电子书或者是下载网址给我?
- 谢谢大家对我的帮助~!真的很感激
- 请教大家一些关于java se的基础问题
- RCP 如何在一个Editor添加一个按钮关闭这个Editor
- 面试题,用Java实现二叉树
2、可以,new PriorityQueue(5, new MyComparator());
3、因为你的对象没有实现Comparable或者传入Comparator
那个优先级队列是不是只能对线程使用啊?如果我在一个线程中定义了一个int值weight,这个值在该线程的运行过程中会不断地改变,
我循环new这个线程,并把它加入优先级队列队列指定Comparator为SortUtil编写的那个SortUtil主体代码为
int compare(MyThread fst,MyThread scd){
//这里简单表示了一下~~
return (fst.getWeight()>=scd.getWeight)?1:-1
} 这个comparator我在单独测试的时候,用Collections.sort(arrList,new SortUtil())排序
是可以使用的·~~这样,我直接使用这个优先级队列·~·它能够根据我提供的对weight进行排序的筛选操作么?
这个队列每次追加对象的时候是用offer呢,还是用add啊?看了API我自己觉得add只是加到文件尾,不会自己排序,offer是插入~~~
可是在调用offer的是后形参对象应该用哪个?我是直接offer(MyThread),结果就是报错的·~我感觉这个地方我写的不对~~~应该怎么处理啊?
先谢谢你拉·~
你说,队列指定Comparator为SortUtil,我不知道你怎么写的。
PriorityQueue<MyThread> q = new PriorityQueue<MyThread>(10, new Comparator<MyThread>() { public int compare(MyThread o1, MyThread o2) {
return o1.weight - o2.weight;
}
});
q.offer(new MyThread(5));
q.offer(new MyThread(7));
q.offer(new MyThread(2));
q.offer(new MyThread(6));
q.offer(new MyThread(8));
System.out.println(Arrays.toString(q.toArray()));
public static class MyThread {
private int weight;
public MyThread(int weight) {
this.weight = weight;
}
public String toString() {
return getClass().getSimpleName() + ":" + weight;
}
}
这个是很正常的。不会有异常。add和offer方法是一样的,没有任何区别。
* MAX:按照优先级从大到小排列
* MIN:按照优先级从小到大排列(默认)
*/
public final static int MAX=-1;
public final static int MIN=1;
private int stat=0;
public SortUtil(){}
public SortUtil(int status){
stat=status;
}
public int compare(MyThread fst, MyThread scd) {
int ans = 0;
if (stat==MAX) {//从大到小
if (fst.getWeight()<=scd.getWeight()) {
return 1;
}else {
return -1;
}
}else if(stat==MIN||stat==0) {//从小到大
if (fst.getWeight()>=scd.getWeight()) {
return 1;
}else {
return -1;
}
}else {//模式选择错误
System.out.println("模式选择错误!");
System.exit(-2);
}
return ans;
}
/**
* @param args
*/
public static void main(String[] args) {
//这段main函数里的是刚写的~~还没测~~~~
PriorityQueue<MyThread> pQueue=new PriorityQueue<MyThread>(5,new SortUtil());
for(int i=0;i<5;i++){
MyThread myT=new MyThread();
myT.start();
pQueue.offer(myT);
}
System.out.println(Arrays.toString(pQueue.toArray()));
}
}
这个是我写的MyThread里的run方法~~~~public void run() {
Calendar cur;
long n;
try {
while (true) {
cur=Calendar.getInstance();
n=cur.getTimeInMillis()/1000;
if (n%2==0) {
weight--;
}else {
weight++;
}
Thread.sleep(n);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这个队列会自动排序么?/**
* @param args
*/
public static void main(String[] args) {
int cnt=0;
PriorityQueue<TaskThread> pQueue=new PriorityQueue<TaskThread>(5,new CopyOfSortUtil());
for(int i=0;i<5;i++){
TaskThread myT=new TaskThread();
myT.start();
pQueue.offer(myT);
}
System.out.println(Arrays.toString(pQueue.toArray()));
try {
while (cnt<5) {
while (!pQueue.isEmpty()) {
Thread.sleep(1000L);
TaskThread taskThread = pQueue.peek();
System.out.println(taskThread.getWeight());
}
cnt++;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
应该改为n=cur.getTimeInMillis()%1000;现在问题是~~~貌似队列里面没有自动排序啊·~~要不就是我的测试方法还是不对
(测试方法里面的TaskThread等同其他地方的MyThread)
pq.add("dog");
pq.add("apple");
pq.add("fox");
pq.add("easy");
pq.add("boy");
//
while(!pq.isEmpty()){
for(String s:pq){
System.out.print(s+" ");
}
System.out.println();
System.out.println("Priority.poll() : "+pq.poll());
}
结果:apple boy fox easy dog
Priority.poll() : apple
boy dog fox easy
Priority.poll() : boy
dog easy fox
Priority.poll() : dog
easy fox
Priority.poll() : easy
fox
Priority.poll() : fox
从这段代码可以看出,第一个元素都是最小的,而每次取出一个数据的时候,后面几个元素都是变化的,而它们变化的规则就是根据二叉树的形式操作的(ps:具体的可以看看二叉树的相关知识)
也就是说·~在poll首个元素的时候~~pq才会根据二叉树重构对么?因为我的pq是在for循环里面添加元素的·~~
如果是 我倒序添加~~那会是什么情况呢?
堆的话·~不是可以指定排序规范么?to bao110908 恩·~不过这个队列不是共享队列~~~只被一个线程持有~~~只不过·~~这个队列里存的是着多个线程的属性值~~~