在 lambda 比较器函数中比较两个字符串,将一个字符串放在另一个字符串之前,具体取决于字符串是否包含单词

Compare two strings in lamdba comparator function placing one in front of the other depending on if the strings contain a word

我刚开始掌握 Java

中的 lambda 函数

我有一个包含 class 个对象的数组列表。

cars.add(new Car( "BMW",  "1 Series", 39345));
cars.add(new Car( "Nissan",  "micra", 16895 ));
cars.add(new Car( "Volkswagon",  "Golf", 23950));
cars.add(new Car( "Skoda",  "Superb", 32080));
cars.add(new Car( "Kia",  "Sportage", 36450));

我想根据型号对汽车进行排序,例如,我希望将所有 Skoda 汽车放在数组列表的开头。

例如,我知道如何按价格对汽车进行排序,因为它只是比较两个价格。

Comparator<Car> byCost = (Car obj1, Car obj2) -> obj1.getPrice() - 
                 obj2.getPrice();
         
Collections.sort(cars, byCost);

我不知道如何使用 Comparator 函数按名称对汽车进行排序。由于我使用 .contains 方法比较两个布尔值,因此我不能像上面那样使用 Comparator 接口方法。这就是我尝试过的方法。

Comparator<Car> bySkoda = (Car obj1, Car obj2) -> {
    if(obj1.getModel().contains("Skoda"))
        return 1;
    else 
        return -1;
};

Collections.sort(cars, bySkoda);

这当然不是怎么做到的。我想要一个关于如何使用 lambda 比较器接口实现此目的的指针?

使用三元运算符可能会帮助您摆脱 lambda 中的 if 语句:

final String c = "Skoda";
Comparator<Car> bySkoda = (car1, car2) -> 
    c.equals(car1.getModel()) ^ c.equals(car2.getModel()) 
        ? c.equals(car1.getModel()) ? -1 : 1 // either of c1 or c2 is "Skoda"
        : car1.getModel().compareTo(car2.getModel()); // both or none of c1, c2 is "Skoda"

备注:

  • lambdas 中的参数类型如果可以推断则可以跳过
  • equals代替contains
  • 似乎没问题
  • 首先放置Skoda模型,我们使用XOR来检查car1car2是否都是"Skoda"
|--------------------|-------------------|-----------|--------------|
|     "Skoda"        |     "Skoda"       |    XOR    |    Result    |
|.equals(car1.model) |.equals(car2.model)|           |              |
|--------------------|-------------------|-----------|--------------|
|          true      |         true      |   false   |        0     |
|          true      |         false     |   true    |       -1     |
|          false     |         true      |   true    |        1     |
|                    |                   |           | car1.model   |
|          false     |         false     |   false   | .compareTo   |
|                    |                   |           | (car2.model) |
|--------------------|-------------------|-----------|--------------|
  • 让其他模型按字母顺序排序似乎是合理的

这可能会被更新以首先提供一个带有优选模型的排序列表:

public static List<Car> sortWithPreferableModelFirst(List<Car> cars, String model) {
    return cars.stream()
               .sorted((car1, car2) ->
                       model.equalsIgnoreCase(car1.getModel()) ^ model.equalsIgnoreCase(car2.getModel()) 
                       ? model.equalsIgnoreCase(car1.getModel()) ? -1 : 1 
                       : car1.getModel().compareTo(car2.getModel()))
               .collect(Collectors.toList());
}

cars = sortWithPreferableModelFirst(cars, "Skoda");