如何为特定字符串编写自定义Java比较器?

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

How Do You Write A Custom Java Comparator For A Specific String?

问题

(x, y) -> x.getName().equals(y.getName()) ?
            x.getDirection().equals("Up") ? -1 : 1 :
            x.getType().compareTo(y.getType())
英文:

Hello I was wondering if somebody could help me with a little bit of code I'm stuck on. So I'm writing a custom comparator using lambda statements I want to do the following. If the names that return of .getName() equals to each other then I want to pick the one that is the String "Up" from .getDirection() (Its guaranteed one of them is "Up" in that case, the other is "Down"), else we will look at which one is alphabetically higher depending on the .getType().

So far I have this:
(x,y) -> x.getName().equals(y.getName()) ? //confused part : x.getType().compareTo(y.getType) );

Any help would be appreciated, thank you.

答案1

得分: 2

以下是翻译好的部分:

output

Car{name='OldCar', up=true, type='type1990'}
Car{name='NewCar', up=true, type='type2019'}
Car{name='NewCar', up=false, type='type2020'}
英文:

I created an example class, hope it can help.

package com;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * @author jinleizhang
 */
public class ComparatorTest {
  static class Car {
    String name;
    boolean up;
    String type;

    Car(String name, boolean up, String type) {
      this.name = name;
      this.up = up;
      this.type = type;
    }

    public String getName() {
      return this.name;
    }

    public boolean isUp() {
      return this.up;
    }

    public String getType() {
      return this.type;
    }

    @Override
    public String toString() {
      return "Car{" +
          "name='" + name + '\'' +
          ", up=" + up +
          ", type='" + type + '\'' +
          '}';
    }
  }

  public static void main(String[] args) {
    Car carA = new Car("NewCar", false, "type2020");
    Car carB = new Car("NewCar", true, "type2019");
    Car carC = new Car("OldCar", true, "type1990");

    List<Car> cars = new ArrayList<>();
    cars.add(carA);
    cars.add(carB);
    cars.add(carC);
    Collections.sort(cars, (x, y) -> {
      if (x.getName().equals(y.getName())) {
        return x.isUp() ? -1 : 1;
      }

      return x.getType().compareTo(y.getType());
    });

    for (var car : cars) {
      System.out.println(car);
    }
  }
}

output

Car{name='OldCar', up=true, type='type1990'}
Car{name='NewCar', up=true, type='type2019'}
Car{name='NewCar', up=false, type='type2020'}

答案2

得分: 2

不要过于贪心地追求简洁。闭包很好用,但目标不是写最少量的代码,而是仅编写完成任务所需的代码,以易于理解的方式(大多数情况下是这样的...)

(x, y) -> {
if (x.getName().equals(y.getName()) {
return "Up".equals(x.getDirection()) ? -1 : 1;
} else {
return x.getType().compareTo(y.getType());
}
}
英文:

Don't try to get too greedy with terseness. Closures are nice, but the objective is not to write the least amount of code, it's to write only the code that's needed to get the job done in a way that's easily understood (well, most of the time anyway...)

(x, y) -> {
if (x.getName().equals(y.getName()) {
return "Up".equals(x.getDirection()) ? -1 : 1;
} else {
return x.getType().compareTo(y.getType());
}
}

答案3

得分: 1

你不能将这个写成一个比较器。

假设你有这些对象:

  • A1: 名字: A 方向: 下 类型: 1
  • A3: 名字: A 方向: 上 类型: 3
  • B2: 名字: B 方向: 上 类型: 2

根据你的逻辑,A1 < B2 且 B2 < A3 且 A3 < A1。这违反了比较器的通用契约的传递性质

英文:

You cannot write this as a comparator.

Suppose you have these objects:

  • A1: Name: A Direction: Down Type: 1
  • A3: Name: A Direction: Up Type: 3
  • B2: Name: B Direction: Up Type: 2

According to your logic, A1 < B2 and B2 < A3 and A3 < A1. This is a violation of the transitive property of the general contract of comparator.

huangapple
  • 本文由 发表于 2020年8月7日 10:41:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63294416.html
匿名

发表评论

匿名网友

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

确定