ThreadLocalRandom.current().nextInt(0, 360) //0부터 360까지

시간 범위 지정하기

val diff = Duration.between(
    LocalDate.now().atStartOfDay(),
    item.checkin.atStartOfDay()
)

Duration.between( ) 두시간의 간격을 계산한다

LocalDate.now().atStartOfDay() 현재 날짜를 현재시간으로 초기화한뒤 해당날짜의 자정으로 설정

item.checkin.atStartOfDay() 체크인의 시작 날짜 설정

diff는 현재 날짜의 자정과 체크인시작 날짜의 자정 사이의 날짜들을 나타낸다

정수를 LocalDate타입으로 변환

잊지말자

fun dateform(a: Int): LocalDate {
    val formatter = DateTimeFormatter.ofPattern("yyyyMMdd")
    val x = LocalDate.parse(a.toString(), formatter)
    return LocalDate.parse(x.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
}

formatter 는 "yyyyMMdd"패턴의 코드스타일을 검사 수정해준다

x는 parse()를 써서 LocalDate객체로 문자열을 파싱해준다

파싱:문자열을 원하는 형식의 데이터로 변환하는 과정

입력받은 8자리 문자열이 "yyyyMMdd"패턴을 가진게 x

x를 다시 포맷해서 패턴을 "yyyy-MM-dd"로 변환해준다

with(객체){ }

with 함수는 Kotlin에서 제공하는 표준 라이브러리 함수 중 하나로, 특정 객체에 대한 일련의 작업을 수행할 때 사용

예시)

data class Person(var name: String, var age: Int)

