您如何按属性对自定义对象的向量进行排序,即其他自定义对象的 Map?

How do you sort a vector of custom objects by attribute, that is a Map of other custom objects?

层次结构如下:

  1. Class 药物 - 它有药物名称和价格。

  2. Class 供应商 - 它拥有 <Drug drug, int quantity>.

  3. 的地图

现在我有一个 Vector<Suppliers>(假设有 5 个供应商),我想按用户输入的药品名称的数量降序排序。

这可能吗?我试过使用比较器,但无法正常工作。

好的,我尝试做的是仅将供应商作为参数药物传递到新的 List 中,然后在列表中执行排序。我认为这是一个很好的解决方法,但我需要以某种方式更改 'sort'。

这是我遍历所有供应商并检查他们是否有药物的方法,如果有 -> 将它们添加到新列表中并尝试最后对其进行排序。

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;
}

问题是我在 sort 行得到 NullPointerException

我认为您建议的 sort 方法需要更改以某种方式作用于新列表而不是旧列表?

@Andrew 的堆栈跟踪

Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Unknown Source)
    at java.util.Optional.<init>(Unknown Source)
    at java.util.Optional.of(Unknown Source)
    at myapp.Supplier.getKeyExtractor(Supplier.java:22)
    at myapp.Orders.lambda[=11=](Orders.java:89)
    at java.util.Comparator.lambda$comparinga9974f(Unknown Source)
    at java.util.TimSort.countRunAndMakeAscending(Unknown Source)
    at java.util.TimSort.sort(Unknown Source)
    at java.util.Arrays.sort(Unknown Source)
    at java.util.ArrayList.sort(Unknown Source)
    at java.util.Collections.sort(Unknown Source)
    at myapp.Orders.sort(Orders.java:89)
    at myapp.Orders.getSortedSuppliersByQuantity(Orders.java:106)
    at myapp.main.main(main.java:22)

以下比较器执行的操作与您的相同,但更短 Java 8 形式:

public void sort(Drug drug, Vector<Supplier> suppliers) {
    Collections.sort(suppliers, Comparator.comparing(s -> s.getDrugs().get(drug)));
}

当地图不包含给定的药物或供应商没有可交易的药物时,可能会出现问题 (NullPointerException)。

如何解决?添加 null 检查或将有效参数传递给方法。


编辑:

我编写了 getKeyExtractor 方法,该方法将抛出一个异常并显示详细消息(如果发生错误)以了解发生了什么:

public void sort(Drug drug, Vector<Supplier> suppliers) {
    Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug)));
}

public static Integer getKeyExtractor(Supplier supplier, Drug drug) {
    return Optional.ofNullable(Optional.ofNullable(supplier.getDrugs())
                               .orElseThrow(() -> new IllegalArgumentException("drugs is null")).get(drug))
                   .orElseThrow(() -> new IllegalArgumentException("the drug couldn't be found"));
}

P.S.

我建议您在此处使用 ListArrayList 而不是 Vector