Как я могу передать карту <String, List <Object> в поток <Entry <String, Object >>?

У меня есть Map<String, List<Object>>.

Как я могу сделать это в потоке Entry<String, Object>, чтобы я мог построить конкатенированный запрос String?

q1    a, b
q2    c, d

в

q1=a&q1=b&q2=c&q2=d

В настоящее время я это делаю.

if (params != null && !params.isEmpty()) {
    final boolean[] flag = new boolean[1];
    params.forEach((n, vs) -> {
        vs.forEach(v -> {
            builder.append(flag[0] ? '&' : '?')
                    .append(n)
                    .append('=')
                    .append(v);
            if (!flag[0]) {
                flag[0] = true;
            }
        });
    });
}

Ответ 1

Ну, вам не нужно создавать Entry<String, Object>. Вы можете использовать flatMap для получения ключа = значение String и напрямую построить запрос String с помощью Collectors.joining:

String query =
    map.entrySet()
       .stream()
       .flatMap(e -> e.getValue().stream().map(v -> e.getKey() + '=' + v))
       .collect(Collectors.joining("&"));

Вход:

{q1=[a, b], q2=[c, d]}

Выход:

q1=a&q1=b&q2=c&q2=d

Ответ 2

Если у вас есть Guava, вам может потребоваться использовать ListMultimap<String, Object> вместо Map<String, List<Object>> и создать свою строку следующим образом:

String query = Joiner.on("&").withKeyValueSeparator("=").join(map.entries());