fun main() {
    val person = Person("John", 30)

    // with 함수를 사용하여 person 객체의 멤버에 직접 접근
    with(person) {
        println("현재 이름: $name")
        println("현재 나이: $age")

        // person 객체의 멤버 수정
        name = "Jane"
        age = 25

        println("수정된 이름: $name")
        println("수정된 나이: $age")
    }

    // with 블록을 빠져나왔을 때의 person 객체 상태
    println("최종 이름: ${person.name}")
    println("최종 나이: ${person.age}")
}
with(peopleList.find { it.name == a }) { 
                    if (this == null) {
                        println("예약된 사용자를 찾을 수 없습니다.")
                    } else {
                        for (i in peopleList) {
                            if (i.name == this.name) {
                                sumcash += i.cash
                                sumprice += i.price
                                sumbal += i.balance
                            }
                        }

peopleList안에 name이 a랑 같은 원소 리스트(peopleList[a이름같은거])를 this로 표현한다

csv파일 작성

csv라고만 적었지만 아마 모든 텍스트 파일은 될것같다

println("영수증 내보내실 분의 성함을 입력해주세요")
                val name = readln()
                val filename = "C:\\Users\\zaq86\\OneDrive\\바탕 화면\\Velogimg\\$name 님 예약 영수증.csv"
                val sortedArray = reserveList.sortedBy { item -> item.people.name }//이름순으로 정렬
                try {

                    File(filename).printWriter().use { out ->
                        //헤더 작성
                        out.println("Name, RoomNumber, CheckIn, CheckOut, Price")

                        sortedArray.forEach { it ->
                            out.println("${it.people.name},${it.roomnum},${it.checkin},${it.checkout},${it.price}")
                        }
                    }

                    println("영수증이 성공적으로 내보내졌습니다. 파일 경로: $filename")
                }catch (e: Exception) {
                    println("에러 발생: $e")
                }

File(경로) File클래스를 이용해서 지정된 파일 경로에대한 파일 객체를 생성

printWriter 로 파일에 직접 문자열을 쓸 수 있다

.use로 블록을 정의하고 out은 printWriter객체를 나타낸다

println으로 헤더를 정의하고 그밑으로 forEach를 사용해 sortedArray를 순회해서 정보를 나열한다

파일만들기(경로).파일내용입력하기{
             내용
             }

널 세이프티

  • Kotlin의 널 세이프티 방법
    • Null 예외로부터 안전한 설계를 위한 다양한 키워드들을 지원해요
    • 코틀린은 ?, !!, ?., ?: 로 Null예외로부터 살아남으려고 해요
    • 하지만 강제로 null이 아니라고하는 !!는 최대한 사용을 지양해주세요!

? -> null저장할수도있어

!! -> 절대 null아님

?.키워드 Null이 아닐때만 실행되는 메소드

생성자

class Archer : Character {
    var name:String
    var age:Int
    var gender:String
    var money:Int
    var hp:Int

    constructor(_name:String, _age:Int, _gender:String, _money:Int, _hp:Int) {//생성자 <- 코틀린이 컴파일하는 시점에서 생성자가 있으면 객체는 만들어짐
        name = _name       //여기서 이미 초기화하니까 위에 class var들을 초기화 할 필요가 없음
        age = _age
        gender = _gender
        money = _money
        hp = _hp
        println("${name}궁수 생성") //궁수를 초기화하기전에 생성한다면 위에 class에 있는 변수들을 초기화해줄 필요가 있음
    }

배열

Arrays 배열의 요소 전부

Arrays는 외부 패키지에 있는 클래스를 임포트해야함 //java.uill.Arrays

// arrayOf메소드를 호출하면 배열을 리턴해줍니다
// 1,2,3,4,5 각각을 저장한 변수 5개를 배열형태로 arr에 저장합니다
var arr = arrayOf(1,2,3,4,5)

// 배열요소를 모두 출력합니다
println(Arrays.toString(arr))

// 배열의 첫번째 요소에 저장된 값을 출력합니다
// var num1 = 1의 num1과 arr[0]은 동일합니다
// arr[0]은 하나의 변수로 취급할 수 있습니다
// arr은 0~4번방(인덱스)까지 접근할 수 있습니다
println(arr[0])

출력 [1, 2, 3, 4, 5] 이런식으로 나옴

컬렉션

List

List 배열(array)와 달리 크기가 정해져있지 않다

listOf 읽기전용

mutableListOf 수정가능

ArrayList<자료형> mutable이랑 비슷하지만 배열형태로 저장

map

		// 읽기전용 맵입니다
    // 변수명[키]로 데이터에 접근할 수 있습니다
    var scoreInfo1 = mapOf("kor" to 94, "math" to 90, "eng" to 92)
    println(scoreInfo1["kor"])

    // 수정가능 맵입니다
    // 변수명[키]로 데이터에 접근할 수 있습니다
    var scoreInfo2 = mutableMapOf("kor" to 94, "math" to 90)
    scoreInfo2["eng"] = 92
    println(scoreInfo2["eng"])

    // 맵의 키와 값을 동시에 추출해서 사용할 수 있습니다
    for((k,v) in scoreInfo2) {
        println("${k}의 값은 ${v}입니다")
    }

for( in ) { } 자주 쓰니까 잘 이해하자

set

set은 순서가 없고 중복없이 데이터를 관리함

다른 컬렉션들은 요소를 찾는데 집중하지만 set은 요소가 존재하는지가 중요

//  읽기전용 Set입니다.
    var birdSet = setOf("닭", "참새", "비둘기")

//  수정가능 Set입니다.
    var mutableBirdSet = mutableSetOf("닭", "참새", "비둘기")
    mutableBirdSet.add("꿩")
    mutableBirdSet.remove("꿩")
    println("집합의 크기는 ${birdSet.size} 입니다")

    var findBird = readLine()!!

    if(birdSet.contains(findBird)) {
        println("${findBird} 종류는 존재합니다.")
    } else {
        println("${findBird}는 존재하지 않습니다.")
    }

contains( ) 메소드는 컬렉션에 지정된 요소가 포함되어있는지 확인

		// 귀여운 새의 집합
    var birdSet = setOf("닭", "참새", "비둘기", "물오리")

    // 날수있는 새의 집합
    var flyBirdSet = setOf("참새", "비둘기", "까치")

    // 모든 새의 집합 (합집합)
    var unionBirdSet = birdSet.union(flyBirdSet)

    // 귀엽고 날수있는 새의 집합 (교집합)
    var intersectBirdSet = birdSet.intersect(flyBirdSet)

    // 귀여운 새들중에서 날수없는 새의 조합 (차집합)
    var subtractBirdSet = birdSet.subtract(flyBirdSet)

    println("=====합집합=====")
    println("모든 새의 집합 : ${unionBirdSet}")

    println("=====교집합=====")
    println("귀엽고 날수있는 새의 집합 : ${intersectBirdSet}")

    println("=====차집합=====")
    println("귀엽고 날수없는 새의 집합 : ${subtractBirdSet}")

union 합집합
intersect 교집합
subtract 차집합

Single-expression function

💡 람다식을 이용해서 메소드를 간결하게 정의할 수 있다

fun add(num1:Int, num2:Int, num3:Int) = (num1+num2+num3)/3


var add = {num1: Int, num2: Int, num3: Int -> (num1+num2+num3) / 3}
println("평균값은 ${add(10,20,30)}입니다")

싱글턴

💡 메모리 전역에서 유일한 객체임을 보장 받는다

  • 설명
    • 보통 객체는 자원이 가능한 만큼 생성할 수 있어요
    • 각각의 객체는 상이한 위치정보를 가지고 있어서 저장하는 값도 객체마다 고유해요
    • 싱글턴을 활용하면 해당 객체는 메모리 전역에서 유일함을 보장하고 위치정보가 고정이예요
    • 프로그램이 실행되는 시점에 메모리에 바로 로드해서 위치를 잡아요
  • Kotlin의 싱글턴 구현방법
    • 코틀린은 companion, object 키워드로 싱글턴을 구현할 수 있어요

그래서 왜 필요?

다른 클래스들에서 쉽게 접근함

전역에서 공통적으로 사용하는 정보라면 메모리를 더욱 효율적으로 활용

객체 자원간의 충돌을 방지

fun main() {
    // trash와 같이 생성자에 매개변수 전달 가능
    var singletonObject1 = MySingletonClass.getInstance(trash = 1)
    singletonObject1.setNum(5)
    println("num값은: ${singletonObject1.getNum()}")

    // singletonObject2에서 num을 10으로 대입
    var singletonObject2 = MySingletonClass.getInstance(trash = 1)
    singletonObject2.setNum(10)

    // singletonObject1의 num이 10으로 출력됨
    // singletonObject1과 singletonObject2는 같은 객체를 공유하기 때문
    println("num값은: ${singletonObject1.getNum()}")

}

class MySingletonClass private constructor() {
    private var num:Int = 0

    companion object {
        @Volatile private var instance: MySingletonClass? = null
        private var trash = 0

        fun getInstance(trash: Int): MySingletonClass {
            this.trash = trash
            // 외부에서 요청왔을때 instance가 null인지 검증
            if(instance == null) {
		            // synchronized로 외부 쓰레드의 접근을 막음
								// 쓰레드는 다음챕터에서 소개합니다!
		            // 쓰레드간의 객체상태 혼돈을 막기위해 사용한다고 이해해주세요
                synchronized(this) {
                    instance = MySingletonClass()
                }
            }
            return instance!!
            
//            엘비스연산자와 뒷장에서배울 scope function을 이용하면
//            아래와같이 더욱 직관적인 코드 작성이 가능합니다
//            return instance ?: synchronized(this) {
//                // also는 호출한 객체를 it으로 넘김
//                // instance가 null이라면 새로 생성하고 아니면 무시함
//                instance ?: MySigletonClass().also {
//                    instance = it
//                }
//            }
        }
    }
    fun setNum(num: Int) {
        this.num = num
    }

    fun getNum(): Int{
        return this.num
    }
}

클래스가 다른대 클래스호출없이 오버라이드 없이 getInstance 불러옴

업캐스팅

fun main() {
    println("몇 마리를 생성하시겠습니까?")
    var count = readLine()!!.toInt()
    var birds = mutableListOf<Bird>()

    for(idx in 0..count-1) {
        println("조류의 이름을 입력해주세요")
        var name = readLine()!!

        birds.add(Sparrow(name) as Bird)
    }
    println("============조류 생성완료============")
    for(bird in birds) {
        bird.fly()
    }
    // 다운캐스팅 오류
    // Sparrow는 Bird가 가져야할 정보를 모두 가지고 있지 않기 때문임
//    var s1:Sparrow = birds.get(0)
}

open class Bird(name: String) {
    var name: String

    init {
        this.name = name
    }

    fun fly() {
        println("${name}이름의 조류가 날아요~")
    }
}

class Sparrow(name: String): Bird(name) {

}

0개의 댓글