Ошибка несовместимых типов при использовании потока и сборщика с ArrayList of Maps - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть такой код:

    ArrayList<Map<String, String>> resultArray = resultList.stream() //
            .map(parser::parseJson) //
            .filter(ev -> ev.entrySet().containsAll(filter.entrySet())) //
            .collect(Collectors.toCollection(ArrayList::new));

Вызывающая сторона resultList - это ArrayList, который представляет собой массив JSON.Я хочу проанализировать каждый элемент на карте, отфильтровать карту и собрать массивы карт.

Код в приведенной выше строке не содержит ошибку компилятора.Но во время выполнения выдает ошибку как:

Error:(51, 25) java: incompatible types: cannot infer type-variable(s) 
R,A,capture#1 of ?,T,C,E (argument mismatch;
java.util.stream.Collector<java.util.Map<java.lang.String,java.lang.String>,capture#2 of 
?,java.util.ArrayList<java.util.Map<java.lang.String,java.lang.String>>
> cannot be converted to java.util.stream.Collector<? super 
java.util.Map,capture#2 of 
?,java.util.ArrayList<java.util.Map<java.lang.String,java.lang.String>>
>)

Я пробовал много разных способов, таких как Collectors.toList(), но это не работает.Я до сих пор ищу чистое решение для анализа каждого элемента String на карте и сбора всех их в виде ArrayList.

Обновление: анализатор с com.json.parsers.JSONParser;

1 Ответ

0 голосов
/ 21 сентября 2018

Согласно (почти загадочному) сообщению об ошибке, проблема заключается в методе parseJson вашего экземпляра parser, который возвращает необработанный Map, т. Е. Карту, в которой не указаны типы ееключи и значения.

Этот метод необходим для возврата Map<String, String> или, по крайней мере, универсального, чтобы он мог возвращать требуемый тип.


РЕДАКТИРОВАТЬ: Я никогда не слышал о вашем парсере JSON.Быстрый поиск в Google показал, что он почти не используется и кажется, что это архивный проектЯ настоятельно рекомендую вам перейти на более качественную библиотеку JSON, такую ​​как Jackson, Gson или, может быть, JSON.simple.

Быстрое и грязное решение с использованием того, что у вас уже есть, - привести возвращенную карту к Map<String, String>., если вы уверены, что у вас действительно есть строки в качестве значений для всех ваших ключей (в противном случае вы можете столкнуться с ужасной ClassCastException).

Для этого вам нужно изменить код на:

List<Map<String, String>> resultArray = resultList.stream()
    .map(json -> (Map<String, String>) parser.parseJson(json))
    .filter(ev -> ev.entrySet().containsAll(filter.entrySet()))
    .collect(Collectors.toCollection(ArrayList::new));

Но, опять же, имейте в виду, что это не очень чисто, и что вы можете вносить больше ошибок с этим составом.Лучшее решение - использовать Джексона:

ObjectMapper mapper = new ObjectMapper(); // Jackson JSON lib entry-point

List<Map<String, String>> resultArray = resultList.stream()
    .map(json -> {
        try {
            return mapper.readValue(json, new TypeReference<Map<Striong, String>>() {});
        } catch (IOException e) {
            throw new UncheckedIOExpcetion(e);
        }
    })
    .filter(ev -> ev.entrySet().containsAll(filter.entrySet()))
    .collect(Collectors.toCollection(ArrayList::new));

Рекомендация: лучше переместить весь блок try / catch внутри операции map в закрытый метод, который возвращает Map<String, String>.

...