String 클래스 - repeat()

누구나 처음으로 프로그래밍 언어 공부를 시작하면서 조건문을 넘어 반복문 파트를 학습하거나 알고리즘 실력을 키우기 위해서 알고리즘 문제 사이트를 접했다면 한번씩은 반복문을 통하여 별찍기 문제를 접했을 것이다. 나 역시도 여러가지 경로로 해당 문제를 접하기도 했고, 응용 별찍기 문제들로 골머리 아팠던 적도 많았던 것 기억이 난다...ㅡ,,ㅡ

 

오늘은 문제들을 다시 풀어보면서 그 전에는 해당 문제를 접했을 경우 중첩된 반복문을 통해서 해결했던 적이 많았는데, 최근 파이썬, 자바스크립트를 통해서 접했던 repeat()이라는 함수를 알게되었고 자바를 통해서 별찍기 문제를 접하면서 알게 된 것을 정리하고자 한다.

 


  • repeat() 메서드

String 클래스 - repeat() 정의

 

JDK 11 Documentaton 문서에 있는 내용을 참조한 부분이다. 해당 메서드를 호출할 때는 int타입으로 반복할 횟수를 전달해주고 해당 문자열을 반복횟수만큼 반복하여 만들어진 문자열을 반환해준다.

 

-참고 : https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html

 

public String repeat(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("count is negative: " + count);
        }
        if (count == 1) {
            return this;
        }
        final int len = value.length;
        if (len == 0 || count == 0) {
            return "";
        }
        if (len == 1) {
            final byte[] single = new byte[count];
            Arrays.fill(single, value[0]);
            return new String(single, coder);
        }
        if (Integer.MAX_VALUE / count < len) {
            throw new OutOfMemoryError("Repeating " + len + " bytes String " + count +
                    " times will produce a String exceeding maximum size.");
        }
        final int limit = len * count;
        final byte[] multiple = new byte[limit];
        System.arraycopy(value, 0, multiple, 0, len);
        int copied = len;
        for (; copied < limit - copied; copied <<= 1) {
            System.arraycopy(multiple, 0, multiple, copied, copied);
        }
        System.arraycopy(multiple, 0, multiple, copied, limit - copied);
        return new String(multiple, coder);
    }

해당 코드를 통해 실제 String 클래스에 repeat() 메서드가 어떻게 선언되고 구현되어 있는지를 볼 수 있다. 간단하게 반복횟수가 0보다 작은 값으로 매개변수에 넘어올 경우 예외가 발생하고, 반복 횟수가 1일 경우 this인 객체 자신의 주소를 반환하며, 문자열 길이가 1일 경우 반복할 횟수만큼의 byte[] 배열을 만들어서 반복할 문자열을 Arrays.fill() 메서드를 통해서 채우게 된다. 아래 부분은 문자열 길이가 2이상일 경우 어떻게 처리하는지가 구현되어 있다.

 


Java 11 이전 / 이후 비교

문제)별 찍기 - 3 (백준 2440번)

--입력--
5

--출력--
*****
****
***
**
*

 

  • java11 이전
public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for(int i = n ; i > 0 ; i--){
            for(int j = i; j > 0 ; j--){
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

이전 버전에서는 행,열 각각 마다 해당 횟수만큼 찍기 위해서 중첩 반복문으로 처리했었다. 물론 다른방법이 있을수도 있으나, 적어도 나는 그랬었다..ㅎ

 

  • java11부터
public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for(int i = n ; i > 0 ; i--){
            System.out.println("*".repeat(i));
        }
    }
}

이처럼 java11버전부터 String 클래스에 추가된 repeat() 메서드를 사용하면 코드도 간결해지고 중첩된 반복문을 단일 반복문으로 처리도 할 수 있었다.


회고

오늘 글을 쓴 목적은 항상 반복적으로 사용하던 것보다 어떻게하면 간결하게 만들 수 있을까? 효율적으로 할 수 있는 것이 뭐가 있을까? 기존에 다른 부분에서 공부하고 알고 있던 내용이 여기에도 적용되는 부분이 있을까 등을 고려하면서 찾아보고 적용해본 것에 큰 의미가 있다고 생각했다.  처음에는 단순 문제를 풀면서 현재 로컬에서는 jdk 11을 사용하고 있었고 인텔리제이를 켜고 한번 문제에 적용을 해봤다. 이때까지는 잘 동작해서 문제를 푸는 사이트에서 코드를 넣고 완료를 했는데 에러가 발생한 것이다. 여기서부터 시발점이 되어서 하나씩 찾아보면서 사이트에서는 jdk 8 환경으로 되어있는 것을 발견했고, 그럼 언제부터 repeat() 메서드를 지원한 것인지를 찾다보니 jdk 11부터 지원하는 것을 알게 되었다. 

 

어떻게보면 정말 기초적인 부분일 수도 있지만, 기존에는 "아 그렇구나!"에서 그쳤다면 이번에는 why?라는 질문을 던져보고 직접 doc 문서를 찾아보고 실제로 어떻게 구현되어 있는지까지 찾아보고 아는 지식을 활용해서 실제로 코드를 이해해보고자 했던 시도가 좋은 시도였다고 생각한다.

 

'P.L > Java' 카테고리의 다른 글

java.lang.Character 클래스  (0) 2023.01.28
java.util.Arrays 클래스를 활용한 배열복사  (0) 2023.01.19
스트림(Stream) 개요  (0) 2022.06.06
기본형 타입 형변환  (0) 2020.08.02
기본형 데이터 타입  (0) 2020.08.02