Есть ли способ отфильтровать подходящие подстроки из списка строк ArrayList с помощью потоков Java?

Есть ли способ добиться этого с помощью Java Streams?

List<String> list = new ArrayList<>();
list.add("x=aa,y=bb,y=cc");
list.add("y=dd,z=ee,w=ff");
list.add("w=gg,w=hh,w=ii");

и я хочу отфильтровать выше ArrayList, чтобы он содержал только строковые значения типа «y». Как ниже

list=["bb","cc","dd"]

Я могу добиться этого, используя несколько строк кода, используя String.split(",") и вставляя подходящую подстроку в новый ArrayList. Но есть ли чистый способ добиться этого с помощью Java Streams?

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

Ответы 2

Ответ принят как подходящий

Ты спрашивал:

is there a clean way to achieve this using Java Streams?

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

Сначала определите некоторые примеры данных, входы список.

Создайте поток из этого списка. Этот поток имеет 3 элемента, учитывая данные нашего примера.

Вызовите Stream#flatMap, чтобы вернуть новый поток, элементы которого состоят из частей элементов исходного потока. Новый поток состоит из 9 элементов, полученных путем разбиения каждого из 3 исходных элементов на 3 части (3 * 3 = 9).

Фильтр — новый более длинный поток для элементов, текст которых начинается с нашего целевого префикса y=.

Преобразуйте каждый из строковых элементов, которые прошли тест предикат нашего фильтра. Используйте простые манипуляции со строками для заменять "y=" с пустой строкой. Таким образом, значение, такое как y=bb, становится bb.

Соберите преобразованные строки, объединив их в новый объект List.

List < String > inputs =
        List.of(
                "x=aa,y=bb,y=cc" ,
                "y=dd,z=ee,w=ff" ,
                "w=gg,w=hh,w=ii"
        );
List < String > results =
        inputs
                .stream()                                                 // Generate stream whose elements are each of the list’s elements.
                .flatMap( input -> Arrays.stream( input.split( "," ) ) )  // Break each element into parts, feeding each part into a new longer stream.
                .filter( pairing -> pairing.startsWith( "y = " ) )          // Filter out any strings not beginning with `y=`. 
                .map( pairing -> pairing.replace( "y = " , "" ) )           // A value such as `y=bb` becomes `bb`.
                .toList();                                                // Collect transformed strings into a new list.

Когда бег.

results.toString() = [bb, cc, dd]

Чтобы отсортировать результаты, добавьте вызов .sorted() перед toList().

Вот один из способов.

List<String> list = new ArrayList<>();
list.add("x=aa,y=bb,y=cc");
list.add("y=dd,z=ee,w=ff");
list.add("w=gg,w=hh,w=ii");
List<String> result = getListOf(list,"y");
System.out.println(result);

отпечатки

[bb, cc, dd]
  • поток строк и разделение на ","
  • затем разделите их на " = ", который возвращает массивы, такие как arr = [x,aa]
  • затем отфильтруйте arr[0] и верните arr[1], если он совпадает.
  • и вернуть результирующий список.
public static List<String> getListOf(List<String> items, String key) {
    return items.stream()
            .flatMap(str -> Arrays.stream(str.split(",")))
            .map(str -> str.split(" = "))
            .filter(s -> s[0].equals(key))
            .map(s -> s[1])
            .toList();
    
}

Вы можете избежать flatMapping, используя mapMulti (Java 16). Примечание: украл идею startsWith из ответа Бэзил Бурк.

public static List<String> getListOf(List<String> items, String key) {
     final String kk = key+" = "; 
     return items.stream().<String>mapMulti((str,putOnStream)-> {
            for (String s : str.split(",")) {
                  if (s.startsWith(kk)) {    
                      putOnStream.accept(s.substring(kk.length()));
                  }
             }})
             .toList();
}

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