英文:
Compare two strings in lamdba comparator function placing one in front of the other depending on if the strings contain a word
问题
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));
Comparator<Car> bySkoda = (Car car1, Car car2) ->
car1.getModel().equals("Skoda") ? -1 : car2.getModel().equals("Skoda") ? 1 : 0;
Collections.sort(cars, bySkoda);
英文:
I'm just coming to grips with lambda functions in Java
I have an array list of class objects.
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));
I want to sort the cars based on model so for example I want all Skoda cars placed at the beginning of the array list.
I know for example how to sort the cars by price because it's simply comparing two prices.
Comparator<Car> byCost = (Car obj1, Car obj2) -> obj1.getPrice() -
obj2.getPrice();
Collections.sort(cars, byCost);
I don't know how to use the Comparator function to sort the cars by name. Since I'm comparing two boolean values by using the .contains method, I cannot use the Comparator interface method like I have above. So this is what I've tried.
Comparator<Car> bySkoda = (Car obj1, Car obj2) -> {
if(obj1.getModel().contains("Skoda"))
return 1;
else
return -1;
};
Collections.sort(cars, bySkoda);
This is of course not how to do it. I would like a pointer as to how I can achieve this using a lambda Comparator interface?
答案1
得分: 2
使用三元运算符可能有助于在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";
注:
- 在lambda中,如果可以推断出参数的类型,则可以省略参数的类型。
- 使用
equals
而不是contains
似乎是可以的。 - 为了将
Skoda
型号放在前面,我们使用异或(XOR)来检查car1
和car2
是否都是"Skoda"
。
|--------------------|-------------------|-----------|--------------|
| "Skoda" | "Skoda" | XOR | 结果 |
|.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");
英文:
Using ternary operator may help you to get rid of if
statement inside the lambda:
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"
Notes:
- the type of arguments in lambdas may be skipped if it can be inferred
- it seems to be fine to use
equals
instead ofcontains
- to place
Skoda
models first, we use XOR to check if bothcar1
andcar2
are"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) |
|--------------------|-------------------|-----------|--------------|
- it seems reasonable to keep other models sorted in alphabet order
This may be updated to provide a sorted list with a preferable model first:
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");
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论