본문 바로가기

2학년 2학기/모바일 소프트웨어 - 코틀린31

Coroutine(2) 2024. 10. 13.
Coroutine(1) import kotlinx.coroutines.*import java.lang.Thread.sleep/***fun main(){ GlobalScope.launch { println("Hello world!2") //코루틴에서 실행 } println("Hello world!1") //main thread에서 실행 sleep(1000)}* Hello world!1* Hello world!2**fun main(){ runBlocking { launch { //얌체 - 양보하지 않는다. println("Hello world!2") //코루틴에서 실행 } } println("Hello world!1") //main th.. 2024. 10. 13.
Array, Generic, Collection) Map Map은 딕셔너리와 비슷한데, 키와 값으로 이루어진 원소들의 모음이다. [불변 Map - mapOf()]map의 출력 방식fun main(){ val mapA: Map = mapOf("One" to 1, "Two" to 2, "Three" to 3) //키와 값을 동시에 출력 for ((k, v) in mapA) { println("($k, $v)") } //(One, 1) //(Two, 2) //(Three, 3) //키만 출력 println(mapA.keys) //[One, Two, Three] //값만 출력 println(mapA.values) //[1, 2, 3]}  키가 중복된 경우 ⭐️: 이전 값은 무시하고 새로.. 2024. 10. 13.
Array, Generic, Collection) Set Set은 순서가 없고, 중복을 허용하지 않는 원소들의 모음이다. 즉, 인덱싱이 불가하다.  [불변 Set - setOf()]Set의 size: 중복은 제거하고 요소 개수를 센다. val setA: Set = setOf(1,2,3,4,4,4)println(setA.size) // 4가 중복이기 때문에 개수는 4개    Set을 List로 변환: List로 변환하면 인덱싱도 가능해진다. val listA: List = setA.toList()println(listA) //[1, 2, 3, 4]     null 값이 있는 Set: ?를 사용해서 null 있어도 안전하게 처리해야한다.null도 중복을 허용하지 않기 때문에, 하나만 있다고 간주한다.val setA: Set = setOf("How", "Are", .. 2024. 10. 13.
Array, Generic, Collection) List Collection이란 여러 원소들의 모음이다. List는 순서가 있는 원소들의 모음이다. 즉, 인덱싱이 가능하다.  불변 List - listOf()[List와 관련된 표준 라이브러리들]val strList: List = listOf("red", "green", "blue")  sizeprintln(strList.size) //3 first, lastprintln("${strList.first()}, ${strList.last()}") //red, blue mapprintln(strList.map { it.length }) //[3, 5, 4]// 각 원소들의 길이 출력, map은 순환하는 것 filterprintln(strList.filter { it.length > 3 }) //[green, blu.. 2024. 10. 13.
Array, Generic, Collection) Generic 이터레이터 원소 출력fun main() { val intSequence: Iterable = listOf(1,2,3,4,5) val iter:Iterator = intSequence.iterator() while(iter.hasNext()){ //다음 원소가 없을 때 까지 val item = iter.next() println(item) // 1 2 3 4 5 }} 콜렉션fun main() { val intCollection: Collection = listOf(1,2,3,4,5) println(intCollection.size) //5 println(intCollection.isNotEmpty()) //true println(intCo.. 2024. 10. 13.
1~5장 교수님 블로그 1장코틀린: 진법 변환 구현 코틀린: 진법 변환 구현십진수 123을 8진수로 어떻게 변환할까요? toString(radix:Int) 함수를 사용하면 됩니다. 아주 쉽죠!fun main() { val x: Int = 123 println("$x is ${x.toString(8)} in octal representation")}라이브러리를 사용하지 않고 직접yshong60.tistory.com코틀린: package와 import(updated) 코틀린: package와 import(updated)쉽게 다가가는 최신 프로그래밍: 코틀린 - 1.2.2 라이브러리에서 import문에 대한 보충 설명입니다. 패키지(package)의 영어 단어 뜻은 꾸러미(parcel), 상자(box)이지만, 프로그래밍 언어에서 패.. 2024. 10. 12.
it과 this it: it은 람다식에서 단일 매개변수를 참조할 때 사용한다. val numbers = listOf(1, 2, 3, 4, 5)// numbers의 각 요소를 it으로 참조numbers.forEach { println(it) // 여기서 it은 리스트의 각 숫자를 가리킴}   this: this는 클래스 내부에서 자기 자신을 가르킬 때 사용한다. 주로 객체의 프로퍼티나 메서드를 참조할 때 사용한다.class Person(val name: String) { fun introduce() { println("My name is ${this.name}") // this는 현재 객체인 Person을 가리킴 }}val person = Person("Kim")person.introduc.. 2024. 10. 12.
Array, Generic, Collection) Array(2) - 배열 관련 연산 이번에는 배열과 관련된 연산들에 대해서 배워보자.배열 객체 복사배열 원소 추가배열 원소 선택(slice)배열 원소 순환(map)배열 정렬기본적으로 연산관련 메소드는 List를 대상으로 만들어진 것이기 때문에 Array의 연산을 하려면 "메소드Array" 형식으로 진행해야한다.  배열 객체 복사fun main() { val origanlArr = arrayOf(1, 2, 3) val arr1 = origanlArr // 배열 객체 자체를 복사 val arr2 = Array(origanlArr.size) { i -> origanlArr[i] } // 배열의 사이즈와 연산을 사용 val arr3 = origanlArr.clone() // 배열 객체를 복사하는 메서드 사용}  배열.. 2024. 10. 11.
Array, Generic, Collection) Array(1) - 배열의 생성 배열은 순서를 갖고있다. 따라서 정수 인덱싱이 가능하다.배열을 생성하는 방법은 총 3가지가 있다. arrayOf(), Array() + 람다식, 타입 + ArrayOf()   arrayOf()var/val 배열명: Array = arrayOf("", "", "")//타입은 생략가능var/val 배열명 = arrayOf("", "", "")  실제 사용 예시는 아래와 같다.fun main() { val strArr = arrayOf("R", "G", "B") strArr.forEachIndexed{ i, str -> print("strArr[$i] = $str, ")} // strArr[0] = R, strArr[1] = G, strArr[2] = B, }      Array() + 람다식.. 2024. 10. 11.
Class(2) - 범위 함수 범위 함수란?Kotlin에서 객체를 특정 범위(scope) 내에서 처리할 수 있게 도와주는 함수로, 객체의 컨텍스트에서 작업을 수행하는 간결한 방법을 제공한다. 주로 코드의 가독성을 높이고 객체를 효율적으로 처리하기 위해 사용된다.  범위함수에는 let, also, apply, with, run이 있다. let: 지정된 값에 대한 변환 작업을 수행하고, 결과를 반환한다.also: 지정된 값을 그대로 반환하면서, 부수적인 작업(로깅, 디버깅 등)을 수행한다. 주로, 객체를 참조하는 목적으로 사용apply: 객체의 속성을 변경하는 작업을 하고, 객체 자체를 반환한다. 주로, 객체를 참조하는 목적으로 사용with: 특정 객체에 대해 여러 작업을 수행하고, 결과를 반환한다.run: 블록 안에서 객체의 작업을 수.. 2024. 10. 11.
Class(2) - data class data class란?데이터를 저장하고 다루는 용도로 특별하게 설계된 클래스이다. 일반적인 클래스와는 다른 몇가지 자동화된 기능을 제공한다.주로 값 객체를 만들 떄 유용하다.  일반 클래스에도 equals, hashCode메소드가 있는데 뭐가 다른가?일반 클래스는 해당 값들의 주소를 비교한다. 따라서 값이 같아도 주소가 다르면 다르다고 판단한다. 하지만 data 클래스는 값을 비교하기ㄷ 때문에 주소가 달라도 값이 같다면 같다고 판단한다.  data class - toString() data class Fruit(var name: String, var sciName: String, var calories: String)fun main(){ val apple = Fruit("Apple", "학명: Ma.. 2024. 10. 11.
Class(2) - 클래스의 기본 메소드 정의 클래스의 기본 메소드를 재정의할 수 있다. toString, equals, hashCode   1. toString class Person(var name: String, var age: Int)fun main(){ val kim = Person("Kim", 18) println(kim) //Person@1be6f5c3}  원래는 이렇게 객체를 출력하면 객체이름과 이상한 값이 나온다. 이걸 toString() 메소드를 재정의해서 출력해보자.   class Person(var name: String, var age: Int) { override fun toString(): String { return "Person(name='$name', age=$age)" }}fun ma.. 2024. 10. 11.
Class(2) - Object Object란?싱글톤 객체를 정의하거나 익명 객체를 생성하며, 동반 객체를 통해 클래스이 정적 멤버처럼 사용되는 특수한 객체를 만드는 키워드이다. 즉, object를 사용해서 3개의 기능을 얻을 수 있다. 싱글톤, 동반 객체, 무명 객체 이렇게 3개의 기능이 있다.  1. object - singleton클래스는 원래 한개로 여러개의 객체를 만들 수 있다. 하지만 class 키워드 대신에, object를 사용하면 객체가 한개만 만들 수 있다. object Button { var clicked = 0 fun onClick() { clicked++ }} 이렇게 생성할 수 있다. object를 사용할 때는 객체가 하나만 생성이 되기 때문에 따로 객체를 생성하지 않고 사용할 수 있다.. 2024. 10. 11.
익명 함수 람다식은 익명함수의 하나이다. 그러면 익명함수는 뭘까?익명함수란 말 그대로 이름이 없는 함수이다. 즉 함수와 선언 방식이 비슷하다.  기본 구조: 일반 함수에서 함수명만 없애면 익명함수이다.변수명 = fun(변수1: 타입, 변수2: 타입): 반환 타입 = 함수 식   실제로 만들어보자. //[일반적인 함수]fun myPureFunc(a: Int, b: Int): Int{ return a+b}//[람다식]val myLambda:(Int, Int) -> Int = {a: Int, b: Int -> a+b}//[익명 함수]val myAnonymous = fun(a: Int, b: Int): Int = a + b 2024. 10. 11.
확장함수(Extension Funtions) 확장함수기존 클래스에 새로운 기능을 추가하는 방법이다.클래스를 수정하지 않고 새로운 메소드를 정의할 수 있게 해준다.  확장 함수의 기본 문법fun 클래스명.함수명(파라미터들): 반환타입 { // 함수의 본문}    사용 예시fun main(){ println("010-1234-5678".extract { it.isDigit() })}fun String.extract(cond: (Char) -> Boolean): String { val sb = StringBuilder() this.forEach { if (cond(it)) sb.append(it) } return sb.toString()} cond: (Char) -> Boolean은 문자 하나를 받아서 Boolean.. 2024. 10. 11.
람다식(2) - it, _ 사용 람다식의 타입 생략람다식을 선언했을 때 타입을 선언할 수 있는 경우가 있다.  타입을 생략하지 않은 경우val myLambda:(Int, Int) -> Int = {a: Int, b: Int -> a+b} 람다식 자체의 타입을 생략하는 경우 (일반적으로 많이 사용하는 경우)val myLambda = {a: Int, b: Int -> a+b} 람다식 내부 입력 변수 타입을 생략하는 경우val myLambda:(Int, Int) -> Int = {a, b -> a+b}    일반적인 함수와 람다식 사용의 차이 //일반적인 함수fun myFun(i: Int): Int = i * 10fun main() { val times = ::myFun println(times(2)) //20} //람다식fun .. 2024. 10. 10.
람다식(1) - 기본적인 선언과 호출, 고차함수와의 사용 람다식이란?람다식이란, 이름이 없는 함수를 간결하게 표현하는 방식이다. 기본 구조변수명: 입력 타입 -> 반환 타입 = {매개변수 -> 함수본문}  적당한 예시로 더하는 일반적인 함수를 람다식으로 변경해보자.//[일반적인 함수]fun myPureFunc(a: Int, b: Int): Int{ return a+b}//[람다식]val myLambda:(Int, Int) -> Int = {a: Int, b: Int -> a+b}// 타입 생략 가능val myLambda:(Int, Int) -> Int = {a, b -> a+b} 이렇게 일반적인 함수를 간단하게 함수이름 없이 람다식으로 간단하게 표현할 수 있다. 람다식의 호출 람다식을 직접 활용해서 호출하는 방법fun main() { val myLa.. 2024. 10. 10.
고차함수(2) - 응용편 고차 함수란 일급 함수라고 했다. 즉, 변수가 함수 역할을 할 수 있다. 일급 함수라는 점을 이용해서, 변수에 함수를 참조해서 변수를 통해서 해당 함수를 사용해보자. 일급 함수를 이용한 고차함수의 활용경우 - 1val strToLower: (String) -> String = String::lowercase//String 클래스의 lowercase 메소드를 사용해서 해당 메소드이 인자로 String을 전달하고 결과를 String으로 받아오는 변수val s: String = "My Lovely Baby"println(strToLower(s)) //my lovely baby 이렇게 변수가 함수 역할을 할 수 있다는 점을 이용해서 String 클래스의 lowercase 메소드를 참조하여 해당 변수를 이용해서 .. 2024. 10. 10.
고차함수(1) - 선언과 사용 고차함수란?일급 함수이면서 일급객체를 사용할 수 있는 것이다. 일급 함수란 함수가 변수 역할을 하는 것이고, 일급 객체란 함수의 실 인자로 사용할 수 있으며, 함수의 반환 값으로도 사용할 수 있는 것이다.   일반 함수와 고차함수의 차이// 일반 함수fun multiply(a: Int, b: Int): Int { return a * b} 일반 함수는 위와 같이 변수만 인자로 받아서 그 변수들을 통해 연산을 해서 값을 반환한다.  fun multiply(a: Int, b: Int, hfunc:(Int, Int) -> Int): Int { return hfunc(a, b)} 하지만 고차함수는 함수를 인자로 받을 수 있다. 즉, 인자로 전달 받은 함수와 전달 받은 변수의 값들을 이용해서 값을 반환한.. 2024. 10. 10.
Kotiln - 함수 함수의 기본 형태fun 함수이름(매개변수: 매개변수 타입) : 반환 타입 { //함수 동작}   Top-level function과 member functionclass Shape { fun calculateArea_method(w: Int, h: Int, ): Int { // member function = method return w * h }}fun calculateArea_top_level(w: Int, h: Int, ): Int { // top-level function return w * h}  Top-level function: 클래스 밖에 생성된 함수Member function: 클래스에 속한 함수 가변 인자: 인자의 개수가 달라질 수 있다. fun acc.. 2024. 10. 10.
Class(1) - 중첩 클래스와 내부 클래스 중첩 클래스 (Nested Class)inner 키워드 없이 클래스 내부에 선언된 클래스를 중첩 클래스라고 합니다.중첩 클래스는 외부 클래스와 독립적입니다. 즉, 중첩 클래스는 외부 클래스의 인스턴스에 접근할 수 없습니다.외부 클래스와 상관없이 단독으로 인스턴스화할 수 있습니다. 예시:class Outer { val outerValue = "Outer Class" // 중첩 클래스 class Nested { fun nestedFunction() = "Nested Class" }}fun main() { // 중첩 클래스는 외부 클래스의 인스턴스 없이도 사용 가능 val nested = Outer.Nested() println(nested.nestedFunc.. 2024. 10. 1.
Class(1) - 추상 클래스와 인터페이스 추상 클래스(abstract): 추상 클래스는 일부 기능을 미리 구현(abstract 키워드 필요!)할 수 있으며, 나머지 기능은 추상 메소드로 남겨놓아 상속받는 클래스에서 구현하도록 요구할 수 있다. : 완전한 구현과 추상적인 정의를 모두 가질 수 있다. :상속을 통해 기능을 재사용하고, 공통된 동작을 하위 클래스에 제공할 때 유용 // 추상 클래스abstract class Bar { abstract fun foo() // 기능 구현 불가능! 하위 클래스에서 구현해야함 fun bar(){ // 일반 메서드 println("Bar!!!") }}// 상속 받을 떄 () 필수 !!!!!!class Foo : Bar() { override fun foo() { .. 2024. 10. 1.
Class(1) - 상속 상속 (Inheritance)상속에는 클래스 상속과 인터페이스 상속이 있는데 우선 클래스 상속에 대해서만 알아보자. 클래스 상속은 단일 상속이므로 한 부모에게만 상속 받을 수 있다. 부모클래스 명칭super classbase classparent class 자식 클래스 명칭sub class derived classchild calss  부모 클래스를 선언하고 자식 클래스에 상속 하는 과정: 상속이 가능하게 하려면 부모 클래스가 될 클래스 앞에 open이라는 키워드를 작성해주어야한다.   [상속하기 전 3개의 클래스 선언] class Animal { var color: String = "" fun eat(){ println("냠냠") }}class Dog { var col.. 2024. 10. 1.
Class(1) - getter, setter 속성 (getter, setter)값을 읽어오는 것을 getter, 값을 설정해주는 것을 setter라고 한다. 기본적으로 코틀린에서는 프로퍼티를 생성하면 val, var에 따라서 자동으로 getter 또는 setter를 작성해준다. (직접 정의할 수도 있다.) val getter만 생성된다. -> val은 값을 할당할 수 없기 떄문이다.vargetter, setter 모두 생성된다.    getter 정의해보기 class Person() { val name: String = "Kim" get(){ //get() = field로 생략 가능 return field } var age: Int = 24 get(){ //get() = fiel.. 2024. 10. 1.
Class(1) - 클래스 선언과 생성자 클래스 및 객체 // 클랙스 선언 - 캡슐화class Person { // 프로퍼티 val name: String = "Kim" var age: Int = 24 var isMarried: Boolean = false //메서드 fun getName() = println("Your name is ${this.name}")}fun main() { val p = Person() //기본 생성자 호출 //dot-notation println(p.name) //Kim} 이렇게 클래스를 선언하고 main함수에서 클래스의 객체를 선언해서 해당 클래스에 있는 요소들에 접근할 수 있다.   하지만 클래스를 사용하는 이유는 커스텀 타입을 만들기 위해서이다. 즉, 여러 데이터.. 2024. 9. 30.
Kotlin_Basic03 - when(2) when을 사용할 때 우리는 꼭 필수적으로 사용한 코드가 있다. 바로 else이다.하지만 변수의 범위를 명확하게 만들면 else는 필요없다. (물론 사용해도 됨) 그 예시로는 enum과 sealed classe가 있다.enum과 sealed class를 각각 사용한 예시1. enum class 사용 예시enum class는 상수들을 정의할 때 사용되며, 상태나 값을 구분할 때 매우 유용하다.enum class Direction { NORTH, SOUTH, EAST, WEST}fun describeDirection(direction: Direction): String { return when (direction) { Direction.NORTH -> "You are heading N.. 2024. 9. 20.
Kotlin_Basic03 - when(1) 코틀린에서 when 문법은 조건에 따라 여러 분기처리를 할 수 있는 강력한 제어 구조이다.when은 switch 문과 비슷하지만 더 유연하고 강력하게 사용할 수 있다. 주로 값을 매칭하거나 조건을 검사할 때 사용된다.기본 형태val value = 2val result = when (value) { 1 -> "One" 2 -> "Two" 3 -> "Three" else -> "Unknown"}print(result) // Twovalue가 1일 경우 "One", 2일 경우 "Two", 3일 경우 "Three"를 반환하고, 그 외의 값은 "Unknown"을 반환한다.else는 기본적인 값을 처리할 때 사용되며, 반드시 포함해야 한다(모든 경우의 수를 처리하지 않을 경우). 여러 조건 처.. 2024. 9. 20.
Kotlin_Basic03 - null 처리 우리는 변수에 값이 null일수도 있고 아닐 수도 있는 경우를 위해서 nullable 타입을 사용해왔다. 다만 이 타입을 사용한 변수를 사용할 때는 늘 이 변수가 null 값을 가질 수 있다는 생각에 안전조치를 해야했다. val str1: Any = "hello"val str2: Any = nullfun checkTypecast(s: Any?): Sting? { val newStr = s as? String ?: return null if(newStr.isNotEmpty()){ return newStr.lowercase() } return ""} 이렇게 위와 같이 as 연산자를 이용하든, 변수를 사용하든 ?를 붙여줘야 했다. 하지만 이런 수고를 덜어줄 수 있는 방법이 있다. .. 2024. 9. 20.
Kotlin_Basic03 - if 식 if문은 흔히 많이 들어본 분기문이다.  그러면 if 식은 뭘까? if식은 if문과 마찬가지로 조건에 따라 블록 내부의 코드가 실행되는 것은 같다. 다만, 코드 블록 값이 어떤 변수에 저장된다는 점이 다르다 val a = 9val b = 8val max = if(a >= b) a else b 이런 식으로 진행하면 a가 b보다 크거나 같을 경우 a가 max에 입력되고 아니면 b가 입력된다. 위 처럼 간단하면 블록 없이 해도 괜찮지만, 복잡하다면 블록을 만들어서 진행하면된다.val a = 9val b = 8val max = if(a >= b) { a } else { b}  하지만 여기서 주의할 점은 블록 내부 마지막 코드가 변수에 저장되기 때문에 마지막 코드는 꼭 저장할 변수 또는 수를 작성해야한.. 2024. 9. 20.