Выяснить, содержит ли список объектов что-то с указанным значением поля?
у меня есть список DTO, полученный от БД, и у них есть идентификатор. Я хочу убедиться, что мой список содержит объект с указанным ID. По-видимому, создание объекта с ожидаемыми полями в этом случае не поможет, потому что contains () вызывает Object.Equals(), и они не будут равны.
Я подошел к решению так: создал интерфейс HasId
, реализовал его во всех моих DTOs и унаследовал 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;
}
}
но в этом случае я не могу напечатать список и ArrayList в SearchableList... Я бы с этим смирился, но хотел убедиться, что не изобрету велосипед.
EDIT (Oct ' 16):
конечно, с введением lambdas в Java 8 способ сделать это прост:
list.stream().anyMatch(dto -> dto.getId() == id);
6 ответов
Я предлагаю создать простой статический метод, как вы написали, без каких-либо дополнительных интерфейсов:
public static boolean containsId(List<DTO> list, long id) {
for (DTO object : list) {
if (object.getId() == id) {
return true;
}
}
return false;
}
Я предлагаю вам просто переопределить 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
;
Ну, я думаю, что ваш подход немного усложнять проблему. Ты сказал:
у меня есть список DTO, полученный от БД, и у них есть идентификатор.
тогда, вероятно, вам следует использовать класс DTO для хранения этих элементов. Если это так, поместите ID getter и setter внутри этого класса:
public class DTO implements HasId{
void setId(Long id);
Long getId();
}
этого достаточно для перебора и ArrayList и поиска нужного идентификатора. Расширение класса ArrayList только для добавления feautre "compare-id" кажется я слишком запутался. @Nikita Beloglazov - хороший пример. Вы можете обобщить его еще больше:
public boolean containsId(List<HasId> list, long id) {
for (HasId object : list) {
if (object.getId() == id) {
return true;
}
}
return false;
}
вы требование не ясно для меня. Когда вы говорите: "убедитесь, что мой список содержит объект с указанным идентификатором", вы хотите:
- обнаружить, если ID присутствует и действовать соответственно
- всегда включайте DTO с требуемым идентификатором в результаты
большинство ответов предполагали, что вы имеете в виду 1, однако, думая об этом, вы могли бы также означать 2, учитывая формулировку вопроса. Вы можете включить требуемый результат, изменив ваш запрос:
SELECT * FROM employee WHERE firstname = 'John' OR id = 42;
public boolean containsId(List<HasId> list, long id) {
boolean flag = false;
for (HasId object : list) {
if (object.getId() == id) {
flag = true;
}
}
return flag;
}
это то, что я использовал в своей функции 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()
согласно вашей логике.