Строковые операции с потоками Java

Строковые операции с потоками Java

1. обзор

В Java 8 появился новый APIStream, который позволяет нам обрабатывать данные декларативным образом.

В этой быстрой статье мы узнаем, как использовать APIStream для разделения разделенных запятымиString на списокStrings и как объединить массивString в String через запятую.

Мы также рассмотрим, как преобразовать массив строк в карту с помощью APIStream.

Практически все время мы сталкиваемся с ситуациями, когда нам нужно перебрать несколькоJava Collections и отфильтроватьCollection на основе некоторой логики фильтрации. В традиционном подходе для такого типа ситуации мы использовали бы множество циклов и операций if-else, чтобы получить желаемый результат.

Если вы хотите узнать больше об APIStream, проверьтеthis article.

2. Объединение строк с помощью APIStream

Давайте воспользуемся APIStream, чтобы создать функцию, которая объединит массивString в разделенный запятымиString:

public static String join(String[] arrayOfString){
    return Arrays.asList(arrayOfString)
      .stream()
      //.map(...)
      .collect(Collectors.joining(","));
}

Здесь стоит отметить:

  • Функцияstream() преобразует любойCollection в поток данных

  • Функцияmap() используется для обработки данных

  • Также есть еще одна функция с именемfilter(), в которую мы можем включить критерии фильтрации

Могут быть сценарии, в которых мы можем захотеть присоединиться кString с некоторым фиксированным префиксом и постфиксом. С APIStream мы можем сделать это следующим образом:

public static String joinWithPrefixPostfix(String[] arrayOfString){
    return Arrays.asList(arrayOfString)
      .stream()
      //.map(...)
      .collect(Collectors.joining(",","[","]"));
}

Как мы видим в методеCollectors.joining(), мы объявляем наш префикс как‘[‘ и постфикс как‘]'; следовательно, сгенерированныйString будет создан с объявленным форматом[…..].

3. РазделениеStrings с помощью APIStream

Теперь давайте создадим функцию, которая с помощью APIStream разделит разделенные запятымиString на списокString:

public static List split(String str){
    return Stream.of(str.split(","))
      .map (elem -> new String(elem))
      .collect(Collectors.toList());
}

Также возможно напрямую преобразоватьString в списокCharacter с помощью APIStream:

public static List splitToListOfChar(String str) {
    return str.chars()
      .mapToObj(item -> (char) item)
      .collect(Collectors.toList());
}

Здесь следует отметить один интересный факт: методchars() преобразуетString в потокInteger, где каждое значениеInteger обозначает значениеASCII каждого и каждую последовательностьChar. Вот почему нам нужно явно указать тип объекта сопоставления в методеmapToObj().

4. String array вMap withStream API

Мы также можем преобразовать массивString в карту, используяsplit andCollectors.toMap, при условии, что каждый элемент в массиве содержит сущность «ключ-значение», объединенную разделителем:

public static Map arrayToMap(String[] arrayOfString) {
    return Arrays.asList(arrayOfString)
      .stream()
      .map(str -> str.split(":"))
      .collect(toMap(str -> str[0], str -> str[1]));
}

Здесь“:” - это разделитель значений ключа для всех элементов в массиве String.

Please remember that in order to avoid compilation error, we need to ensure that code is compiled using Java 1.8. Для этого нам нужно добавить вpom.xml следующий плагин:


    
      
        org.apache.maven.plugins
        maven-compiler-plugin
        3.3
        
          1.8
          1.8
        
      
    

5. тестирование

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

Во-первых, давайте протестируем наш простой метод соединения:

@Test
public void givenArray_transformedToStream_convertToString() {
    String[] programmingLanguages = {"java", "python", "nodejs", "ruby"};
    String expectation = "java,python,nodejs,ruby";

    String result  = JoinerSplitter.join(programmingLanguages);
    assertEquals(result, expectation);
}

Затем давайте создадим еще один, чтобы протестировать нашу простую функцию разделения:

@Test
public void givenString_transformedToStream_convertToList() {
    String programmingLanguages = "java,python,nodejs,ruby";

    List expectation = new ArrayList<>();
    expectation.add("java");
    expectation.add("python");
    expectation.add("nodejs");
    expectation.add("ruby");

    List result  = JoinerSplitter.split(programmingLanguages);

    assertEquals(result, expectation);
}

Наконец, давайте протестируем наш массивString для отображения функциональности:

@Test
public void givenStringArray_transformedToStream_convertToMap() {

    String[] programming_languages = new String[] {"language:java","os:linux","editor:emacs"};

    Map expectation=new HashMap<>();
    expectation.put("language", "java");
    expectation.put("os", "linux");
    expectation.put("editor", "emacs");

    Map result = JoinerSplitter.arrayToMap(programming_languages);
    assertEquals(result, expectation);

}

Точно так же нам нужно создать остальные тестовые случаи.

6. Заключение

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

Как всегда, доступен полный исходный кодover on Github.