1

我有一个汽车对象列表。每个汽车对象都有一个类型,指示它是轿车、suv、双门轿车、面包车还是卡车)以及其他属性。假设我的应用程序按下面列出的顺序排列这些

  • 轿车(最低)
  • 轿跑车
  • 越野车
  • 卡车(最高)

如何从列表中找到排名最高的类型。

class Car {

 public Car (String type, String model, int year, long mileage){
     this.type=type;
     this.model = model;
     this.year = year;
     this.mileage = mileage;
 }

  private String type; // Sedan, SUV etc
  private String model; // Focus, Corolla, Camry, Taurus etc
  private int year; 
  private long mileage;

 //getters

}

List<Car> allCars = new ArrayList();
allCars.add(new Car("Coupe", "Focus", 1999, 50000) );
allCars.add(new Car("Sedan", "Camry", 2007, 60000) );
allCars.add(new Car("Truck", "Sierra", 2007, 50000) );
allCars.add(new Car("Truck", "F-150", 2001, 60000) );
allCars.add(new Car("Van", "Sienna", 1999, 40000) );

Java 5 中查找卡车(具有最高等级类型的汽车)的最有效方法是什么。如果需要,我可以使用 apache commons api 或 guava。

我可以循环并创建一组独特的类型。

 Set<String> uniqueTypes = new HashSet<String>;
 for(Car car: allCars) {
     uniqueTypes.add(car.getType);
 }

使用上面的集合,我怎样才能找出最大值(即本例中的卡车)。Collections.max() 会按自然顺序返回最大值吗?

4

2 回答 2

2

虽然引入 CarType 枚举是一个很好的方法,但如果你不能/不想将类型更改为字符串,你可以使用Ordering更强大和更优美的流式ComparatorAPI 的 Guava。在你的情况下使用Ordering#explicit(T, T...)

final Car maxRank = Ordering.explicit("Sedan", "Coupe", "Van", "SUV", "Truck")
    .onResultOf(CarFunction.GET_TYPE)
    .max(allCars);
System.out.println(maxRank.getModel()); // Sierra

其中CarFunction.GET_TYPE定义为:

private enum CarFunction implements Function<Car, String> {
  GET_TYPE {
    @Override
    public String apply(final Car car) {
      return car.getType();
    }
  };
}

或作为private static final Function或在 Java 8 中作为 lambda c -> c.getType()

您可以在此 Wiki 页面上阅读有关订购的更多信息。

于 2013-04-19T09:19:51.937 回答
2

首先,它有助于使汽车的类型成为enum- 这使您可以更轻松地对值进行排序并为Car类添加类型安全性。

下一步是使用 中的max(Collection<? extends T> coll, Comparator<? super T> comp)方法Collections

您需要决定如何对其他值进行排序 - 当您有两辆相同类型的汽车时。默认实现将返回它遇到的第一个最大值。如果类型相同,您可能希望对模型进行二次排序。

这是一个例子:

public static void main(String[] args) throws ParseException {
    List<Car> allCars = new ArrayList();
    allCars.add(new Car(CarType.COUPE, "Focus", 1999, 50000));
    allCars.add(new Car(CarType.SEDAN, "Camry", 2007, 60000));
    allCars.add(new Car(CarType.TRUCK, "Sierra", 2007, 50000));
    allCars.add(new Car(CarType.TRUCK, "F-150", 2001, 60000));
    allCars.add(new Car(CarType.VAN, "Sienna", 1999, 40000));

    Car max = Collections.max(allCars, new Comparator<Car>() {
        @Override
        public int compare(Car o1, Car o2) {
            return o1.getType().compareTo(o2.getType());
        }
    });
    System.out.println(max);
}

static class Car {

    public static enum CarType {

        SEDAN,
        COUPE,
        VAN,
        SUV,
        TRUCK;
    }
    private CarType type;
    private String model; // Focus, Corolla, Camry, Taurus etc
    private int year;
    private long mileage;

    public Car(CarType type, String model, int year, long mileage) {
        this.type = type;
        this.model = model;
        this.year = year;
        this.mileage = mileage;
    }
    //getters
    //toString
}

在这种情况下max是“Sierra”,因为它是列表中的第一辆卡车。

或者,您可以使用 a SortedSetlike aTreeSet但是您需要非常小心地实施 the Comparator,因为它需要与 equals 一致,否则具有相同等级但不是的项目equals将被简单地忽略。

编辑

enum在内部使用 a 但String在构造函数中使用 a 的示例:

static class Car {

    public static enum CarType {

        Sedan,
        Coupe,
        Van,
        SUV,
        Truck;
    }
    private CarType type;
    private String model; // Focus, Corolla, Camry, Taurus etc
    private int year;
    private long mileage;

    public Car(String type, String model, int year, long mileage) {
        this.type = CarType.valueOf(type);
        this.model = model;
        this.year = year;
        this.mileage = mileage;
    }
    //getters
    //toString
}
于 2013-04-19T00:49:54.980 回答