2013-04-19 55 views
1

我有一个Car对象列表。每个汽车物体都有一个类型,表明它是轿车,SUV,轿跑车,货车还是卡车)以及其他属性。假设我的应用程序在下面通过特定对象属性查找HashSet/ArrayList中的最大值

  • 轿车(最低)
  • 跑车上市的顺序排列这些
  • 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或番石榴。

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

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

使用上面的设置,我怎么能找出最大(即卡车在这个例子中)。 Collections.max()会按自然顺序返回最大值吗?

+1

使'type'成为'enum'。 – jlordo

+1

您需要将'max'方法与'Comparator'一起使用,并告诉如何订购物品。 –

回答

2

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

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

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

下面是一个例子:

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是“塞拉”,因为它是在列表中的第一辆卡车。

或者,您也可以使用SortedSetTreeSet但你将需要非常小心与实施Comparator因为这将需要consistent with equals否则即有相同的排名,但并没有equals只会被忽略的项目, 。

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 
} 
+0

谢谢@ bmorris591你的例子。在我的情况下,CarTypes是许多API使用的现有对象,将它们转换为Enums可能不是微不足道的。但是,即使使用Enum,您在哪里指定订单(VAN排名高于COUPE,SEDAN或TRUCK的排名高于其他所有排名)。 – aprajitha

+1

您可以在内部使用'CarType.valueOf(String)'将其作为'enum'来解析传入的'String'到'CarType'。当枚举被声明时,它们被分配一个索引,这个索引是它们的自然顺序 - 所以它们被声明的顺序是它们排序的顺序。也许阅读[this](http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)。 –

2

虽然引入CarType枚举是做到这一点的好方法,如果你不能/:

编辑

使用enum国内,而且在构造函数中采取String示例不想改变字符串类型,你可以使用番石榴的Ordering这是更强大和抛光流利Comparator API。在你的情况下使用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拉姆达c -> c.getType()

你可以在this Wiki page了解更多关于订购。

+0

非常简洁... – Cemo