Выясните, содержит ли список объектов что-либо с указанным значением поля?
У меня есть список 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);
Ответы
Ответ 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()
в соответствии с вашей логикой.