Поиск в ArrayList с пользовательскими объектами для определенных строк

У меня есть ArrayList с пользовательскими объектами. Я хочу искать в этом ArrayList строки.

Класс для объектов выглядит так:

public class Datapoint implements Serializable {

  private String stateBased;
  private String name;
  private String priority;
  private String mainNumber;
  private String groupadress;
  private String dptID;

  public Datapoint(){
  }

  public String getMainNumber() {
    return mainNumber;
  }

  public void setMainNumber(String mainNumber) {
    this.mainNumber = mainNumber;
  }

  public String getName() {
    return name;
  }

  ..and so on

Я знаю, как искать строку в ArrayList, но как это сделать в ArrayList с моими пользовательскими объектами:

ArrayList<String> searchList = new ArrayList<String>();
String search = "a";
int searchListLength = searchList.size();
for (int i = 0; i < searchListLength; i++) {
if (searchList.get(i).contains(search)) {
//Do whatever you want here
}
}

Итак, я хочу иметь функцию для поиска в моем ArrayList, например, с пятью объектами для всех строк «имя».


person Mokkapps    schedule 19.09.2012    source источник


Ответы (7)


Самый простой способ - создать for, где вы проверяете, имеет ли атрибут name пользовательского объекта желаемую строку.

    for(Datapoint d : dataPointList){
        if(d.getName() != null && d.getName().contains(search))
           //something here
    }

Я думаю, это поможет вам.

person Renato Lochetti    schedule 19.09.2012
comment
также пробовал этот, но он не находит мою строку. Если я конвертирую свой ArrayList в String, он выглядит так [[[true] [Wippe links oben] [1] [1.001] [Low] [1 ]], [[true] [Wippe rechts] [1] [1.001] [Low] [2 ]], [[true] [Temperaturwert] [7] [7.001] [Low] [256 ]], [[true] [Schalten (Status)] [1] [1.001] [Low] [257 ]]] - person Mokkapps; 19.09.2012
comment
Какую строку вы хотите найти в этом примере? - person Renato Lochetti; 19.09.2012
comment
Ok. Код, который я разместил, ищет только атрибут имени. Вы можете добавить другие проверки внутри предложения IF. Например: d.getMainNumber().contains... Это решит проблему, но это не очень красивое решение. Изменятся ли атрибуты в будущем? - person Renato Lochetti; 19.09.2012
comment
ах, конечно.... атрибуты всегда одни и те же, поэтому я реализую шесть предложений if, и это должно решить мою проблему. Знаете ли вы лучшее или более красивое решение? Как я могу узнать имя атрибута для моего MainNumber? - person Mokkapps; 19.09.2012
comment
Вы можете реализовать метод внутри класса Datapoint, который выполняет проверки всех атрибутов. Таким образом, вы просто вызываете этот метод в IF, и он вернется, если объект имеет желаемую строку в одном атрибуте или нет. Другое решение - использовать Reflection и получить все методы, но я думаю, что это уже конец. - person Renato Lochetti; 19.09.2012

ОБНОВЛЕНИЕ: Использование синтаксиса Java 8

List<DataPoint> myList = new ArrayList<>();
//Fill up myList with your Data Points

List<DataPoint> dataPointsCalledJohn = 
    myList
    .stream()
    .filter(p-> p.getName().equals(("john")))
    .collect(Collectors.toList());

Если вы не возражаете против использования внешней библиотеки, вы можете использовать Предикаты из библиотеки Google Guava следующим образом:

class DataPoint {
    String name;

    String getName() { return name; }
}

Predicate<DataPoint> nameEqualsTo(final String name) {
    return new Predicate<DataPoint>() {

        public boolean apply(DataPoint dataPoint) {
            return dataPoint.getName().equals(name);
        }
    };
}

public void main(String[] args) throws Exception {

    List<DataPoint> myList = new ArrayList<DataPoint>();
    //Fill up myList with your Data Points

    Collection<DataPoint> dataPointsCalledJohn =
            Collections2.filter(myList, nameEqualsTo("john"));

}
person munyengm    schedule 19.09.2012
comment
Наконец-то в java 8 появилась функциональная нотация. Рулз! - person Diego Duarte; 31.12.2015
comment
Мне нужно аналогичное решение для Java 7, потому что Android не справляется с Java 8 с более низкими API. - person Neon Warge; 05.08.2016
comment
есть ли разница в производительности с этим ответом и верхним? - person Dasser Basyouni; 13.08.2018

попробуй это

ArrayList<Datapoint > searchList = new ArrayList<Datapoint >();
String search = "a";
int searchListLength = searchList.size();
for (int i = 0; i < searchListLength; i++) {
if (searchList.get(i).getName().contains(search)) {
//Do whatever you want here
}
}
person G_S    schedule 19.09.2012
comment
Возможное исключение NullPointerException, если getName() не настроен. - person gtgaxiola; 19.09.2012
comment
просто думая, что установлено каждое значение для конкретного объекта. - person G_S; 19.09.2012
comment
Если я конвертирую свой ArrayList в String, он выглядит так [[[true] [Wippe links oben] [1] [1.001] [Low] [1 ]], [[true] [Wippe rechts] [1] [1.001] [Low] [2 ]], [[true] [Temperaturwert] [7] [7.001] [Low] [256 ]], [[true] [Schalten (Status)] [1] [1.001] [Low] [257 ]]] . Если я использую, например, String search = "1.001";, он не найдет никакой строки... у вас есть идеи? – - person Mokkapps; 19.09.2012
comment
почему вы конвертируете его в строку? Вам интересно узнать, находится ли поиск строки в вашем массиве независимо от того, находится ли он в stateBased, имени, приоритете, mainNumber, групповом адресе или dptID? - person G_S; 19.09.2012

Вероятно, что-то вроде:

ArrayList<DataPoint> myList = new ArrayList<DataPoint>();
//Fill up myList with your Data Points

//Traversal
for(DataPoint myPoint : myList) {
    if(myPoint.getName() != null && myPoint.getName().equals("Michael Hoffmann")) {
        //Process data do whatever you want
        System.out.println("Found it!");
     }
}
person gtgaxiola    schedule 19.09.2012

Чтобы пользовательский класс правильно работал в коллекциях, вам необходимо реализовать/переопределить методы equals() класса. Для сортировки также переопределите compareTo().

См. эту статью или погуглите о том, как правильно реализовать эти методы.

person Ridcully    schedule 19.09.2012

contains() просто вызывает equals() для ArrayList элементов, поэтому вы можете перегрузить equals() вашего класса на основе переменной класса name. Возвратите true из equals(), если name равно соответствующему String. Надеюсь это поможет.

person Egor    schedule 19.09.2012
comment
Не мешает ли это ему искать в других полях? - person gtgaxiola; 19.09.2012
comment
@gtgaxiola, да, и это также не очень хорошее решение с точки зрения дизайна, но обычно нехорошо сравнивать разные типы данных. - person Egor; 19.09.2012

Используйте 1_:

CollectionUtils.find(myList, new Predicate() {
   public boolean evaluate(Object o) {
      return name.equals(((MyClass) o).getName());
   }
}
person MukeshKoshyM    schedule 19.07.2013