본문 바로가기
Kotlin/Kotlin 프로그래밍

[Kotlin] 문자열(String)

by 주 녕 2021. 5. 21.
728x90

모든 내용은 Do it! 코틀린 프로그래밍을 바탕으로 정리한 것입니다. 

 

문자열

문자열의 기본 처리

문자열은 연속된 문자의 배열 → 불변(immutable)값으로 생성되므로 참조되고 있는 메모리가 변경될 수 없음

∴ 새로운 값을 할당하려고 한다면 기존 메모리 이외에 새로운 문자열을 위한 메모리를 만들어 할당해야 함

    val hello: String = "Hello World!"
    println(hello[0])  // 접근 가능
    
    hello[0] = 'K'  // 오류
    var s = "abcdef"
    s = "xyz"  // 새로운 메모리 공간 생성
  • var나 val에서 하나의 요소에 새 값을 할당할 수 없음
  • var로 선언하는 경우, 전체 문자열을 내부적으로 새로 생성해 할당되고 기존 메모리 공간은 GC(Garbage Collector)에 의해 제거
    • 기존의 문자열은 GC에 의해 제거되지만 제거 시점은 프로그래머가 제어할 수 없기 때문에 대량의 문자열을 다룰 때는 메모리 낭비 등이 일어나지 않도록 주의해야 함

 

💡 JVM을 기반으로 동작하는 코틀린은 자바에서 만들어진 메모리 구조를 사용함.

자바의 String은 리터럴(literal)과 new 연산자에 의해 만들어지는데, 리터럴로 선언할 경우 상수 풀(Constant Pool)에 저장되고 new에 의해 선언되면 String 객체가 힙에 생성되게 됨. 자바 7부터는 상수 풀의 영역이 힙 영역으로 옮겨져 기존의 메모리 부족 오류를 개선함. 따라서 기존에 문자열은 GC 대상에 없었지만, 자바 7 이후 GC 대상에 포함되어 참조가 없으면 메모리에서 삭제됨.

 

[ 문자열 추출하고 병합하기 ]

  • String.substring(인덱스 범위 지정): String
  • CharSequence.subSequence(인덱스 범위 지정): CharSequence
    s = "abcdef"
    println(s.substring(0..2))  // abc
    
    var a = "abcdef"
    a = a.substring(0..1) + "X" + a.substring(3..s.length-1)  // abxdef
  • substring()의 인자는 인덱스 번호를 범위 지정자(in)을 사용해 추출함
  • var로 선언했기 때문에 문자열을 새롭게 할당하는 것이 가능하고, + 연산자를 사용하여 병합하여 전체를 다시 할당함
    • 기존 문자열 "abcdef"는 어딘가 남아있다가 GC에 의해 제거됨

 

[ 문자열 비교하기 ]

    var s1 = "Hello Kotlin"
    var s2 = "Hello KOTLIN"
    
    println(s1.compareTo(s2))  // 32
    println(s1.compareTo(s2, true))  // 대소문자 무시 - 0
  • s1과 s2가 같다면 0 반환
  • s1이 s2보다 작으면 양수 반환, 그렇지 않으면 음수 반환

 

[ StringBuilder 사용하기 ]

  • 문자열이 사용할 공간을 좀 더 크게 잡을 수 있기 때문에 요소를 변경할 때 이 부분이 사용되어 특정 단어를 변경할 수 있게 됨
  • 기존의 문자열보다는 처리속도가 느림
  • 단어를 변경하지 않고 그대로 사용하면 임시 공간이 메모리를 좀 더 사용하게 되므로 낭비할 수 있음

→ 문자열이 자주 변경되는 경우에 사용

fun main() {
    var s = StringBuilder("Hello")
    s[2] = 'x'

    println(s.append("World"))  // HexloWorld
    println(s.insert(10, "Added"))  // HexloWorldAdded
    println(s.delete(5, 10))  // HexloAdded
}
  • s는 메모리 공간을 새롭게 만들지 않고 여유 분의 공간을 이용해 문자 요소가 변경됨
  • append() - 포함, insert() - 추가, delete() - 삭제가 용이함
    • 문자열을 포함시키기 위해 사용하는 append()는 생성된 버퍼를 사용하므로 보통 + 연산자를 이용해 새로운 객체를 만들어 처리하는 것이 더 좋음

 

