Выяснить, содержит ли список объектов что-либо с указанным значением поля? - PullRequest
28 голосов
/ 20 сентября 2011

У меня есть список DTO, полученных от БД, и у них есть идентификатор. Я хочу убедиться, что мой список содержит объект с указанным идентификатором. Очевидно, что создание объекта с ожидаемыми полями в этом случае не поможет, так как содержит () вызовы для Object.equals (), и они не будут равны.

Я пришел к такому решению: создал интерфейс HasId, реализовал его во всех моих DTO и унаследовал ArrayList с новым классом, в котором есть метод contains(Long id).

public interface HasId {
    void setId(Long id);
    Long getId();
}

public class SearchableList<T extends HasId> extends ArrayList<T> {
    public boolean contains(Long id) {
        for (T o : this) {
            if (o.getId() == id)
                return true;
        }
        return false;
    }
}

Но в этом случае я не могу типизировать List и ArrayList в SearchableList ... Я бы с этим жил, но хотел убедиться, что я не изобретаю велосипед.

РЕДАКТИРОВАТЬ (октябрь '16):

Конечно, с введением лямбды в Java 8, способ сделать это очень просто:

list.stream().anyMatch(dto -> dto.getId() == id);

Ответы [ 6 ]

48 голосов
/ 20 сентября 2011

Я предлагаю создать простой статический метод, как вы написали, без каких-либо дополнительных интерфейсов:

public static boolean containsId(List<DTO> list, long id) {
    for (DTO object : list) {
        if (object.getId() == id) {
            return true;
        }
    }
    return false;
}
8 голосов
/ 20 сентября 2011

Я предлагаю вам просто переопределить equals в вашем SearchableDto, это будет что-то вроде:

public boolean equals(Object o){
    if (o instanceof SearchableDto){
        SearchableDto temp = (SearchableDto)o;
        if (this.id.equals(temp.getId()))
            return true;
    }
    return false;
}

В этом случае contains должно работать, вероятно, если оно имеет тот же id;

2 голосов
/ 20 сентября 2011

Ну, я думаю, что ваш подход немного усложняет проблему.Вы сказали:

У меня есть список DTO, полученных из БД, и у них есть идентификатор.

Тогда, вероятно, вам следует использовать класс DTO для хранения этих элементов,Если это так, поместите метод получения и установки идентификатора в этот класс:

public class DTO implements HasId{
    void setId(Long id);
    Long getId();
}

Этого достаточно для итерации по ArrayList и поиска нужного идентификатора.Расширение класса ArrayList только для добавления функции «Compare-ID» мне кажется слишком сложным.@ Никита Белоглазов - хороший пример.Вы можете обобщить это еще больше:

public boolean containsId(List<HasId> list, long id) {
    for (HasId object : list) {
        if (object.getId() == id) {
            return true;
        }
    }
    return false;
}
1 голос
/ 28 июля 2017

Это то, что я использовал в моей функции DFS GetUnvisitedNeighbour.

    public static int GetUnvisitedNeighbour(int v)
{
    Vertex vertex = VertexList.stream().filter(c -> c.Data == v).findFirst().get();
    int position = VertexList.indexOf(vertex);
    ...
}

Раньше я работал в C #. С лямбда-выражениями в C # работать гораздо проще, чем в Java.

Вы можете использовать функцию filter, чтобы добавить условие для свойства элемента.

Затем используйте findFirst().get() или findAny.get() в соответствии с вашей логикой.

0 голосов
/ 08 января 2017
   public boolean containsId(List<HasId> list, long id) {
    boolean flag = false;
    for (HasId object : list) {
        if (object.getId() == id) {
           flag = true;
        }
    }
    return flag;
}
0 голосов
/ 20 сентября 2011

Ваше требование мне не понятно.Когда вы говорите «убедитесь, что мой список содержит объект с указанным идентификатором», вы хотите:

  1. определить, присутствует ли идентификатор и действовать соответственно
  2. всегда включает DTO стребуемый идентификатор в ваших результатах

Большинство ответов предполагали, что вы имеете в виду 1, однако, думая об этом, вы могли бы также иметь в виду 2, учитывая формулировку вопроса.Вы можете включить требуемый результат, изменив свой запрос:

SELECT * FROM employee WHERE firstname = 'John' OR id = 42;
...