Перебрать ArrayList с несколькими условиями в Java - PullRequest
0 голосов
/ 09 февраля 2011

Сценарий: Arraylist, содержащий следующие DTO.

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");

Жезл, чтобы получить все DTO, которые удовлетворяют queryParams.Таким образом, требуемый ArrayList должен иметь все записи, которые соответствуют queryParams, поэтому в моем случае он должен исключить последнюю статью с базовым Id = SB14, потому что в этой статье State равен NH.Как построить запрос, который возвращает эти результаты?

Ответы [ 3 ]

0 голосов
/ 09 февраля 2011

Возможно, вам придется переосмыслить свои структуры данных.То, как вы их сейчас настраиваете, будет довольно сложно создать эффективный поиск.Если я понимаю, что вы ищете, следующий код должен дать вам желаемый результат:

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?Нет. Однако он возвращает список идентификаторов статей, которые соответствуют вашим критериям фильтра.Вы можете легко расширить его, чтобы вернуть список dtos, если хотите.

0 голосов
/ 09 февраля 2011

Это ужасная структура данных. Что-то вроде Map<Long,Map<Field, String>> было бы намного лучше, где Long - это articleId, Field - это список имен полей, а String - это значение поля. Для запросов вы также можете поддерживать обратное отображение пар поле / значение в идентификаторы.

Или, что еще лучше, сделайте все это в рамках ORM / JPA и позвольте СУБД выполнить всю тяжелую работу за вас.

0 голосов
/ 09 февраля 2011
for (MetadatRetrievalDTO dto : dtos) {
    for (Map.Entry entry : queryParams.entrySet()) {
        if (dto.getMetadataName().equals(entry.getKey()) && dto.getMetadataValue().equals(entry.getValue())) {
            // dto matches
        }
    } }

Не уверен, если это то, что вы имеете в виду ... Но вы должны рассмотреть индексацию или что-то в этом роде ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...