使用带有自定义比较器的 reverseOrder() 按降序对列表进行排序?
Sorting a List in descending order using reverseOrder() with custom Comparator?
我有以下 Supplier
类型的对象列表,我想使用 reverseOrder()
方法对它们进行排序(因此它们将按降序排列)。但是,在互联网上阅读了一整天之后,我仍然无法正常工作。我很确定这是我在这里缺少的非常小的东西。升序的自然顺序就可以了。
这是我的 Supplier
class:
public class Supplier {
private String supplierName = "";
private String representative = "";
private String representativesPhoneNumber = "";
private Map<Drug, Integer> listOfDrugs = new HashMap<Drug, Integer>();
Supplier(String n, String rep, String repPhoneNum, String drugName, double drugPrice, int stock) {
this.supplierName = n;
this.representative = rep;
this.representativesPhoneNumber = repPhoneNum;
listOfDrugs.put(new Drug(drugName, drugPrice), stock);
}
public Map<Drug, Integer> getListOfDrugs() {
return this.listOfDrugs;
}
public static Integer getKeyExtractor(Supplier supplier, Drug drug) {
return Optional.ofNullable(Optional.ofNullable(supplier.getListOfDrugs())
.orElseThrow(() -> new IllegalArgumentException("drugs is null")).get(drug))
.orElseThrow(() -> new IllegalArgumentException("the drug couldn't be found"));
}
}
它有一个 Map
如果对象 <Drug, Integer>
。
这是我的 Drug
class:
public class Drug {
private String name = "";
private double price = 0.0;
Drug(String n, double p) {
this.name = n;
this.price = p;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(price);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Drug other = (Drug) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
return false;
return true;
}
}
为了防止垃圾邮件,大部分代码都被删减了。 :)
还有我的 Orders
class,我实际上在其中进行排序:
public class Orders {
private Map <Drug, Integer> orderedDrugs = new HashMap <Drug, Integer>();
private Vector<Supplier> suppliers = new Vector <Supplier>();
public void sort(Drug drug, List<Supplier> sortedSuppliers) {
Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder()));
}
public List<Supplier> getSortedSuppliersByQuantity(Drug drug) {
List <Supplier> sortedSuppliers = new ArrayList <Supplier>();
for(Supplier s : suppliers) {
for(Entry<Drug, Integer> entry : s.getListOfDrugs().entrySet()) {
if(entry.getKey().getDrugsName().equals(drug.getDrugsName()));
sortedSuppliers.add(s);
}
}
sort(drug, sortedSuppliers);
return sortedSuppliers;
}
}
再次精简代码,只显示实际问题所需的方法。
到目前为止我已经尝试过:
Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder()));
Collections.sort(suppliers, Collections.reverseOrder(Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug))));
但两者都不起作用。我需要在某处实施 compareTo()
还是我缺少某些方法?由于升序有效,但降序无效。
使用 Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug)));
将它们按升序排序并起作用。
提前感谢您的帮助,久违了post!
更新:
我也尝试在 Supplier
class 中实现 compareTo
,但我得到了 NPE。 :/
public int compareTo(Supplier a) {
for(Entry<Drug, Integer> entry : listOfDrugs.entrySet()) {
int result = listOfDrugs.get(entry.getKey()).compareTo(a.listOfDrugs.get(entry.getKey()));
if(result != 0)
return result;
}
return 0;
}
是的,你需要。实施 Comparator (and tweak it as required), and invoke the sort 方法。
更新:
要使用 lambda 表达式执行此操作,请尝试 here.
更新#2:
以下是我想出的。希望对您有所帮助:
/**
Input:[9, 9, 5, 1, 6, 3, 9, 4, 7, 1]
Reversed:[1, 7, 4, 9, 3, 6, 1, 5, 9, 9]
ReverseOrdered:[9, 9, 9, 7, 6, 5, 4, 3, 1, 1]
*/
private static void testCollectionsSort() {
List<Integer> integerList = new ArrayList<>();
int size=10;
Random random = new Random();
for(int i=0;i<size;i++) {
integerList.add(random.nextInt(size));
}
System.out.println("Input:"+integerList);
List<Integer> integerListTwo = new ArrayList<>(integerList);
Collections.reverse(integerListTwo);
System.out.println("Reversed:"+integerListTwo);
Comparator<Integer> integerComparator = (Integer a, Integer b) -> b.compareTo(a); // 'b' is compared to 'a' to enable reverse
Collections.sort(integerList, integerComparator);
System.out.println("ReverseOrdered:"+integerList);
}
尝试
Collections.sort(suppliers,
Comparator.comparing((Supplier s) -> Supplier.getKeyExtractor(s, drug)).reversed());
我构建了一个简化的版本并且这很有效。我没有和你一起试过Supplier
,等等类。
好的,我找到了解决该问题的方法,因为其他所有方法都不适合我。在我使用 sort
方法按升序对列表进行排序后,我只需调用:Collections.reverse(myList);
并按降序获得排序后的列表。我知道这可能很蹩脚,但对我有用。
我有以下 Supplier
类型的对象列表,我想使用 reverseOrder()
方法对它们进行排序(因此它们将按降序排列)。但是,在互联网上阅读了一整天之后,我仍然无法正常工作。我很确定这是我在这里缺少的非常小的东西。升序的自然顺序就可以了。
这是我的 Supplier
class:
public class Supplier {
private String supplierName = "";
private String representative = "";
private String representativesPhoneNumber = "";
private Map<Drug, Integer> listOfDrugs = new HashMap<Drug, Integer>();
Supplier(String n, String rep, String repPhoneNum, String drugName, double drugPrice, int stock) {
this.supplierName = n;
this.representative = rep;
this.representativesPhoneNumber = repPhoneNum;
listOfDrugs.put(new Drug(drugName, drugPrice), stock);
}
public Map<Drug, Integer> getListOfDrugs() {
return this.listOfDrugs;
}
public static Integer getKeyExtractor(Supplier supplier, Drug drug) {
return Optional.ofNullable(Optional.ofNullable(supplier.getListOfDrugs())
.orElseThrow(() -> new IllegalArgumentException("drugs is null")).get(drug))
.orElseThrow(() -> new IllegalArgumentException("the drug couldn't be found"));
}
}
它有一个 Map
如果对象 <Drug, Integer>
。
这是我的 Drug
class:
public class Drug {
private String name = "";
private double price = 0.0;
Drug(String n, double p) {
this.name = n;
this.price = p;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(price);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Drug other = (Drug) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
return false;
return true;
}
}
为了防止垃圾邮件,大部分代码都被删减了。 :)
还有我的 Orders
class,我实际上在其中进行排序:
public class Orders {
private Map <Drug, Integer> orderedDrugs = new HashMap <Drug, Integer>();
private Vector<Supplier> suppliers = new Vector <Supplier>();
public void sort(Drug drug, List<Supplier> sortedSuppliers) {
Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder()));
}
public List<Supplier> getSortedSuppliersByQuantity(Drug drug) {
List <Supplier> sortedSuppliers = new ArrayList <Supplier>();
for(Supplier s : suppliers) {
for(Entry<Drug, Integer> entry : s.getListOfDrugs().entrySet()) {
if(entry.getKey().getDrugsName().equals(drug.getDrugsName()));
sortedSuppliers.add(s);
}
}
sort(drug, sortedSuppliers);
return sortedSuppliers;
}
}
再次精简代码,只显示实际问题所需的方法。
到目前为止我已经尝试过:
Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder()));
Collections.sort(suppliers, Collections.reverseOrder(Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug))));
但两者都不起作用。我需要在某处实施 compareTo()
还是我缺少某些方法?由于升序有效,但降序无效。
使用 Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug)));
将它们按升序排序并起作用。
提前感谢您的帮助,久违了post!
更新:
我也尝试在 Supplier
class 中实现 compareTo
,但我得到了 NPE。 :/
public int compareTo(Supplier a) {
for(Entry<Drug, Integer> entry : listOfDrugs.entrySet()) {
int result = listOfDrugs.get(entry.getKey()).compareTo(a.listOfDrugs.get(entry.getKey()));
if(result != 0)
return result;
}
return 0;
}
是的,你需要。实施 Comparator (and tweak it as required), and invoke the sort 方法。
更新: 要使用 lambda 表达式执行此操作,请尝试 here.
更新#2:
以下是我想出的。希望对您有所帮助:
/**
Input:[9, 9, 5, 1, 6, 3, 9, 4, 7, 1]
Reversed:[1, 7, 4, 9, 3, 6, 1, 5, 9, 9]
ReverseOrdered:[9, 9, 9, 7, 6, 5, 4, 3, 1, 1]
*/
private static void testCollectionsSort() {
List<Integer> integerList = new ArrayList<>();
int size=10;
Random random = new Random();
for(int i=0;i<size;i++) {
integerList.add(random.nextInt(size));
}
System.out.println("Input:"+integerList);
List<Integer> integerListTwo = new ArrayList<>(integerList);
Collections.reverse(integerListTwo);
System.out.println("Reversed:"+integerListTwo);
Comparator<Integer> integerComparator = (Integer a, Integer b) -> b.compareTo(a); // 'b' is compared to 'a' to enable reverse
Collections.sort(integerList, integerComparator);
System.out.println("ReverseOrdered:"+integerList);
}
尝试
Collections.sort(suppliers,
Comparator.comparing((Supplier s) -> Supplier.getKeyExtractor(s, drug)).reversed());
我构建了一个简化的版本并且这很有效。我没有和你一起试过Supplier
,等等类。
好的,我找到了解决该问题的方法,因为其他所有方法都不适合我。在我使用 sort
方法按升序对列表进行排序后,我只需调用:Collections.reverse(myList);
并按降序获得排序后的列表。我知道这可能很蹩脚,但对我有用。