Java 스트림을 사용한 문자열 작업
1. Stream API를 사용하여 문자열 결합
Stream API를 사용하여 String 배열을 쉼표로 구분된 String으로 결합하는 함수를 만들어 본다.
1
2
3
4
5
6
public static String join(String[] arrayOfString){
return Arrays.asList(arrayOfString)
.stream()
//.map(...)
.collect(Collectors.joining(","));
}
여기서 주의할 점 이다.
stream()
함수는 모든 컬렉션을 데이터 스트림으로 변환한다.map()
함수는 데이터를 처리하는데 사용된다.필터링 기준을 포함할 수 있는
filter()
라는 또 다른 함수도 있다.
고정된 접두사와 접미사를 사용하여 문자열을 결합하려는 시나리오가 있을 수 있다. Stream API를 사용하면 다음과 같은 방법으로 이를 수행할 수 있다.
1
2
3
4
5
6
public static String joinWithPrefixPostfix(String[] arrayOfString){
return Arrays.asList(arrayOfString)
.stream()
//.map(...)
.collect(Collectors.joining(",","[","]"));
}
Collectors.joining()
메소드에서 볼 수 있듯이 접두어를 ‘[’ 로 선언 하고 접미어를 ‘]’ 로 선언한다. 따라서 생성된 문자열은 선언된 [...]
형식으로 생성된다.
2. Stream API를 사용하여 문자열 분할
Stream API를 사용하여 쉼표로 구분된 문자열을 문자열 목록으로 분할하는 함수를 만들어 본다.
1
2
3
4
5
public static List<String> split(String str){
return Stream.of(str.split(","))
.map (elem -> new String(elem))
.collect(Collectors.toList());
}
Stream API를 사용하여 문자열을 문자 목록 으로 직접 변환하는 것도 가능하다.
1
2
3
4
5
public static List<Character> splitToListOfChar(String str) {
return str.chars()
.mapToObj(item -> (char) item)
.collect(Collectors.toList());
}
chars()
메서드가 String을 Integer 스트림으로 변환한다. 여기서 각 Integer 값은 각각의 Char 시퀀스의 ASCII 값을 나타낸다. 그렇기 때문에 mapToObj()
메서드에서 매퍼 객체를 명시적으로 형변환해야 한다.
3. Stream API로 매핑할 문자열 배열
배열의 각 항목에 구분 기호로 연결된 key-value 엔터티가 포함되어 있는 경우 분할 및 Collectors.toMap
을 사용하여 문자열 배열을 매핑 하도록 변환할 수도 있다.
1
2
3
4
5
6
public static Map<String, String> arrayToMap(String[] arrayOfString) {
return Arrays.asList(arrayOfString)
.stream()
.map(str -> str.split(":"))
.collect(toMap(str -> str[0], str -> str[1]));
}
여기서 “:” 은 문자열 배열의 모든 요소에 대한 key-value 구분 기호이다.
컴파일 오류를 방지하려면 코드가 Java 1.8을 사용하여 컴파일되었는지 확인해야 한다. 이렇게 하려면 pom.xml
에 다음 플러그인을 추가해야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
4. 테스트
함수 생성이 완료되었으므로 결과를 확인하기 위한 테스트 케이스를 생성해 본다.
먼저 간단한 조인 방법을 테스트해 본다.
1
2
3
4
5
6
7
8
@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);
}
다음으로 간단한 분할 기능을 테스트하기 위해 또 다른 것을 만들어 본다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void givenString_transformedToStream_convertToList() {
String programmingLanguages = "java,python,nodejs,ruby";
List<String> expectation = new ArrayList<>();
expectation.add("java");
expectation.add("python");
expectation.add("nodejs");
expectation.add("ruby");
List<String> result = JoinerSplitter.split(programmingLanguages);
assertEquals(result, expectation);
}
마지막으로 기능을 매핑하기 위해 문자열 배열을 테스트해 본다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void givenStringArray_transformedToStream_convertToMap() {
String[] programming_languages = new String[] {"language:java","os:linux","editor:emacs"};
Map<String,String> expectation=new HashMap<>();
expectation.put("language", "java");
expectation.put("os", "linux");
expectation.put("editor", "emacs");
Map<String, String> result = JoinerSplitter.arrayToMap(programming_languages);
assertEquals(result, expectation);
}
같은 방식으로 나머지 테스트 케이스도 생성해야 한다.