【问题标题】:Finding out if a list of Objects contains something with a specified field value?找出对象列表是否包含具有指定字段值的内容?
【发布时间】:2011-11-20 20:01:12
【问题描述】:

我有一个从数据库收到的 DTO 列表,它们有一个 ID。我想确保我的列表包含具有指定 ID 的对象。显然,在这种情况下创建具有预期字段的对象将无济于事,因为 contains() 调用 Object.equals(),它们不会相等。

我想出了一个这样的解决方案:创建一个接口 HasId,在我所有的 DTO 中实现它,并使用具有 contains(Long id) 方法的新类继承 ArrayList。

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 年 10 月):

当然,随着 Java 8 中 lambda 的引入,实现这一点的方法很简单:

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

【问题讨论】:

  • 我确定您的意思是“发明轮子”。
  • 为什么不直接搜索列表
  • 尼山,这正是我的意思,这是一个翻译问题:D Ray Tayek,哇,这么简单而优雅的想法我什至没有想到,我会确保我'试试看,谢谢
  • 不确定我是否可以将 List 类型转换为 List
  • 感谢您使用 anyMatch() 方法进行编辑。

标签: java list object arraylist contains


【解决方案1】:

我建议像你写的那样创建简单的静态方法,没有任何额外的接口:

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

【讨论】:

  • 为了更好的代码可读性,我会从 for 和 if 中删除括号。在我看来,这是一种很好的做法。无论如何感谢这个方法!
  • hmm,就性能而言不是最佳选择,我认为@medopal的解决方案更好
  • @Choletski 这里的性能有什么问题?假设我们不使用并行计算,你不能比 O(N) 做得更好。
【解决方案2】:

我建议您只需覆盖 SearchableDto 中的 equals 就可以了:

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 列表,它们有一个 ID。

    那么您可能应该使用 DTO 类来保存这些项目。如果是这样,请将 id getter 和 setter 放入该类中:

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

    这足以遍历和 ArrayList 并搜索所需的 id。 扩展 ArrayList 类仅用于添加“compare-id”功能对我来说似乎过于复杂。 @Nikita Beloglazov 就是一个很好的例子。你可以更概括它:

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

    【讨论】:

      【解决方案4】:

      这是我在 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# 中的 Lambda 表达式比 Java 更容易使用。

      您可以使用filter函数为元素的属性添加条件。

      然后根据你的逻辑使用findFirst().get()findAny.get()

      【讨论】:

        【解决方案5】:

        你的要求我不清楚。当您说“确保我的列表包含具有指定 ID 的对象”时,您是否希望:

        1. 检测 ID 是否存在并采取相应措施
        2. 始终在结果中包含具有所需 ID 的 DTO

        大多数回答都假设您的意思是 1,但考虑到问题的措辞,您也可以表示 2。您可以通过更改查询来包含所需的结果:

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

        【讨论】:

        • 这是一个测试语句,我想确保我的 Hibernate 代码正确映射并从数据库中提取正确的值。
        • 好吧,如果这是一个特定的测试用例,那么为什么不循环检索到的对象,如果找不到所需的 ID,则测试失败呢?为什么你的所有 DTO 都为此实现 HasId 接口?
        【解决方案6】:
           public boolean containsId(List<HasId> list, long id) {
            boolean flag = false;
            for (HasId object : list) {
                if (object.getId() == id) {
                   flag = true;
                }
            }
            return flag;
        }
        

        【讨论】:

        • 最好在标志值为真时打破for each循环,而不是循环到结束
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-03
        • 1970-01-01
        • 2016-07-10
        • 2014-04-06
        • 2017-08-10
        • 2019-07-04
        相关资源
        最近更新 更多