我有List
个对象。我想迭代这个对象列表并根据条件处理一些对象子集,最后创建一个新的对象列表,其中一些已处理的对象被删除。
这样做的最佳方式是什么。?
示例:
实际对象:List<Cars>
Cars
。Cars
中,要删除相同型号的那些。答案 0 :(得分:7)
Google Guava libraries有:
Iterables.filter(cars, new Predicate<Car>() {
@Override
public boolean apply(Car car) {
//return true or false depending on whether you
// want this car to remain in the list
}
}
您还可以使用中间Set
- 即
cars = new ArrayList<Car>(new HashSet<Car>(cars));
您已正确实施hashCode
和equals
。如果这是您汽车的标识,则此选项可行。
您也可以使用迭代器:
for (Iterator<Car> it = cars.iterator(); it.hasNext();) {
Car car = it.next();
if (conditions here) {
it.remove();
}
}
顺便说一句,我知道上面的例子并没有完全解决你的问题 - 你仍然应该考虑在外部循环中迭代什么。
答案 1 :(得分:3)
如果您希望自定义等于比较,那么您应该定义Comparator<Car>
,然后循环浏览汽车。
List<Car> originalList;
Comparator<Car> c = new CarSpeedComparator();
List<Car> result = carFilter(originalList, c);
/// Below is the filter method
public static List<Car> carFilter(List<Car> original, Comparator<Car> comp)
List<Car> result = new ArrayList<Car>();
// Process each car
for (Car car: original) {
boolean containsC = false;
// now we check each car in the result
// to see if we already have an equivalent car
for (int i = 0; i < result.size(); i++) {
// if the two cars are equivalent under the rules
// then we already have that car in the list
if (comp.compare(result.get(i), car) == 0) {
containsC = true;
break;
}
}
// if the result does not contain an equivalent car,
// add it to the list
if (!containsC) result.add(car)
}
return result;
}
//// Implementation of one of the necessary comparators
public class CarSpeedComparator implements Comparator<Car> {
public int compare(Car c1, Car c2) {
return c1.getSpeed() - c2.getSpeed();
}
}
结果列表只包含每个速度的一辆车。
答案 2 :(得分:1)
听起来你可能想先做的就是按速度索引列表中的汽车。完成后,可能更容易完成您正在寻找的其余处理。 Guava的Multimap对此有好处:
ImmutableListMultimap<Integer, Car> speedIndex = Multimaps.index(cars,
new Function<Car, Integer>() {
public Integer apply(Car from) {
return from.getSpeed();
}
});
现在speedIndex
将是一个多图,可让您执行以下操作:
for (Integer speed : speedIndex.keySet()) {
ImmutableList<Car> carsWithSpeed = speedIndex.get(speed);
// Do stuff
}
这使您可以对原始列表中具有相同速度的所有汽车进行分组。然后你可以对你想做的任何处理。您可能希望按型号对这组汽车编制索引,为您提供具有相同速度和型号的汽车分组。如果需要,您可以从原始列表中删除这些汽车。或者,如果您根本不想修改原始列表,只是获取已移除一组汽车的列表副本,您可以将要删除的每辆汽车添加到Set
,然后获取副本那些车被移除了这样:
Set<Car> carsToRemove = ...;
List<Car> filteredList = Lists.newArrayList(Iterables.filter(cars,
Predicates.not(Predicates.in(carsToRemove))));
答案 3 :(得分:0)
如果你在大名单上反复这样做,你会希望提高效率。保留一个对象列表,同时为每个车型保留单独的列表; Hashtable<String, List> models
。这样,您已经为未来的类别完成了模型部分。它需要更多的内存,但显着的搜索时间更短。
答案 4 :(得分:0)
对我来说,看起来OP只需要一组独特的(模型,速度)对。如果是这样,这是一个简单的方法:
class Car {
private final String model;
private final int speed;
public int hashCode(){
return model.hashCode() + speed;
}
public boolean equals(Object obj){
//check on null/different class omitted.
Car other = (Car)obj;
return this.model.equals(obj.model) && this.speed == other.speed;
}
}
然后
Set<Car> cars = new HashSet<Car>(originalListOfCars);