Как выполнить поиск в списке объектов Java - программирование

Как выполнить поиск в списке объектов Java

У меня есть список объектов, и список очень большой. Объект

class Sample {
    String value1;
    String value2;
    String value3;
    String value4;
    String value5;
 }

Теперь мне нужно найти конкретное значение объекта в списке. Скажем, если value3=='three' мне нужно вернуть эти объекты (мой поиск не всегда основан на значении3)

Список

List<Sample> list = new ArrayList<Sample>();

Каков эффективный способ сделать это?

Спасибо.

4b9b3361

Ответ 1

Вы можете попробовать Коллекции сообщества Apache.

Существует класс CollectionUtils, который позволяет выбирать или фильтровать элементы по Predicate.

Ваш код будет выглядеть следующим образом:

Predicate condition = new Predicate() {
   boolean evaluate(Object sample) {
        return ((Sample)sample).value3.equals("three");
   }
};
List result = CollectionUtils.select( list, condition );

Update:

В java8, используя Lambdas и StreamAPI, это должно быть:

List<Sample> result = list.stream()
     .filter(item -> item.value3.equals("three"))
     .collect(Collectors.toList());

гораздо приятнее!

Ответ 2

Использование Java 8

С 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, "three") является выражением лямбда
  • result - это List с типом Sample
  • Это очень быстро, без кастинга на каждой итерации
  • Если ваша логика фильтра становится тяжелее, вы можете сделать list.parallelStream() вместо list.stream() (прочитать это)


Apache Commons

Если вы не можете использовать 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[], вам нужен дополнительный код (как показано в моем примере).



Бонус: хорошая статья в блоге, рассказывающая о том, как найти элемент в списке.

Ответ 3

Если вы всегда выполняете поиск на основе value3, вы можете сохранить объекты на карте:

Map<String, List<Sample>> map = new HashMap <>();

Затем вы можете заполнить карту с помощью key = value3 и value = списка объектов Sample с тем же свойством value3.

Затем вы можете запросить карту:

List<Sample> allSamplesWhereValue3IsDog = map.get("Dog");

Примечание. Если экземпляры 2 Sample могут иметь одинаковый value3, вы можете просто использовать Map<String, Sample>.

Ответ 4

Модифицируйте этот список и добавьте список в образцы, попробуйте это

Псевдокод

Sample {
   List<String> values;
   List<String> getList() {
   return values}
}



for(Sample s : list) {
   if(s.getString.getList.contains("three") {
      return s;
   }
}

Ответ 5

Поскольку ваш список равен ArrayList, можно предположить, что он несортирован. Следовательно, нет никакого способа поиска элемента, который быстрее, чем O (n).

Если это возможно, вы должны подумать об изменении своего списка в SetHashSet как реализация) с определенным Comparator для вашего класса образца.

Другая возможность - использовать HashMap. Вы можете добавить свои данные как Sample (пожалуйста, запустите имена классов с прописной буквой) и используйте строку, которую вы хотите искать как ключ. Тогда вы можете просто использовать

Sample samp = myMap.get(myKey);

Если на ключ может быть несколько выборок, используйте Map<String, List<Sample>>, в противном случае используйте Map<String, Sample>. Если вы используете несколько ключей, вам нужно будет создать несколько карт, содержащих один и тот же набор данных. Как все они указывают на одни и те же объекты, пространство не должно быть проблемой.