[ 기타 문자열 처리 ]

  • toLowerCase, toUpperCase : 소문자/대문자 변경
  • split() : 하나 이상의 특정 문자 단위로 잘라내기 - 결과값은 List<String>으로 할당됨
  • trim() : 앞뒤 공백 제거

 

[ 문자열 정수로 변환하기 ]

  • toInt() 메서드를 통해 정수로 변환
  • 숫자가 아닌 경우에는 NumberFormatException 오류를 발생하기 때문에 try~catch 블록으로 처리해야 함
  • 숫자가 아닌 문자가 포함되었을 때 null로 반환받으려면 toInt() 대신 toIntOrNull()을 사용하면 프로그램 중단을 방지할 수 있음
fun main() {
    val num: Int = "123".toInt()

    try {
        "12w".toInt()
    } catch (e: NumberFormatException) {
        println(e.printStackTrace())
        println("12w".toIntOrNull())
    }
}

 

 

리터럴 문자열

[ 이스케이프 문자(Escape Character) ]

특수한 문자를 처리하기 위해 백슬래시(\)를 포함한 문자 표현

  • \t  : 탭(tab)
  • \r  : 캐리지 리턴(carriage return)
  • \\  : 백슬래시(backslash)
  • \b  : 백스페이스(backspace)
  • \n  : 개행(newline)
  • \'  : 작은따옴표(single quote)
  • \"  : 큰따옴표(double quote)
  • \$  : 달러 기호(dollar)
  • \uHHHH : 유니코드(16진값)

 

3중 따옴표(""")를 사용하면 이스케이프 문자 중 개행 문자를 넣지 않고도 원본 문자열을 그대로 표시할 수 있음

trimMargin()을 사용해 특정 문자 기준( | - 파이프 기호가 기본값)으로 공백을 제거할 수 있음

fun main() {
    val text = """
        |Tell me and I forget.
        |Teach me and I remember.
        |Involve me and I learn.
        |(Benjamin Franklin)
    """.trimMargin()  // trim default는 |
    print(text)
    
    //Tell me and I forget.
    //Teach me and I remember.
    //Involve me and I learn.
    //(Benjamin Franklin)
}

 

[ 형식 문자 ]

코드의 결과값을 문자열의 원하는 형태로 나타낼 수 있음

코틀린에서는 형식 문자를 사용하기 위해 String에 format()을 사용함

inline fun String.format(vararg args: Any?): String (source)
  • Any에 대한 매개변수를 가변적으로 받아들일 수 있는 vararg로 선언됨
  • 따라서 필요한 만큼 형식 문자를 사용할 수 있음

< 형식 문자의 종류 >

  • %b  : 참과 거짓의 Boolean 유형
  • %o  : 8진 정수
  • %x  : 16진 정수
  • %g  : 10진 혹은 E 표기법의 실수
  • %e  : E 표기법의 실수
  • %d  : 부호 있는 정수
  • %f  : 10진 실수
  • %c  : 문자
  • %s  : 문자열
  • %t  : 날짜나 시간
  • %n  : 줄 구분
  • %h  : 해시코드
fun main() {
    val pi = 3.141592
    val dec = 10
    val s = "hello"

    println("pi = %.2f, %3d, %s".format(pi, dec, s))  // pi = 3.14,  10, hello
}

 

 

* Kotlin의 배열 관련 포스팅

 

[Kotlin] 배열(Array)

모든 내용은 Do it! 코틀린 프로그래밍을 바탕으로 정리한 것입니다. 배열 다루기 코틀린에서 배열은 Array 클래스로 표현함 배열 사용 방법 [ 기본적인 배열 표현 ] arrayOf() : 기본 생성자 Array() :

junyoung-developer.tistory.com

728x90

댓글