在 Java 中为优先级队列实现自定义比较器的问题
Issue with implementing custom Comparator for Priority Queue in Java
请原谅我对 Java.
中优先队列和比较器的理解
看来,我能够根据某种排序顺序为优先级队列实现基本比较器。
但我无法为以下场景想出一些办法:
1. Given a list of Files with name convention xx_yy_zz.dat .<br/>
2.xx,yy,zz can be from 00-50 <br/>
3.I need to process the files with xx=30 first,xx=35 second xx=40 third and then the rest.<br/>
由于我对优先级队列的了解有限,我尝试实现它,我能够对其进行排序,但只能在 xx 的 asc 或 desc 值中进行排序,这不是要求。
我的方法是
put the list of file names in priority Queue ,split the filename on regex "_"
then compare the first index of split array using comparator based on it values but as expected i failed miserably since my requirement was something different
请分享一些 ideas/approach。
很遗憾,我无法为我的案例提供所需的比较器。
不过谢谢大家的期待
可能是我不明白你到底需要什么...但只要试试这段代码,它就会对所有字符串进行排序,如果它们的开头有两位数字的话
public static void main(String[] args) {
PriorityQueue<String> q = new PriorityQueue<String>((first, second) -> {
return Integer.parseInt(first.substring(0, 2)) - Integer.parseInt(second.substring(0, 2));
//and if you want to reverse order, simply add "-" like this:
//return -(Integer.parseInt(first.substring(0, 2)) - Integer.parseInt(second.substring(0, 2)));
});
q.add("23lk");
q.add("22lkjl");
q.add("45ljl");
for(String str : q) {
System.out.println(str);
}
}
}
广告输出
22lkjl
23lk
45ljl
如果这不是解决方案,请详细说明问题,也许我或其他人会帮助您。
您可以在 compare()
方法中使用简单的 if
语句来检查一个字符串是否以 "30"
开头而另一个字符串不是。然后你知道这个字符串必须在另一个之前。您 运行 在文件名的第一部分使用如下 if
语句:
- 它们一样吗?
- 左边是
30
吗?
- 是对的吗
30
?
- 左边是
35
吗?
- 是对的
35
吗?
- 左边是
40
吗?
- 是对的
40
吗?
比较器可能如下所示:
public int compare(String a, String b) {
String[] splitA = a.split("_");
String[] splitB = b.split("_");
if (splitA[0].equals(splitB[0])) {
return 0;
}
if (splitA[0].equals("30")) {
return -1;
}
if (splitB[0].equals("30")) {
return 1;
}
if (splitA[0].equals("35")) {
return -1;
}
if (splitB[0].equals("35")) {
return 1;
}
if (splitA[0].equals("40")) {
return -1;
}
if (splitB[0].equals("40")) {
return 1;
}
return 0;
}
使用以下测试源码:
System.out.println(Arrays.toString(data));
Arrays.sort(data, new SpecialComparator());
System.out.println(Arrays.toString(data));
您可能会得到这样的输出(取决于 data
数组):
[30_45_35.dat, 00_12_34.dat, 35_50_20.dat, 40_03_05.dat, 33_28_14.dat,
30_16_31.dat, 20_29_23.dat, 24_41_29.dat, 30_49_18.dat, 40_12_13.dat]
[30_45_35.dat, 30_16_31.dat, 30_49_18.dat, 35_50_20.dat, 40_03_05.dat,
40_12_13.dat, 00_12_34.dat, 33_28_14.dat, 20_29_23.dat, 24_41_29.dat]
(为清楚起见添加了新行)
如您所见,首先是 30
,然后是唯一的 35
,然后是第三个 40
,然后是所有剩余的内容。您可能希望在字符串上使用 compareTo()
以防 compareTo
方法 return 0
以获得更好的字符串“子排序”,这将基于此上面的基本排序。
请原谅我对 Java.
中优先队列和比较器的理解 看来,我能够根据某种排序顺序为优先级队列实现基本比较器。
但我无法为以下场景想出一些办法:
1. Given a list of Files with name convention xx_yy_zz.dat .<br/>
2.xx,yy,zz can be from 00-50 <br/>
3.I need to process the files with xx=30 first,xx=35 second xx=40 third and then the rest.<br/>
由于我对优先级队列的了解有限,我尝试实现它,我能够对其进行排序,但只能在 xx 的 asc 或 desc 值中进行排序,这不是要求。
我的方法是
put the list of file names in priority Queue ,split the filename on regex "_" then compare the first index of split array using comparator based on it values but as expected i failed miserably since my requirement was something different
请分享一些 ideas/approach。
很遗憾,我无法为我的案例提供所需的比较器。
不过谢谢大家的期待
可能是我不明白你到底需要什么...但只要试试这段代码,它就会对所有字符串进行排序,如果它们的开头有两位数字的话
public static void main(String[] args) {
PriorityQueue<String> q = new PriorityQueue<String>((first, second) -> {
return Integer.parseInt(first.substring(0, 2)) - Integer.parseInt(second.substring(0, 2));
//and if you want to reverse order, simply add "-" like this:
//return -(Integer.parseInt(first.substring(0, 2)) - Integer.parseInt(second.substring(0, 2)));
});
q.add("23lk");
q.add("22lkjl");
q.add("45ljl");
for(String str : q) {
System.out.println(str);
}
}
}
广告输出
22lkjl
23lk
45ljl
如果这不是解决方案,请详细说明问题,也许我或其他人会帮助您。
您可以在 compare()
方法中使用简单的 if
语句来检查一个字符串是否以 "30"
开头而另一个字符串不是。然后你知道这个字符串必须在另一个之前。您 运行 在文件名的第一部分使用如下 if
语句:
- 它们一样吗?
- 左边是
30
吗? - 是对的吗
30
? - 左边是
35
吗? - 是对的
35
吗? - 左边是
40
吗? - 是对的
40
吗?
比较器可能如下所示:
public int compare(String a, String b) {
String[] splitA = a.split("_");
String[] splitB = b.split("_");
if (splitA[0].equals(splitB[0])) {
return 0;
}
if (splitA[0].equals("30")) {
return -1;
}
if (splitB[0].equals("30")) {
return 1;
}
if (splitA[0].equals("35")) {
return -1;
}
if (splitB[0].equals("35")) {
return 1;
}
if (splitA[0].equals("40")) {
return -1;
}
if (splitB[0].equals("40")) {
return 1;
}
return 0;
}
使用以下测试源码:
System.out.println(Arrays.toString(data));
Arrays.sort(data, new SpecialComparator());
System.out.println(Arrays.toString(data));
您可能会得到这样的输出(取决于 data
数组):
[30_45_35.dat, 00_12_34.dat, 35_50_20.dat, 40_03_05.dat, 33_28_14.dat,
30_16_31.dat, 20_29_23.dat, 24_41_29.dat, 30_49_18.dat, 40_12_13.dat]
[30_45_35.dat, 30_16_31.dat, 30_49_18.dat, 35_50_20.dat, 40_03_05.dat,
40_12_13.dat, 00_12_34.dat, 33_28_14.dat, 20_29_23.dat, 24_41_29.dat]
(为清楚起见添加了新行)
如您所见,首先是 30
,然后是唯一的 35
,然后是第三个 40
,然后是所有剩余的内容。您可能希望在字符串上使用 compareTo()
以防 compareTo
方法 return 0
以获得更好的字符串“子排序”,这将基于此上面的基本排序。