Как передать карту со значениями Stream<String> с помощью Stream API?

У меня есть карта Map<String, Stream<String>>. Мне нужно построить отсортированный поток всех участников без дублирования, игнорировать нулевые или пустые строки, обрезать лишние пробелы и изменить каждый на Заголовок.

Например, для данной карты:

{
  "A"=["B", "C", " D  "],
  "B"=["kas", "B", "c ", "dddd"]
}

Я должен получить:

["B", "C", "D", "Dddd", "Kas"]

Мне нужно создать такой метод:

public Stream<String> listN(Map<String, Stream<String>> map) {
    map.values().stream()... ?
}

но я даже не знаю, как начать.

Ваша карта не очень хорошая идея. Поток можно использовать только один раз. Лучше бы Map<String, Suppler<Stream<String>>.

user207421 17.05.2023 04:15
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Если я правильно понял, и вам не нужно использовать ключи карты, тогда вы можете использовать метод значений() карты, использовать для них flatMap, чтобы сгладить результаты (возможно, вам придется сначала сопоставить списки с потоком), а затем вы можете использовать sorted() и, наконец, Different(), все методы Stream.

спасибо за идею, но как я могу игнорировать лишние пробелы и чувствительность к регистру?

pure21_h 16.05.2023 23:27
Ответ принят как подходящий

Поток значений карты, флапмап в поток строк, затем примените различные фильтры и модификации, разные, сортируйте:

public Stream<String> listN(Map<String, Stream<String>> map) {
    return map.values().stream()
      .flatMap(s -> s)
      .filter(Objects::nonNull)
      .filter(Predicate.not(String::isBlank))
      .map(String::trim)
      .map(String::toLowerCase)
      .map(s -> s.substring(0, 1).toUpperCase() + s.substring(1))
      .distinct()
      .sorted();
}

Смотрите живую демонстрацию.

Ваш вопрос и имя вашего метода, похоже, указывают на то, что вы хотите вернуть список, а не поток. Возможно, вы также хотели использовать Map<String, List<String>> (но тогда я не знаю вашего варианта использования). В любом случае это возвращает List<String>, но, что более важно, демонстрирует предложение @user20742 использовать Map<String, Supplier<Stream<String>>>, чтобы карту можно было использовать повторно, если это необходимо. В противном случае карта переживет только один вызов, и потоки будут исчерпаны.

Map<String, Supplier<Stream<String>>> map = Map.of("A",
        () -> Stream.of("B", "C", " D ",null), "B",
        () -> Stream.of("kas", "B", "c ", "dddd"));

for (int i = 0; i < 3; i++) {
    List<String> list = listN(map);
    System.out.println(list);
}

отпечатки

[B, C, D, Dddd, Kas]
[B, C, D, Dddd, Kas]
[B, C, D, Dddd, Kas]

С исходной картой она печаталась один раз, а затем выдавала IllegalStateException, показывающую, что потоки были использованы.

Модифицированный метод ниже возвращает список, используя описанную карту. Поскольку метод, похоже, не использует instance fields, я объявил его static. За исключением некоторых небольших изменений, здесь используются те же конструкции, что и в ответе Bohemian. Основное отличие заключается в вызове .get() для получения потока от поставщика.

public List<String> listN(Map<String, Supplier<Stream<String>>> map) {
   return map.values().stream().flatMap(a -> a.get())
           .filter(str-> str != null && !str.isBlank())
           .map(a -> {
               a = a.trim();
               return a.substring(0, 1).toUpperCase() + a.substring(1);
           }).distinct().sorted().toList();
}

Другие вопросы по теме

NodeJS Streams — завершает поток чтения в конвейере, но продолжает обрабатывать уже прочитанные фрагменты
Как обрабатывать несколько потоков во Flutter с помощью signalr, обмена сообщениями Firebase и локальных уведомлений Flutter
Преобразование списка объектов в список с уникальным списком объектов
Rust Streams: как преобразовать TryStream<Ok = Vec<Item>, Error = MyErrorType>> в TryStream<Ok = Item, Error = MyErrorType>
Как вернуть фрагментированный текст/простой контент из веб-API, используя минимальный API
Как использовать stimulus и turbo_stream для элементов, которые часто меняются?
Java использует потоки для изменения вложенного списка и возврата родительского списка
Перепроверьте интернет-соединение во флаттере только при нажатии кнопки повторной попытки
Как преобразовать список строк с дубликатами в список строк только с разными символами, используя потоки API в Java?
Как вернуть результат index.query(query, streaming=True) llama_index?