我有一个Car对象列表。每个汽车对象都有一个类型,表明它是轿车,轿车,轿跑车,货车还是卡车)以及其他属性。假设我的应用程序按照下面列出的顺序排列
如何从列表中找到排名最高的类型。
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中找到Truck(排名最高的汽车)的最有效方法是什么。如果需要,我可以使用apache commons api或guava。
我可以循环播放并创建一组独特的类型。
Set<String> uniqueTypes = new HashSet<String>;
for(Car car: allCars) {
uniqueTypes.add(car.getType);
}
使用上面的Set,我怎样才能找到max(即本例中的Truck)。 Collections.max()会按自然顺序返回最大值吗?
答案 0 :(得分: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”,因为它是列表中的第一辆卡车。
或者您可以像SortedSet
一样使用TreeSet
,但是您需要非常小心来实施Comparator
,因为它需要consistent with equals否则,具有相同排名但不是equals
的项目将被忽略。
修改强>
在内部使用enum
但在构造函数中使用String
的示例:
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
}
答案 1 :(得分:2)
尽管引入CarType枚举是一种很好的方法,但是如果你不能/不想将类型改为字符串,你可以使用Guava的Ordering
,它更强大,更流畅{{1} API。在您的情况下,请使用Ordering#explicit(T, T...)
:
Comparator
其中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();
}
};
}
或在Java 8中作为lambda private static final Function
。
您可以在this Wiki page上阅读有关订购的详情。