У меня есть список объектов, и список очень большой. Объект есть
class Sample {
String value1;
String value2;
String value3;
String value4;
String value5;
}
Теперь мне нужно искать конкретное значение объекта в списке. Скажите, если value3 == 'three'
Я должен вернуть эти объекты (Мой поиск не всегда основан на value3)
Список есть
List<Sample> list = new ArrayList<Sample>();
Какой эффективный способ сделать это?
Спасибо.
Вы можете попробовать Apache Commons Collections.
Существует класс CollectionUtils, который позволяет выбирать или фильтровать элементы по индивидуальному заказу Predicate.
Ваш код будет таким:
Predicate condition = new Predicate() {
boolean evaluate(Object sample) {
return ((Sample)sample).value3.equals("three");
}
};
List result = CollectionUtils.select( list, condition );
Обновление:
В java8 , используя Lambdas и StreamAPI, это должно быть:
List<Sample> result = list.stream()
.filter(item -> item.value3.equals("three"))
.collect(Collectors.toList());
намного приятнее!
С помощью Java 8 вы можете просто преобразовать свой список в stream, позволяющий вам писать:
import java.util.List;
import java.util.stream.Collectors;
List<Sample> list = new ArrayList<Sample>();
List<Sample> result = list.stream()
.filter(a -> Objects.equals(a.value3, "three"))
.collect(Collectors.toList());
Обратите внимание, что
a - > Objects.equals (a.value3, «три»)
является лямбда-выражениемresult
- это List
с типом Sample
list.parallelStream ()
вместо list.stream ()
(прочитайте это)& Лт; br >
Если вы не можете использовать Java 8, вы можете использовать библиотеку Apache Commons и написать:
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
Collection result = CollectionUtils.select(list, new Predicate() {
public boolean evaluate(Object a) {
return Objects.equals(((Sample) a).value3, "three");
}
});
// If you need the results as a typed array:
Sample[] resultTyped = (Sample[]) result.toArray(new Sample[result.size()]);
Обратите внимание, что:
Object
до Sample
Sample []
, вам нужен дополнительный код (как показано в моем примере)& Лт; br >
Бонус: хорошая статья в блоге, рассказывающая о том, как найти элемент в списке.
Если вы всегда ищете на основе value3
, вы можете сохранить объекты в карте:
Map<String, List<Sample>> map = new HashMap <>();
Затем вы можете заполнить карту key = value3
и value = list Образцы объектов с тем же свойством value3
.
Затем вы можете запросить карту:
List<Sample> allSamplesWhereValue3IsDog = map.get("Dog");
Примечание: если 2 экземпляра Sample
не могут иметь одинаковое value3
, вы можете просто использовать Map < String, Sample >
.
Я изменяю этот список и добавляю список к образцам, попробуйте это
Pseudocode
Sample {
List<String> values;
List<String> getList() {
return values}
}
for(Sample s : list) {
if(s.getString.getList.contains("three") {
return s;
}
}
Поскольку ваш список является «ArrayList», можно предположить, что он несортирован. Следовательно, нет способа поиска вашего элемента, который быстрее, чем O (n) .
Если вы можете, вам следует подумать о том, чтобы изменить свой список на «Set» (с «HashSet» в качестве реализации) с определенным «Comparator» для вашего класса выборки.
Другой возможностью было бы использовать HashMap
. Вы можете добавить свои данные как Sample
(пожалуйста, начните имена классов с заглавной буквы) и использовать строку, которую вы хотите найти в качестве ключа. Тогда вы можете просто использовать
Sample samp = myMap.get(myKey);
Если на ключ может быть несколько выборок, используйте Map < String, List < Sample > >
, в противном случае используйтеMap < String, Sample >
. Если вы используете несколько ключей, вам придется создать несколько карт, которые содержат один и тот же набор данных. Поскольку все они указывают на одни и те же объекты, пространство не должно быть большой проблемой.