Как фильтровать массив в 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);
теперь я хочу фильтровать массив автомобилей, сохраняя только 4 двери и более:
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 4)
//add cars[i] to a new array
}
}
как я должен это сделать?
прежде чем я сделал это с вектором:
Vector subset = new Vector();
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 4)
//add cars[i] to a new array
subset.addElement(cars[i]);
}
}
и тогда я бы сделал новый массив с размером вектора. Затем я снова перебирал вектор и заполнить новый массив. Я знаю, что это очень большая процедура-то простая.
я использую J2ME.
7 ответов
EDIT: увидел, что ArrayList не находится в J2ME, но на основе документации он имеет вектор. Если этот векторный класс отличается от вектора J2SE (as в этой документации указано), тогда, возможно, будет работать следующий код:
Vector carList = new Vector();
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 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;
}
это дважды пересекает список и дважды вызывает тест, но не имеет дополнительных выделений или копирования. Методы векторного стиля пересекают список один раз, но выделяют примерно в два раза больше памяти (временно) и копирует каждый хороший элемент примерно в два раза. Так что если вы фильтруете крошечный часть списка (или производительность не проблема, что очень часто не так), то векторный метод хорош. В противном случае, версия выше работает лучше.
Если вам действительно нужен простой массив в результате, я думаю, что ваш путь-это путь: вы не знаете количество результирующих элементов перед фильтрованием, и вы не можете построить новый массив, не зная количества элементов.
однако, если вам не нужна потокобезопасность, рассмотрите возможность использования ArrayList
вместо Vector
. Это должно быть немного быстрее. Затем использовать ArrayList и Л!--2-- > метод для получения массива.
Я не вижу много ошибок в вашем коде. Вы могли бы просто придерживаться векторов во всем, хотя.
вы можете упростить вторую часть (где вы копируете соответствующие элементы в новый массив) с помощью Vector.copyInto (Object []).
нет прямого способа удалить элементы из массива; его размер фиксирован. Что бы вы ни делали, вам нужно каким-то образом выделить новый массив.
Если вы хотите избежать незначительных накладных расходов памяти при выделении 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
доступна Ява меня с API, в отличие от вектора.подсписок.)( Спасибо за поправку.
вам все равно нужно будет создать новый массив.
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);
это не совсем эффективно, хотя.