在 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来检查car1
和car2
是否都是"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");
我刚开始掌握 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来检查car1
和car2
是否都是"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");