如何在Java中过滤数组?

如何在Java中过滤数组?

我有一系列对象,例如汽车:

类:

public class Car{ public int doors; public Car(int d){ this.doors = d; } } 

使用:

 Car [] cars = new Cars[4]; cars[0] = new Car(3); cars[1] = new Car(2); cars[2] = new Car(4); cars[3] = new Car(6); 

现在我想过滤汽车arrays,只保留4门以上:

 for(int i = 0; i 4) //add cars[i] to a new array } } 

我该怎么做?

在我用Vector做之前:

 Vector subset = new Vector(); for(int i = 0; i 4) //add cars[i] to a new array subset.addElement(cars[i]); } } 

然后我会创建一个具有Vector大小的新数组。 然后我再次循环向量并填充新数组。 我知道这对于简单的事情来说是一个非常大的过程。

我正在使用J2ME。

编辑:看到ArrayList不在J2ME中,但基于文档,它确实有一个Vector。 如果该Vector类与J2SE Vector不同(如本文档所示 ),那么以下代码可能会起作用:

 Vector carList = new Vector(); for(int i = 0; i 4) carList.addElement(cars[i]); } } Car[] carArray = new Car[carList.size()]; carList.copyInto(carArray); 

执行此操作的最有效方法 – 如果您正在过滤的谓词价格低廉并且您使用单个线程访问它 – 通常会遍历列表两次:

 public Car[] getFourDoors(Car[] all_cars) { int n = 0; for (Car c : all_cars) if (c.doorCount()==4) n++; Car[] cars_4d = new Car[n]; n = 0; for (Car c : all_cars) if (c.doorCount()==4) cars_4d[n++] = c; return cars_4d; } 

这会遍历列表两次并调用测试两次,但没有额外的分配或复制。 Vector样式方法遍历列表一次,但分配大约两倍所需的内存(瞬态)并将每个好元素复制两次。 因此,如果您要过滤列表的一小部分(或者性能不是问题,通常不是问题),那么Vector方法很好。 否则,上面的版本表现更好。

如果你真的需要一个普通的数组作为结果,我认为你的方式是要走的路:你在过滤之前不知道结果元素的数量,并且你不能在不知道元素数量的情况下构造一个新的数组。

但是,如果您不需要线程安全性,请考虑使用ArrayList而不是Vector 。 它应该有点快。 然后使用ArrayList的toArray方法获取数组。

我看不出你的代码有多大错。 你可以坚持使用矢量。

您可以使用Vector.copyInto(Object [])简化第二部分(将匹配项复制到新数组中)。

没有直接的方法可以从数组中删除元素; 它的大小是固定的。 无论你做什么,你都需要以某种方式分配一个新arrays。

如果你想避免分配Vector的次要内存开销,另一种选择是在你的数组上进行两次传递。 第一次,只需计算要保留的元素数量。 然后分配一个大小的数组,并再次遍历旧数组,将匹配的元素复制到新数组中。

您可以使用System.arrayCopy()

 Car[] cars = ... int length = cars.length < 4 ? cars.length() : 4; Car filter = new Car[4]; System.arrayCopy(cars, 0, filter, 0, length); 

更新: System.arrayCopy在Java ME API中可用,与Vector.subList()不同。 谢谢你的纠正。

无论如何,您将需要创建一个新arrays。

 Vector vector = new Vector(array.length); for (int i = 0; i < array.length; i++) { if (array[i].doors > 4) { vector.add(array[i]); } } Car[] result = new Car[vector.size()]; vector.copyInto(result); 

但这并不是很有效。