Струнни операции с Java потоци

1. Общ преглед

Java 8 представи нов Stream API, който ни позволява да обработваме данни по декларативен начин.

В тази бърза статия ще научим как да използваме API на Stream за разделяне на разделен със запетая низ в списък от низове и как да се присъединим към масив от низове в разделен със запетая низ .

Също така ще разгледаме как да преобразуваме масив от низове в map с помощта на Stream API.

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

Ако искате да прочетете повече за Stream API, проверете тази статия.

2. Присъединяване на низове с Stream API

Да използваме Stream API за създаване на функция, която ще се присъедини към String масив в разделени със запетая, String :

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

Точки за отбелязване тук:

  • Функцията stream () преобразува всяка колекция в поток от данни
  • Функцията map () се използва за обработка на данните
  • Има и друга функция, наречена filter () , където можем да включим критерии за филтриране

Възможно е да има сценарии, при които може да се наложи да се присъединим към String с някакъв фиксиран префикс и postfix. С API на Stream можем да направим това по следния начин:

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

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

3. Разделяне на низове с Stream API

Сега, нека създадем функция, която ще раздели String, разделен със запетая, в списък от String, използвайки Stream API:

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

Също така е възможно директно преобразуване на String в списък с символи с помощта на Stream API:

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

Един интересен факт, който трябва да отбележим тук, е, че методът chars () преобразува String в поток от Integer, където всяка Integer стойност обозначава ASCII стойността на всяка последователност Char . Ето защо трябва изрично да напечатаме обекта на mapper в метода mapToObj () .

4. String Array to Map With Stream API

Също така можем да преобразуваме String масив в map с помощта на split и Collectors.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.

Моля, не забравяйте, че за да избегнем грешка при компилацията, трябва да гарантираме, че кодът се компилира с помощта на 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. Заключение

API на Stream ни предоставя усъвършенствани техники за обработка на данни. Този нов начин за писане на код е много ефективен по отношение на управлението на куп памет в многонишка среда.

Както винаги, пълният изходен код е достъпен в Github.