ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Kotlin 기초 문법 예제
    Kotlin 2021. 3. 17. 15:32
    반응형

    [키워드]

    as : 형 변환자 
    in : for , range , when 등 사용 
    is :  타입 캐스팅 ( instanceOf() )
    this : 자바에서 접근이 힘든 부분까지 접근 가능, 상위 scope 까지 접근 가능
    
     class A { // implicit label @A
        inner class B { // implicit label @B
            fun Int.foo() { // implicit label @foo
                val a = this@A // A's this
                val b = this@B // B's this
    
                val c = this // foo()'s receiver, an Int
                val c1 = this@foo // foo()'s receiver, an Int
    
                val funLit = lambda@ fun String.() {
                    val d = this // funLit's receiver
                }
    
    
                val funLit2 = { s: String ->
                    // foo()'s receiver, since enclosing lambda expression
                    // doesn't have any receiver
                    val d1 = this
                }
            }
        }
    }
    
    typealias : import 의 alias 와 동일 기능 수행 
    
    typealias NodeSet = Set<Network.Node>
    typealias FileTable<K> = MutableMap<K, MutableList<File>>
    typealias MyHandler = (Int, String, Any) -> Unit
    typealias Predicate<T> = (T) -> Boolean
    
    class A {
        inner class Inner
    }
    
    class B {
        inner class Inner
    }
    
    typealias AInner = A.Inner
    typealias BInner = B.Inner
    
    by : 클래스, 프로퍼티 위임
    
    interface Base {
        fun print()
    }
    
    class BaseImpl(val x: Int) : Base {
        override fun print() { print(x) }
    }
    
    /*Derived 클래스는 Base 인터페이스를 상속할 수 있으며, 
    모든 public 메서드를 지정한 객체로 위임한다.*/
    class Derived(b: Base) : Base by b
    
    fun main() {
        val b = BaseImpl(10) 
        Derived(b).print()// 사용시 기존 오버라이딩된것이 아니라 
    }
    
    실행시 출력 값
    10
    

    [변수 ]

    var : 일반 변수 

    val : 불변 변수 ( final ) , Read-only

    var total: Int = 0 
    val a: Int = 10 + 53 - 7 
    val b: Int = 32 + 45 - a 
    total = a + b
    
    

    [배열]

    // arrayOf() 로 생성 가능 
    // get,set 은 이미 구현되있음.
    
    val array = arrayOf(1,2,3,4)
    println(array[0])
    
    // 5개 배열에 0으로 초기화 
    val array= arrayof( 5 , {  i->(i*0).toInt() } )
    
    
    // 자료형 배열 
    val intArray=IntArray(5,{i->(i*i).toInt() })
    
    // 멀티자료형 배열이 가능 
    val array= arrayOf(1,"wa",'c',"wai",1.55555)
    
    // 배열크기를 받아서 Null 로 초기화 
    var nullArray= arrayOfNulls<String>(5)
    

     

    [조건문 ]

    //if 는 자바 와 동일
    //when 
    var num = 1 
    when ( num ){
    	10 -> {
        	println(10)
        }
        9-> {
        	println(9)
        }
        else->{
        	println(num)
        }
    }
    
    
    // when case 2 
    var num = when ( num ){
    	10 -> {
        	println(10)
        }
        9-> {
        	println(9)
        }
        else->{
        	println(num)
        }
    }

    [반복문 ]

    //while 은 자바와 동일 
    // for ( 파이썬과 유사 ) 
    
    for ( num in 0..9) {
    	println(num)
    }
    //     num <=9
    for ( num in 0..9 step 2) {
    	println(num)
    }
    //     num >=0
    for ( num in 9 downTo 0 step 2) {
    	println(num)
    }
     //    num>0 
    for ( num in 9 until 0 step 2 ) {
    	println(num)
    }
    
    for ( str in arr ) {
    	println(str)
    }
    // withIndex : 배열의 인덱스 번호와 값을 반환
    for ( (idx , value) in arr.withIndex() ) {
    	println("$idx : $ value ")
    }
    // indices : 배열의 번위를 리턴
    for ( num in arr.indices ) {
    	println( arr[num] )
    }
            // foreach 케이스 
            
            val lists2 = (1..10).toList()
            lists2.forEach{
                    i->if(i < 10) log.info(i.toString())
            else return@forEach
            }        
    
            val lists3 = (1..10).toList()
            run loop@{
                lists3.forEach { i ->
                    if (i < 10)  log.info(i.toString())
                    else return@loop
                }
            }
    
            val numbers:IntArray = intArrayOf(1,2,3,4,5,6)
            numbers.forEachIndexed {
                    i , e-> testPrint(i,e)
            }
            
            
          fun testPrint(i: Int , e : Int){
              println( "index : $i , value : $e" )
          }

    [Unit 타입]

    fun noReturnFunction(a: Int): Unit { println("a는 $a") }
    
    // 강제적으로 Unit 타입 객체를 리턴 함
    

    [디폴트 ]

    fun sum(a: Int = 0, b: Int = 0, print: Boolean = false): Double { 
       val result = a + b 
       if (print) { 
       	println(result) 
        } return result 
       } 
       
       
       // 실행 예제
       sum(1, 1) 
       sum(a = 1, print = true) 
       sum(print = true) 
       sum(print = true, a = 10, b = 30)
    
    

    [객체 ]

    // 객체 생성시 new 키워드 생략
    fun main(args: Array<String>) {
    	val person = object {
        	val name: String = "멍청이"
            val age: Int = 18
        }
      
         println(person.name ) 
         println(person.age ) 
      
      }

    [클래스]

    // 일반 클래스 
    class Person { 
    	var name: String = "" var age: Int = 0 
    } 
    fun main(args: Array<String>) { 
    	val person: Person 
        person = Person() 
        person.name = "홍길동" 
        person.age = 36 
    }
    
    
    // 추상 클래스와 인터페이스는 자바와 동일 
    
    interface User {
        val email:String //구현시 오버라이드 필요
    
        val nickname: String //구현시 오버라이드 불필요
            get() = email.substringBefore("@")
    
        //error!!! 인터페이스에서는 초기화 할수 없음
        val emailId :String= email.substringBefore("@")
    }
    
    //email은 꼭 오버라이드 해야됨!!
    class UserChild(override val email: String) : User
    
    
    // 데이터 클래스 : 데이터만을 담기 위한 클래스 
    // 프로퍼티 자동 생성 ( getter, setter ) 
    
    data class data( val a: Int , var b : Any ) 
    
    
    // 생성 제약 
    // 생성자는 최소 1개 이상의 파라미터를 받아야한다. 
    // 모든 prime 생성자는 val, var 이여야한다 
    // 데이터 클래스로 추상, 실드 클래스는 작성 불가 
    // 데이터 클래스는 상속 불가 
    
    // copy()
    // 객체 복사시 , 일부값을 변경하고 싶을떄 
    ret = ret.copy(a=20) 
    
    // toString, hashCode , equals 자동 오러라이딩 
    
    // componentN() : component 함수를 작성 , 분리선언시 필요 
    // 객체의 값을 여러변수로 분리해서 사용 하는것 
    val (var1,var2) = data(10,20) 
    
    // enum class 
    // 검색 : valueOf()
    // 값 : values()
    enum class Person{
       name , age
    }
    
    enum class Person{
       name(10, 20) , 
       age(10, 20)
    }
    
    // sealed class 
    // enum class 확장형 
    // 다른 파일에서 sealed 클래스 내부를 상속 불가 
    // sealed class 를 쓰는 이유는 when표현식 때문 
    // 안드로이드 UI 상태 관리상의 이점이 있어 사용하는것으로 추정
    sealed class  Expr{
        class Const(val number : Double) : Expr()
        class Sum(val e1 : Expr, val e2 : Expr) : Expr()
        object NotANumber : Expr()
    }
    class Ho : Expr.Const(12.2){
    
    }
       
    //NotSealedClass
    open class ExprNonSealed {
        class Const(val number: Double) : ExprNonSealed()
        class Sum(val e1: ExprNonSealed, val e2: ExprNonSealed) : ExprNonSealed()
        object NotANumber : ExprNonSealed()
    }
    //NotSealedClass when
    fun tmpEval(exprNonSealed: ExprNonSealed) : Double=when(exprNonSealed){
        is ExprNonSealed.Const -> exprNonSealed.number
        is ExprNonSealed.Sum -> tmpEval(exprNonSealed.e1)+tmpEval(exprNonSealed.e2)
        ExprNonSealed.NotANumber -> Double.NaN
    }

     

    [맴버변수]

    class make {
    	var name = ""
        var age = ""
        
        fun print(){
        	println("name:" + this.name ) 
            prlintln("age:" ${this.age}세") 
        }

    [생성자 ]

    // contructor 가 있는곳이 주 생성자 
    
    //생성자 초기화 
    class Person constructor( name : String , age : Int ) {
    	val name: String
        val age : Int
        init {
        	this.name = name 
            this.age = age 
        }
    }
    
    // init 분할 
    class Sum( a : Int , b : int ) {
    	val a = a 
        val b : Int
        
        init { 
        	this.b = b         
        }
        
        var sum: Int 
        init {
        	sum = a+b
        }
    }
    
    // 생성자+ 프로퍼티   : age 값이 있으면 그대로 없다면 0으로 세팅 
    class Car(val name: String , val age : Int=0 ) 
    
    
    // 보조 생성자 
    // 파라미터에 맞게 보조 생성자가 최초 init 이후 실행 됨.
    // (파라미터가 중복되는 모든 경우의 수의 보조 생성자가 실행됨)
    class Sum(val a :Int  ) {
    	init {
        	println("init excute.")
        }
    	constructor( b : Int , a : Int ) : this( b + a ) {
        
        	println("constructor 1 excute. ")
        }
        constructor( c: Int ,b : Int , a : Int ) : this( a+b+c , a ) {    
        	println("constructor 2 excute. ")
        }
        init {
        	println("Other init excute")
        }
    }    
    fun main(args: Array<String>) { 
      	println("${Sum(15, 6)") 
        println("${Sum(6, 3, 17)") 
    }
    
    
        
        
        
    }

    [Getter][Setter]

    class Person { 
    	var age: Int = 0 
        get() { 
        	return field 
        } 
        set(value) { 
        	field = if (value >= 0) value else 0 
        } 
    }
    
    

    [상속]

    // open : 클래스, 함수 재정의를 허용 하겠다는 의미 final 의 반대 
    // override : 상속을 위해 반드시 명시 해야함.
    // init : java 에서 생성자에 선언되는 부분 따라서 init 이 생성자보다 먼저 실행 됨.
    // 기본 상속 문법 
    class child : parent() {}
    class child : parent(12,14) {}
    
    open class parent {
    	contructor( x : Int ,y : Int ) {
        }
        open fun test(){}
    }
    class child : perent{
    	contructor() : super(12,14) {
        
        }
        override fun test(){}
    }
    
    // 1회용 상속
    open class Person( val name: String , val age: Int) {
    	open fun print(){
        	println("name:$name, age:$age")
        }
    }
    
    fun main( args: Array<String> ) {
    	// object 키워드로 1회용 상속 사용 
    	val person : Person = object : Person ("Test", 18 ) {
        	override fun print() { 
            	println("override message")
            }
        }
        person.print()
    }
    
    // 인터페이스 : 클래스 인터페이스 순서는 무관 
    // LifeCycle : 생성자 인자 -> 위임된 생성자 -> 프로퍼티 선언 ->초기화 블럭 -> 생성자 
    class child : parent , test1 , test2 {}
    

    [Any]

    /**
    equals() : == 연산자를 오버로딩하는 멤버 함수
    hashCode() : 객체 고유의 해시코드를 반환하는 멤버 함수
    toString() : 객체의 내용을 String 타입으로 반환하는 멤버 함수
    **/
    
    open class Any { 
    	open operator fun equals(other: Any?): Boolean 
        open fun hashCode(): Int 
        open fun toString(): String 
    }
    
    
    
    
    
    class Person(val name: String, val age: Int) {
    	override fun toString() = "이름:$name 나이:$age" 
    } 
    
    
    
    

    [Nothing] 

    // 리턴행위를 하지 않음 
    // 
    fun throwing(): Nothing = throw Exception() 
    fun main(args: Array<String>) { 
    	println("start") 
        val i: Int = throwing() 
        println(i) 
    }
    
    

    [Nullable ]& [null] 

    // Nullable이란, null 값을 지정할 수 있는 변수
    // ? 를 붙이면 Nullable 하게 만들수 있음.
    
    fun main(args: Array<String>) { 
    	val str : String? = if (true) "test" else null 
    }
    
    
    // Nullable 참조변수의 프로버티에 맴버변수 접근시 ? 연산자를 사용해야함 
    class Building(var name: String){ 
    	fun print(){ 
       		println("name : $name") 
        } 
    } 
    fun main(args: Array<String>) { 
        var obj: Building? = null // Nullable 한 결과 
        obj?.print() // print() 함수가 호출되지 않는다. 
        obj = Building("백화점")  // 값이 Null 이 아님
        obj?.print() // print() 함수 호출된다. 
    }
    
    // Not-Null 단정 연산자
    class Building(var name: String) 
    
    fun main(args: Array<String>) { 
    	val obj: Building? = null     
        obj!!.name = "백화점" // !! 키워드는 Not-null 타입으로 강제 캐스팅 ( 이미 null 이므로 Exception 발생 ) 
    }
    
    
    // 엘비스 연산자  : null 아니면 그값을 그대로 사용 , null 이면 우측 값을 사용 
    fun main(args: Array<String>) { 
    	val num1: Int? = null 
        println(num1 ?: 0) // 0 
        val num2: Int? = 15 
        println(num2 ?: 0) // 15 
    }
    
    
    // 첫번째 요소 가져오기 
    val main = email.firstOrNull() ?: ""
    
    
    
    
    

    [스마트 캐스팅]

    // 컴파일러가 자동으로 변환해주는 기능 
    // is -> 자료형 확인 연산자 ( intatnseOf (java)) 
    // Any = Object ( java ) 
    fun smartCast( value : Any ) {
    
    	when( value ) {
        	is Int -> println("Integer")
            is String->println("String")
            is IntArray->println("Int Array")
            else-> return
        }
    }
    
    
    fun smartCast2( value : Any ) {
    	if( value is Int ) {
        	println("Integer")        
        }else if (  value is String) {
        	println("String")
        }else if ( value is IntArray ) {
          	println("Int Array")
        }else{
        	return
        }
    }
    
    //as 는 형 변환 as , as? 사용
    class As {
    	fun asInt( num : Number ) {
        	// val 로 변수 사용시 as int 를 생략해도 스마트캐스트가 지원되어 자동변환
            // var 경우 아래와 같이 명시적 형변환 사용
            val i :Int = num as int 
        }
    }

    [접근 지정자] 

    public : 모든 곳에서 접근 가능, 접근 지정자를 생략하면 기본적으로 public이 된다.
    internal : 같은 모듈 안에서 접근 가능. (IntelliJ IDEA 모듈, Maven / Gradle 프로젝트 모듈)
    protected : 클래스 내부와, 서브클래스 안에서만 접근 가능.
    private : 프로퍼티와 멤버 함수일 경우, 해당 클래스 안에서만 접근 가능하고, 그 외의 경우, 같은 파일 내에서만 접근 가능하다.
    
    

    [접근 지정자] [오버라이딩]

    open class AAA(protected open val number: Int) 
    class BBB(number: Int) : AAA(number) { 
       public override val number: Int 
       get() = super.number 
    } 
    
    fun main(args: Array<String>) { 
    	val b = BBB(26) 
        val a: AAA = b 
        println(a.number) // 에러 println(b.number)
    }
    

    [확장 함수]

    //기존 String 클래스에 함수를 추가하여 사용 
    fun String.containNumber(): Boolean { // 문자열에 숫자가 포함되어 있으면 true 
    	this.forEach { 
        	if (it in '0'..'9') return true 
        } return false 
    } 
    fun main(args: Array<String>) { 
    	println("123abc".containNumber()) // true 
        println("abc".containNumber()) // false 
    }
    

     

    [객체 선언] [싱글톤 패턴 코드]

    class Life(){
        object singleTone{
            const val my=10
            var my2=12
            fun test(){ }
        }
    }
    fun main(args : Array<String>){
        Life.singleTone.test()
    }

    [동반자객체] & [어노테이션]

    // static 효과
    class Person private constructor() { 
    	companion object { 
        	fun create(): Person { 
            	countCreated += 1 return Person() 
            } 
            var countCreated = 0 
         } 
    }
    
    
    // @JvmField 
    // getter,setter 를 작성 하지 않음
    // @JvmStatic
    // getter,setter 를 작성 
    class Life(){
       companion object {
           @JvmStatic
           val jvmstatic=10
           @JvmField
           val jvmfiled=12
       }
    }

    [filter] 

    var listInts = listOf(1,2,3,4,5,6)
    // filter 
    listInts.filter{ it % 2 == 0 } 
    
    // list filtering 
    if ( "A" in lists ) {}
    if( "B" !in lists ) {}
    
    // map 순회 
    for( (k,v) in maps ){
    	println("$k : $v")
    }
    
    
    var listInts = listOf(1,2,3)
    listInts.map{it*it} // 각항목의 제곱을 새로운 리스트로 변환
    
    val people = listOf(Person("a",18) , Person("b", 20 ) ) 
    listInts.map { it.name } // 이름만 리스트 화 
    peple.map(Person::name) // 위와 동일 수행, 더 단순화 
    
    peple.filter{ it.age > 18 }.map(Person::name) // 18살 이사의 이름만 
    
    // 가장 나이가 많은 사람들 모두 출력 
    val maxAge = people.maxBy(Person::age)!!.age //외부로 빼서 불필요한 반복 제거
    people.filter { it.age == maxAge }
    
    /맵 사용
    //map 에는 filterKeys, mapKeys 와 filterValues, mapValues 함수가 있음
    val numbers = mapOf(0 to "zero", 1 to "one")
    val upperNumbers = numbers.mapValues { it.value.toUpperCase() }
    //출력
    [0=ZERO, 1=ONE]
    
    

    [find]

    val words = listOf("Lets", "find", "something", "in", "collection", "somehow") // 문자열 컬렉션 정의
    val first = words.find { it.startsWith("some") } // "some"으로 시작하는 첫 번째 요소 찾기(=something) 
    val last = words.findLast { it.startsWith("some") } // "some"으로 시작하는 마지막 요소 찾기(=somehow) 
    val nothing = words.find { it.contains("nothing") } // "nothing"을 포함하는 첫 번째 요소 찾기(=null)
    
    
    // 람다를 만족하는 하나를 찾을수 있음
    val people = listOf(Person("A", 27), Person("B", 35), Person("C", 35))
    val canBeInClub27 = { p: Person -> p.age <= 27 }
    
    // 27인 첫번째 것을 리턴하거나 없으면 null 을 리턴
    people.find(canBeInClub27)
    
    // find 에서 null 을 리턴한다는 것을 명확히 함
    people.firstOrNull()
    
    

    [first] , [last]

    val numbers = listOf(1, -2, 3, -4, 5, -6) // 숫자 컬렉션 정의 
    val first = numbers.first() // 첫번째 요소 찾기(= 1) 
    val last = numbers.last() // 마지막 요소 찾기(=-6) 
    val firstEven = numbers.first { it % 2 == 0 } // 짝수중 첫번째 요소 찾기(=-2) 
    val lastOdd = numbers.last { it % 2 != 0 } // 짝수가 아닌 요소 중 마지막 요소 찾기(=5)
    
    

    [all]

    // 모든 원소가 람다식을 만족하는지 체크 
    val people = listOf(Person("A", 27), Person("B", 35), Person("C", 35))
    val canBeInClub27 = { p: Person -> p.age <= 27 } // 람다식의 조건
    people.all(canBeInClub27)
    
    //출력
    // false 모든 값이 27 이하가 아니기때문에 false 출력

    [any]

    // 하나라도 만족하는지 체크 
    val people = listOf(Person("A", 27), Person("B", 35), Person("C", 35))
    val canBeInClub27 = { p: Person -> p.age <= 27 }
    people.any(canBeInClub27)
    
    //출력
    // true A가 27 으로 하나라도 만족하기 때문에 true 출력

    [count]

    // 람다식을 만족하는 갯수를 리턴
    
    val people = listOf(Person("A", 27), Person("B", 35), Person("C", 35))
    val canBeInClub27 = { p: Person -> p.age <= 27 }
    people.count(canBeInClub27)
    
    people.filter(canBeInClub27).size // 비효율적인 방법

    [groupBy]

    // 조건에 따라 그룹으로 묶음
    val list = listOf("A", "AB", "C")
    list.groupBy(String::first).toString() //first가 같은 값으로 묶음
    
    //출력
    //{A=[A, AB], C=[C]}

    [flatMap]

    // 두개의 리스트가 하나로 합쳐짐 
    val strings = listOf("abc", "de")
    strings.flatMap { it.toList() }
    //출력 [a, b, c, d, e]
    
    
    // 중복 제거
    val strings = listOf("abc", "de", "de")
    strings.flatMap { it.toList() }.toSet()
    //출력 [a, b, c, d, e]
    
    // 단순히 리스트를 펼치기만 할때 ( 중복제거 x )
    val strings = listOf("abc", "de", "de")
    strings.map{ it.toList() }.flatten()
    //출력 [a, b, c, d, e, d, e] 

     

    [Sequence]

    // list(1) -> map(1*1) -> find(1>3) -> list(2) -> map(2*2) -> find(4>3) -> 종료
    listOf(1,2,3,4)
    		.asSequence()
            .map{ it*it } // 각 항목의 제곱
            .filter{ it%2 == 0 } // 짝수인것들만 
            .toList() // 최종 연산
            
            
    // 사용자 정의 시퀀스 
    //sequence 는 함수를 한개 원소씩 순차적으로 실행하여 조건에 맞으면 그대로 종료
    val naturalNumbers = generateSequence(0) { it + 1} //0부터 시작
    //여기까지도 아무것도 실행안됨
    val numbersTo100 = naturalNumbers.takeWhile { it <= 100 }
    //sum() 은 최종연산
    numbersTo100.sum()
    
    /시퀀스로 파일 탐색하기
    fun File.isinsideHiddenDirectory() = //확장함수
        generateSequence(this) {
            it.parentFile
        }.any {
            it.isHidden
            //find 함수로 원하는 디렉터리를 찾을 수도 있음
        }
    
    val file = File("파일경로+파일명")
    file.isinsideHiddenDirectory()        

     

    [표준함수]

    [apply] 

    // 일반 케이스 
    
    val menuFile = File("menu_file.txt")
    
    menuFile.setReadable(true)
    
    menuFile.setWritable(true)
    
    menuFile.setExecutable(false)
    
    //    Apply 적용 케이스 
    
    val menuFile = File("menu_file.txt).apply {
    
        setReadable(true)
    
        setWritable(true)
    
        setExecutable(false)
    
    }

    [let]

    // 일반 케이스 ( 첫번째 요소의 제곱 ) 
    val firstNumber = listOf(2,4,6).first()
    
    val firstNumberSquared = firstNumber * firstNumber
    
    // let 적용 케이스
    val firstNumberSquared = listOf(2,4,6).first().let {
        it * it
    } 
    
    
    // 일반케이스 
    fun Greeting(reservedGuest : String?) : String {
        return if (reservedGuest != null) {
        " 안녕하세요, $reservedGuest. 이쪽으로 오세요"
        } else {
            "안녕하세요, 잠시만 기다리세요."
        }
    
    }
    
    // let 케이스 
    fun Greeting( reservedGuest : String? ) : String {
    	return reservceGuest?.let{
        " 안녕하세요, $it. 이쪽으로 오세요"
        } ?: "안녕하세요, 잠시만 기다리세요."
    }

    [run]

    fun nameIsLong(name: String) = name.length >= 10
    
    nameIsLong("Albert")
    
    nameIsLong("Albert Einstein")
    
    
    "Albert".run(::nameIsLong)
    
    "Albert Einstein".run(::nameIsLong)
    
    
    
    
    fun main() {   
    	"Test Message..."
        	.run(::compar)
            .run(::sendMessage)
            .run(::println)
    }
    
    fun compare( a: String  ) = a.length > 10
    fun sendMessage( ret : Boolean ) : String {
    
    	return if( ret ) {
        	"Long!!"
        } else {
        	"Short!!"
        }
    
    }

    [also]

    fun main() {
    
    	val nums = mutailbeListOf("1", "2" , "3" ) 
        val sizeNm = : Int
        nums 
        	.also{
            	println("$it" ) 
            }
            .alse {
            	sizeNm = it.size 
            }
            .add( "4" )
    
    }
    
    
    // 값 스왑
    
    var a = 1 
    var b =2 
    a = b.also { b=a } 
    

     

    [takeif], [takeUnless]

    fun main(){
    
    	val num = 20
        var even = num.takIf{ it %2 == 0  }
        var odd = num.takeUnless { it % 2 == 0 } 
        println(  " 짝수 : $even , 홀수 : $odd " ) 
        // 출력 : 짝수 : 20 , 홀수 : null 
    
    
    
    }

    [문자열]

    // escape sequence //
    /**
    작은 따옴표 : \'
    탭 : \t
    백스페이스 : \b
    newline : \n
    carriage return :  \r
    끈따옴표 : \"
    백슬러스 : \\
    달러 : \$
    유니코드 : \u
    **/
    
    
    // substing() 
    
    val str = "test's string data"
    val indexStr = str.indexOf('\'')
    val temp = indexStr.substirng( 0 until indexstr )
    
    
    // split() 
    
    val str = "test, string, data"
    val temp = str.split(',')
    val strTmp = temp[0]
    val (strTmp1, strTmp2, strTmp3 ) = str.split(',')
    
    
    // replace() 
    
    // 기본
    val str = "Java with!"
    val r = str.replace("Java","Kotlin")
    
    //정규 표현식 사용 
    val str = "Java with!"
    val re = ".a.\\w".toRegex()
    val r = str.replace(re,"Kotlin")
    
    
    // 다른방법 ( 암호에 사용하기 쉬움 ) 
    val str = "test, string, data"
    str.replace(Regex("[aei]") ) { //Regex 문자 검색 패턴 정의 
    	when (it.value ) {
        	"a" -> "1"
            "e" -> "2"
            
            
    // forEach() 
    //  문자열 문자를 하나씩 처리하는 함수 
    "Unicode".forEach{ println("$it")} 
            "i" -> "3"
            else -> it.value
        }
    }

     

    [파일 입출력]

    [쓰기] 

    fun main(){
    	val path_1 = "/test/test.txt"
        val text = "test"
        
        val file = File(path_1)
        val printWriter = PrintWriter(file)
        printWirter.println(text)
        printWirter.close()
        
        // use()
        
        File(path_1).printWriter.use{ it.println(text) } 
        
        // use() + bufferWriter 
        
       	File(path_1).bufferedWriter.use{ it.write(text) } 
    
    	// FileWriter + write() 
        val writer = FileWriter( path_1 , true ) // append 여부 옵션 
        try{
        	writer.write(text)
        }catch(e: IOException){}
    	filnally{ writer.close } 
        
        // FileWriter + use()
        FileWriter(path_1 ,  true ).use{ it.write(text) }
    }

    [읽기]

    fun main(){
    
    	val path = "/test/test.txt"
        try {
        	val read = FileReader(path)
            varl str = read.readText()
        }catch(e:IOException){
        	
        }
        // bufferdReader ver 1 
        val file = File(path)
        val input = file.inputStream()
        val text = input.bufferedReader().use{ it.readText() }
    	
        // bufferdReader ver 2 , file 객체 생략 
    	val bufReader = File(path).bufferedReader()
        val text2 = bufReader.use{ it.readText() }
        
        // file 복사 
        val target = /test/test2.txt 
        File(path).copyTo(File(target), true , 2048 ) // 경로 , 오버라이드 여부 , 버퍼크기
    }

    [fold]

    // 초기값 0 을 정해주고 왼쪽 부터 오른쪽까지 값을 각각 적용 
    var result = listOf( 1,2,3,4,5 ).fold( 0 , { total, next-> total + next } )
    // result : 15
    
    // 데이터 객체일때 
    
    val lists= listOf(
    	Apple("a++", 500),
        Apple("a+", 400),
        Apple("a", 300),
        Apple("b", 200),
        Apple("c", 100)
    )
    
    val applePrice = appleList.map { it.price }.fold(0, { total, next -> total + next })
    println("applePrice : ${applePrice}")
    // mulTotal : 1500
    
    
    

    [Collection]

    [map]

     val langMap: Map<Int,String> = mapOf(11 to "Java", 22 to "Kotlin", 33 to "C++")
     val capitalCityMap: MutableMap<String,String>   //  선언할 때 키와 값의 자료형을 명시할 수 있음
        = mutableMapOf("Korea" to "Seoul", "China" to "Beijing", "Japan" to "Tokyo")
     
     
     
      for((key, value) in langMap){
            println("key=$key, value=$value")
    //        key=11, value=Java
    //        key=22, value=Kotlin
    //        key=33, value=C++
        }
        println("langMap[22] = ${langMap[22]}") 		//  langMap[22] = Kotlin
        println("langMap.get(22) = ${langMap.get(22)}") 	//  langMap.get(22) = Kotlin
        println("langMap.keys = ${langMap.keys}")   	//  langMap.keys = [11, 22, 33]

    [set]

    val mixedTypesSet = setOf("Hello", 5, "World", 3.14, 'c')
    val intSet: Set<Int> = setOf(1,5,5)
    val animals = mutableSetOf("Lion","Dog","Cat","Python","Hippo")
    val intsHashSet: HashSet<Int> = hashSetOf(6, 3, 4, 7)   //  불변성 기능이 없음
    
    val insSortedSet: TreeSet<Int> = sortedSetOf(4,1,7,2)
    val intsLinedHashSet: java.util.LinkedHashSet<Int> = linkedSetOf(35, 21, 76, 26, 75)

    [list]

    val stringList = listOf("one", "two", "one")
    var names: List<String> = listOf("one","two","three")
    var mixedTypes = listOf("Hello", 1, 2.45, 's')  //  <Any>타입
    val emptyList: List<String> = emptyList<String>()
    val nonNullsList: List<Int> = listOfNotNull(2, 45, 2, null, 5, null)
    //  가변형 List를 생성하고 자바의 ArrayList로 반환
    val stringList: ArrayList<String> = arrayListOf<String>("Hello", "Kotlin", "Wow")
    //  가변형 List의 생성 및 추가, 삭제, 변경
    val mutableList: MutableList<String> = mutableListOf<String>("kildong","Dooly","Chelsu")

    [Collection 합치기]

            val strs1 : HashMap<String, Any> = hashMapOf<String, Any>( "a" to 1 , "b" to 2 )
            val strs2 = hashMapOf<String, Any>( "c" to 3 , "d" to 4 )
            val str = strs1 + strs2
           
    
            val list1 = listOf<Int>(1,2,3,4,5,6)
            val list2 = listOf<Int>(2,10,22)
    
            val distinctList = list2.toMutableList().apply { addAll(list1) }.distinct()
            val normalList = list2.toMutableList().apply { addAll(list1) }
    
    

     

    [Get URL]

    val params = mapOf("name" to "John Doe", "occupation" to "gardener")
            val urlParams = params.map {(k, v) -> "${(k)}=${v}"}
                .joinToString("&")

     

    참고사이트 :  jeong-pro.tistory.com/220  ,fiftiesstudy.tistory.com/104, heegs.tistory.com/

     

    반응형

    'Kotlin' 카테고리의 다른 글

    코틀린 vs Java  (0) 2021.07.12
    Kotlin Coroutine 사용하기  (0) 2021.05.13
    Kotlin 기초 (2) - Collection & 표준함수  (0) 2021.03.18
Designed by Tistory.