【问题标题】:Iterate over an ArrayList with multiple condition in Java在 Java 中迭代具有多个条件的 ArrayList
【发布时间】:2011-02-08 22:48:22
【问题描述】:

场景:包含以下 DTO 的 Arraylist。

MetadatRetrievalDTO[] dto  = new MetadatRetrievalDTO[16];

dto[0] = new MetadatRetrievalDTO();
dto[0].setArticleId(11);
dto[0].setBaseId("SB11");
dto[0].setMetadataName("TYPE");
dto[0].setMetadataValue("RANCH");

dto[1] = new MetadatRetrievalDTO();
dto[1].setArticleId(11);
dto[1].setBaseId("SB11");
dto[1].setMetadataName("PRICE");
dto[1].setMetadataValue("1200000");

dto[2] = new MetadatRetrievalDTO();
dto[2].setArticleId(11);
dto[2].setBaseId("SB11");
dto[2].setMetadataName("STATE");
dto[2].setMetadataValue("NJ");

dto[3] = new MetadatRetrievalDTO();
dto[3].setArticleId(11);
dto[3].setBaseDocId("SB11");
dto[3].setMetadataName("REGION");
dto[3].setMetadataValue("NE");
//////////////////////////////////////////////////////
dto[4] = new MetadatRetrievalDTO();
dto[4].setArticleId(12);
dto[4].setBaseId("SB12");
dto[4].setMetadataName("TYPE");
dto[4].setMetadataValue("RANCH");

dto[5] = new MetadatRetrievalDTO();
dto[5].setArticleId(12);
dto[5].setBaseId("SB12");
dto[5].setMetadataName("PRICE");
dto[5].setMetadataValue("1200001");

dto[6] = new MetadatRetrievalDTO();
dto[6].setArticleId(12);
dto[6].setBaseId("SB12");
dto[6].setMetadataName("STATE");
dto[6].setMetadataValue("NJ");

dto[7] = new MetadatRetrievalDTO();
dto[7].setArticleId(12);
dto[7].setBaseId("SB12");
dto[7].setMetadataName("REGION");
dto[7].setMetadataValue("NE");

//////////////////////////////////////////////////////
dto[8] = new MetadatRetrievalDTO();
dto[8].setArticleId(13);
dto[8].setBaseId("SB13");
dto[8].setMetadataName("TYPE");
dto[8].setMetadataValue("RANCH");

dto[9] = new MetadatRetrievalDTO();
dto[9].setArticleId(13);
dto[9].setBaseId("SB13");
dto[9].setMetadataName("PRICE");
dto[9].setMetadataValue("1200002");

dto[10] = new MetadatRetrievalDTO();
dto[10].setArticleId(13);
dto[10].setBaseId("SB13");
dto[10].setMetadataName("STATE");
dto[10].setMetadataValue("NJ");

dto[11] = new MetadatRetrievalDTO();
dto[11].setArticleId(13);
dto[11].setBaseId("SB13");
dto[11].setMetadataName("REGION");
dto[11].setMetadataValue("NE");


//////////////////////////////////////////////////////
dto[12] = new MetadatRetrievalDTO();
dto[12].setArticleId(14);
dto[12].setBaseId("SB14");
dto[12].setMetadataName("TYPE");
dto[12].setMetadataValue("RANCH");

dto[13] = new MetadatRetrievalDTO();
dto[13].setArticleId(14);
dto[13].setBaseId("SB14");
dto[13].setMetadataName("PRICE");
dto[13].setMetadataValue("1200003");

dto[14] = new MetadatRetrievalDTO();
dto[14].setArticleId(14);
dto[14].setBaseId("SB14");
dto[14].setMetadataName("STATE");
dto[14].setMetadataValue("NH");

dto[15] = new MetadatRetrievalDTO();
dto[15].setArticleId(14);
dto[15].setBaseId("SB14");
dto[15].setMetadataName("REGION");
dto[15].setMetadataValue("NE");

每篇文章的 BaseID 都是唯一的。搜索条件是:

HashMap<String,String> queryParams = new HashMap<String, String>();
    queryParams.put("TYPE","RANCH");
    queryParams.put("STATE","NJ");
    queryParams.put("REGION","NE");

我想获得所有满足queryParams 的 DTO。 因此,所需的 ArrayList 应该包含与 queryParams 匹配的所有记录,因此在我的情况下,它应该排除最后一篇基本 Id = SB14 的文章,因为在本文中 StateNH。如何构建返回这些结果的查询?

【问题讨论】:

    标签: java arraylist iterator


    【解决方案1】:

    您可能需要重新考虑您的数据结构。按照您当前设置它们的方式,创建有效的搜索将相当困难。如果我了解您正在寻找的内容,以下代码应该可以为您提供所需的结果:

    private Set filter(MetadatRetrievalDTO[] data, Map<String, String> filter) {
            Set<Integer> rtnIdSet = new HashSet();
            for (MetadatRetrievalDTO dto : data) {
                rtnIdSet.add(dto.getArticleId());
            }
    
            Set<Integer> filterSet = new HashSet();
            for (String key : filter.keySet()) {
                filterSet.clear();
                String value = filter.get(key);
                for (MetadatRetrievalDTO dto : data) {
                    if (key.equals(dto.getMetadataName()) && value.equals(dto.getMetadataValue())) {
                        filterSet.add(dto.getArticleId());
                    }
                }
    
                rtnIdSet.retainAll(filterSet);
            }
    
            return  rtnIdSet;
        }

    这是优化的吗?不。它是否返回 DTO 的数组?不会。但是,它会返回与您的过滤条件匹配的文章 ID 列表。如果需要,您可以轻松扩展它以返回 dto 列表。

    【讨论】:

    • 感谢 Kris 的回答,我知道使用的数据结构不是最佳的,但这是遗留代码,我正在进行更改以满足一些小要求。
    【解决方案2】:
    for (MetadatRetrievalDTO dto : dtos) {
        for (Map.Entry entry : queryParams.entrySet()) {
            if (dto.getMetadataName().equals(entry.getKey()) && dto.getMetadataValue().equals(entry.getValue())) {
                // dto matches
            }
        } }
    

    不确定这是不是你的意思......但你应该考虑索引或类似的东西......

    【讨论】:

      【解决方案3】:

      这是一个糟糕的数据结构。像Map&lt;Long,Map&lt;Field, String&gt;&gt; 这样的东西会更好,其中Long 是articleId,Field 是字段名称的枚举,String 是字段值。对于查询,您还可以维护字段/值对到 id 的逆映射。

      或者,更好的是,在 ORM/JPA 框架中完成所有这些工作,让 DBMS 为您完成所有繁重的工作。

      【讨论】:

        猜你喜欢
        • 2013-01-17
        • 2012-06-09
        • 1970-01-01
        • 2011-05-25
        • 2011-09-11
        • 2013-11-13
        • 2016-08-31
        • 2016-05-01
        • 2021-01-29
        相关资源
        最近更新 更多