[자바, Java] Stream - Collectors.joining()
Stream 의 joining 사용법
프로그래머스를 통해 알고리즘 문제를 풀었는데, 내가 for문으로 String 을 이어 붙여서 반환한 것과 다르게,
다른 분의 풀이 방법에서 Stream 의 Collectors.joining() 로 쉽게 답을 반환하는 모습이 보였다.
toList() 같은 컬렉션 반환 방법만 알고있었지, String 배열을 이어붙여서 하나의 String 으로 반환시키는 기능은 몰랐다.
이번에 joining 에대해 공부한 만큼 정리해보고자 한다.
1. joining() 메서드는 무엇일까??
문자열 스트림의 모든 요소를 하나의 문자열로 연결해서 반환하는 역할을 가진다.
- joining() 에 인자를 안주면 그대로 이어붙이고, 인자를 주면 요소들의 사이마다 인자를 넣어서 이어붙인다.
2. Collectors.joining() 의 실제 구현 모습
public static Collector<CharSequence, ?, String> joining() { return new CollectorImpl<CharSequence, StringBuilder, String>( StringBuilder::new, StringBuilder::append, (r1, r2) -> { r1.append(r2); return r1; }, StringBuilder::toString, CH_NOID); }
위 구현 모습을 최대한 풀어서 이해해 보자면,
- StringBuilder 를 생성한다.
- StringBuilder 로 모든 요소를 append 한다.
- append 한 StringBuilder 를 String 으로 반환한다.
3. joining() 사용법
3-1. 문자열(String)의 문자들을 역정렬해서 반환
예시
class Scratch { public static void main(String[] args) { String s = "dafaafq"; String collect = Stream.of(s.split("")) .sorted(Comparator.reverseOrder()) .collect(Collectors.joining()); System.out.println(collect); } } // 출력 결과 // qffdaaa
- 문자열의 문자들을 역정렬 시킨 후, 다시 그대로 이어붙여서 반환하는 모습을 볼 수 있다.
3-2. 접두사와 접미사를 붙여서 반환
예시
class Scratch { public static void main(String[] args) { String s = "dafaafq"; String collect = Stream.of(s.split("")) .sorted(Comparator.reverseOrder()) .collect(Collectors.joining(", ", "[", "]")); System.out.println(collect); } } // 출력 결과 // [q, f, f, d, a, a, a]
문자열의 문자들을 역정렬 시킨 후, ‘쉼표 + 띄어쓰기’를 요소들 사이마다 넣어준 뒤, 접두어에 “[” 를, 접미어에 “]” 를 붙여서 String으로 반환한다.
- 참고로 이건 배열출력이 아닌 String 출력임을 주의하자.
- 일부러 배열출력과 같은 형식의 출력 형식으로 만들어보았다.
- 참고로 이건 배열출력이 아닌 String 출력임을 주의하자.
3-3. String 뿐만이 아닌 CharSequence 인터페이스를 구현한 클래스 타입의 배열은 전부 사용 가능 - StringBuilder, StringBuffer, String 등등
예시
class Scratch { public static void main(String[] args) { StringBuilder[] s = {new StringBuilder("aa"), new StringBuilder("cc"), new StringBuilder("bb")}; String collect = Stream.of(s).collect(Collectors.joining()); System.out.println(collect); } } // 출력 결과 // aaccbb class Scratch { public static void main(String[] args) { StringBuffer[] s = {new StringBuffer("aa"), new StringBuffer("cc"), new StringBuffer("bb")}; String collect = Stream.of(s).collect(Collectors.joining()); System.out.println(collect); } } // 출력 결과 // aaccbb
- StringBuilder, StringBuffer 의 배열을 만들고 바로 joining 메서드를 사용해서 이어붙이고, String 으로 반환한다.
근데 사실 CharSequence 구현체를 이어붙여서 String으로 반환하는 방법은 String.join() 메서드를 통해 더 쉽게 이어붙일 수 있다.
예시
class Scratch { public static void main(String[] args) { StringBuilder[] s = {new StringBuilder("aa"), new StringBuilder("cc"), new StringBuilder("bb")}; String collect = String.join("", s); System.out.println(collect); } } // 출력 결과 // aaccbb class Scratch { public static void main(String[] args) { StringBuffer[] s = {new StringBuffer("aa"), new StringBuffer("cc"), new StringBuffer("bb")}; String collect = String.join("", s); System.out.println(collect); } } // 출력 결과 // aaccbb
3-4. 객체의 toString 을 이용해서 결합
예시
class Scratch implements Comparable<Scratch> { String name; int age; public Scratch(String name, int age) { this.name = name; this.age = age; } public static void main(String[] args) { Scratch jun = new Scratch("jun", 29); Scratch sin = new Scratch("sin", 23); Scratch moon = new Scratch("moon", 25); Scratch[] scArr = {jun, sin, moon}; String collect = Stream.of(scArr) .sorted(Comparator.reverseOrder()) // 나이를 기준으로 내림차순 정렬을 한다. .map(Object::toString) // 객체의 toString 값을 가져온다. .collect(Collectors.joining("\n")); // 개행문자로 joining 한다. System.out.println(collect); } @Override public int compareTo(Scratch o) { return this.age - o.age; // 나이순으로 오름차순 정렬 } @Override public String toString() { return "Scratch{" + "name='" + name + '\'' + ", age=" + age + '}'; } } // 출력 결과 // Scratch{name='jun', age=29} // Scratch{name='moon', age=25} // Scratch{name='sin', age=23}