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

huangapple go评论80阅读模式
英文:

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( &quot;BMW&quot;,  &quot;1 Series&quot;, 39345));
cars.add(new Car( &quot;Nissan&quot;,  &quot;micra&quot;, 16895 ));
cars.add(new Car( &quot;Volkswagon&quot;,  &quot;Golf&quot;, 23950));
cars.add(new Car( &quot;Skoda&quot;,  &quot;Superb&quot;, 32080));
cars.add(new Car( &quot;Kia&quot;,  &quot;Sportage&quot;, 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&lt;Car&gt; byCost = (Car obj1, Car obj2) -&gt; 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&lt;Car&gt; bySkoda = (Car obj1, Car obj2) -&gt; {
    if(obj1.getModel().contains(&quot;Skoda&quot;))
        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)来检查car1car2是否都是"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 = &quot;Skoda&quot;;
Comparator&lt;Car&gt; bySkoda = (car1, car2) -&gt; 
    c.equals(car1.getModel()) ^ c.equals(car2.getModel()) 
        ? c.equals(car1.getModel()) ? -1 : 1 // either of c1 or c2 is &quot;Skoda&quot;
        : car1.getModel().compareTo(car2.getModel()); // both or none of c1, c2 is &quot;Skoda&quot;

Notes:

  • the type of arguments in lambdas may be skipped if it can be inferred
  • it seems to be fine to use equals instead of contains
  • to place Skoda models first, we use XOR to check if both car1 and car2 are &quot;Skoda&quot;
|--------------------|-------------------|-----------|--------------|
|     &quot;Skoda&quot;        |     &quot;Skoda&quot;       |    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&lt;Car&gt; sortWithPreferableModelFirst(List&lt;Car&gt; cars, String model) {
    return cars.stream()
               .sorted((car1, car2) -&gt;
                       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, &quot;Skoda&quot;);

huangapple
  • 本文由 发表于 2020年10月14日 02:51:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/64341412.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定