Подтвердить что ты не робот

Выясните, содержит ли список объектов что-либо с указанным значением поля?

У меня есть список DTO, полученный от БД, и у них есть идентификатор. Я хочу, чтобы мой список содержал объект с указанным ID. Очевидно, что создание объекта с ожидаемыми полями в этом случае не поможет, потому что содержит() вызовы 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... Я бы жил с этим, но хотел убедиться, что я не изобретаю велосипед.

EDIT (октябрь '16):

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

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

Ответ 1

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

public static boolean containsId(List<DTO> list, long id) {
    for (DTO object : list) {
        if (object.getId() == id) {
            return true;
        }
    }
    return false;
}

Ответ 2

Я предлагаю вам просто переопределить 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;

Ответ 3

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

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

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

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

Это достаточно для повторения и ArrayList и поиска нужного идентификатора. Расширение класса ArrayList только для добавления "compare-id" feautre кажется слишком сложным. Хороший пример - Никита Белоглазов. Вы можете обобщить его еще больше:

public boolean containsId(List<HasId> list, long id) {
    for (HasId object : list) {
        if (object.getId() == id) {
            return true;
        }
    }
    return false;
}

Ответ 4

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

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

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

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

Ответ 5

   public boolean containsId(List<HasId> list, long id) {
    boolean flag = false;
    for (HasId object : list) {
        if (object.getId() == id) {
           flag = true;
        }
    }
    return flag;
}

Ответ 6

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

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

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

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

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