Как я могу отфильтровать множество на Яве?
У меня есть множество объектов, например, автомобили:
Класс:
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.
Если вам действительно нужен простой массив в результате, я думаю, что ваш путь - это путь: вы не знаете количество полученных элементов, прежде чем фильтровать, и вы не можете построить новый массив, не зная Количество элементов.
Однако, если вам не нужна безопасность потоков, рассмотрите возможность использования ArrayList
вместо Vector
. Это должно быть несколько быстрее. Затем используйте метод ArrayList Toarray
, чтобы получить массив.
Редактировать: Увидел, что ArrayList не находится в J2ME, но на основе документации у него есть вектор. Если этот векторный класс отличается от j2se vector (как Эта документация указывает ), то, возможно, следующий код будет работать:
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);
Нет прямого способа удаления элементов из массива; его размер исправлен. Что бы вы ни делали, вам нужно как-то выделить новый массив.
Если вы хотите избежать незначительной накладной расстройки памяти выделения Vector
, другой вариант будет делать два пропуска по вашему массиву. Первый раз просто подсчитайте количество элементов, которые вы хотите сохранить. Затем выделите массив, который снова и снова включите свой старый массив, копируя соответствующие элементы в новый массив.
Для передачи данных между различными экземплярами приложения можно использовать Pipes . Если вам просто нужно сообщить другому экземпляру, что что-то произошло, вы можете отправить сообщения из одного приложения в другое с помощью API SendMessage.
-121--2387536-Я не вижу ничего плохого в вашем коде. Можно просто придерживаться Векторов.
Вторую часть (где копируются соответствующие предметы в новый массив) можно упростить с помощью Vector.copyInto (Object []).
-121--2325131-Если вам действительно нужен простой массив в результате, я думаю, ваш путь - это путь: вы не знаете количество результирующих элементов до фильтрации, и вы не можете построить новый массив, не зная количество элементов.
Если безопасность потоков не требуется, рекомендуется использовать ArrayList
вместо Vector
. Это должно быть несколько быстрее. Затем используйте метод ArrayList toArray
для получения массива.
Вам нужно будет создать новый массив в любом случае.
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);
Это не совсем эффективно, хотя.
Наиболее эффективный способ сделать это-- если предикат, по которому вы фильтруете, недорогой, и вы обращаетесь к нему с помощью одного потока-- обычно он проходит по списку дважды:
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.copyinto (объект []).
Вы можете использовать System.arrayCopy()
:
Car[] cars = ...
int length = cars.length < 4 ? cars.length() : 4;
Car filter = new Car[4];
System.arrayCopy(cars, 0, filter, 0, length);
UPDATE: System.arrayCopy
доступна в Java ME API, в отличие от Vector.subList(). Спасибо за исправление.