Java 按列表类型排序对象 属性

Java sort object by list type property

我有以下对象:

public class Shipping {
    String name;
    List<Method> methods;
}

public class Method {
    String serviceType;
    String cost;
}

我有:

List<Shipping> shippings;

我想按照return成本最低的方法对运费进行排序。

示例:

shipping: "Josh" with 2 methods: "Premium","5" and "Basic","3"
shopping: "Nash" with 2 methods: "Prem", "7" and "Base","2"

会这样排序:

shopping: "Nash" with 2 methods: "Base","2" and "Prem", "7"
shopping: "Josh" with 2 methods: "Basic","3" and "Premium","5"

我需要它 return 方法成本最低的方法作为第一个方法,同时对方法进行排序以使最便宜的方法排在第一位。

最好的方法是什么?如果有更好的解决方案,我正在使用 Java 8,并且有 guava

编辑: cost 是一个浮点数。我需要将它保留为 String,因为它是我传递给 REST api 的对象,不希望客户端解析它。

您需要比较器或为方法 class 实现 Comparable,例如:

public class Method implements Comparable<Method> {
    public int compareTo(Method thatMethod) {
        return Integer.compare(Integer.parseInt(this.cost), Integer.parseInt(thatMethod.getCost()));//if you need name then you could do this.cost.compareTo(thatMethod.getServiceType()); assuming serviceType can never be null 
    }
}

然后按如下方式对您的列表进行排序:

Collections.sort(methods);

我建议您阅读 Java 的排序 tutorial。您的要求似乎表明您想要按其 Method 对每个 Shipping 实例进行排序,而在其他地方您想要对要按字母顺序排序的 Shipping 实例的集合进行排序,但它不是从你写的完全清楚。

无论如何,一旦您阅读了教程,就可以直接做到这一点。总之,您可以使用 Comparator 或通过实施 Comparable 并简单地在您的数据集上调用 Collections.sort(...) 来完成此操作。

您可以先对 shippings 列表中每个 Shipping 实例的 methods 字段进行排序,然后按每个实例的第一个元素对 shippings 列表进行排序 methods 列表:

for (Shipping shipping : shippings)
    shipping.methods.sort((m1, m2) -> Integer.compare(m1.cost, m2.cost));

shippings.sort((s1, s2) -> 
  Integer.compare(s1.methods.get(0).cost, s2.methods.get(0).cost));

您可能需要做一些额外的工作将成本转换为整数,但总体思路是相同的。

您可以定义新的 Comparator 来定义您的排序标准,如下所示:

Comparator<Shipping> shippingComparator = new Comparator<Shipping>{
public int compare(Shipping obj1, Shipping obj2) {
    //your rules for comparing Shipping1, Shipping 2 goes here
    //return -1 when obj1 should be before obj2
    //return 1 when obj1 should be after obj2
    //return 0 when obj1 is equal to obj2 and relative position doesnt matter
} 

然后使用此比较器对您的列表进行排序:

ArrayList<Shipping> shippings;
//populate List
Collections.sort(shippings, shippingComparator );

我们将假设所有运输都至少有 1 种方法。因此,您希望按成本对运输方式进行排序。那么让我们这样做吧:

shippings.forEach(shipping -> {
    shipping.getMethods().sort(Comparator.comparing(Method::getCost));
});

然后您希望运输列表按其方法的最低成本排序。最低成本是第一种方法的成本,因为它们现在已排序:

shippings.sort(Comparator.comparing(shipping -> shipping.getMethods().get(0).getCost()));

请注意,这假设您希望按字典顺序比较成本。如果正如我所怀疑的那样,成本实际上是一个数字,那么它应该存储在方法 class 中,而不是作为一个字符串。因此,将其设为 Integer 或 BigDecimal,或任何合适的类型。