-
TECHIT 앱 스쿨 2기: Android 20일차 (23.05.23)[THEC!T] 앱 스쿨2기 : Android 2023. 5. 24. 00:25728x90
자료 출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 내용
오늘 오전에는 어제 내주신 간단한 과제에 대하여 설명 및 중첩클래스와 데이터 클래스를 이용하여 작성하면서 개념을 설명해주셨습니다.
오후에는 배열과 문자열, 컬렉션에 대해서 설명해주셨습니다.
코틀린에서 배열은 개발자가 편한대로 작성할 수 있도록 배열관련 문법들을 지원합니다.
배운 내용과 더불어 알고 있는 내용을 조금 추가하여 작성하였으며, 이해하기 쉽도록 IntArray 을 사용하였으며 IntArray 대신 Array를 작성하여도 되며 Array로 작성할 경 코드에서는 c2에 들어가는 람다식에서 자료형을 추가하면 됩니다.
그리고 새로운 배열이 생성되는 것을 확인하기 위하여 변수를 변경하지 않고 진행하였습니다.fun main(){ // 기본 배열 val a1 = arrayOf(10,20) val a11 = arrayOf(10,"문자",11.11) // a2 ~ a4 는 해당 자료형만 저장하는 배열 // String은 일반 배열 val a2 = intArrayOf(100,200) val a3 = doubleArrayOf(11.11) val a4 = booleanArrayOf(true, false) val a5 = charArrayOf('a','b','c') val a6 = arrayOf("문자열") println("배열 내용 출력 방법 .contentToString()") println("a1.contentToString() : ${a1.contentToString()}") println("---------------------------") // 크기가 정해져 있는 배열 생성 // { } 안에 숫자를 적어도 되고, 규칙성 있는 배열을 만들고 싶다면 // 람다식을 전달하여 작성할 수 있다. val b1 = Array(5){0} // it 은 인덱스 번호가 들어온다 0,1,2,3,4 val b2 = Array(5){ (it+1)*5 } println("b1 : ${b1.contentToString()}") println("b2 : ${b2.contentToString()}") println("---------------------------") // 크기가 정해져 있는 배열에서 특정 자료형만을 저장 하는 배열 // String 제외 val c1 = IntArray(5){it * 5} println("c1 : ${c1.contentToString()}") // 배열의 형식이 정해져 있기 때문에 자료형을 생략한 람다식 전달 가능 var c2 = IntArray(5){ i -> i * 10} println("c2 : ${c2.contentToString()}") println("---------------------------") // 자바에서는 배열에 값(객체)를 추가하는 것이 안되었지만 // 코틀린에서는 문법 표시상으로는 추가하는 것처럼 보이게 할 수 있다. // 하지만 실제로는 새로운 배열을 만들어 ID를 전달한다. // 하기 코드는 c2에 500을 더한 배열을 생성하여 c2변수에 생성한 배열(객체)의 ID를 전달한 것이다. println("기존 c2 : ${c2.contentToString()}") println("기존 c2에 저장된 객체의 ID : $c2") c2 += 500 println("c2 += 500 : ${c2.contentToString()}") println("c2 += 500 하고 난 후 c2에 저장된 객체의 ID: $c2") println("---------------------------") // 배열의 값(객체) 변경 println("기존 c2 : ${c2.contentToString()}") c2[0] = 100 println("c2[0] = 100 변경 : ${c2.contentToString()}") println("---------------------------") // 배열의 일부를 가져와 새로운 배열로 만들기 println("기존 c2 : ${c2.contentToString()}") println("기존 c2에 저장된 객체의 ID : $c2") c2 = c2.sliceArray(1 .. 3) println("c2 : ${c2.contentToString()}") println("c2 = c2.sliceArray(1 .. 3) 이후 c2에 저장된 객체의 ID: $c2") println("---------------------------") // 배열이 지원하는 다양한 메서드들 println("기존 c2 : ${c2.contentToString()}") println("첫 번째 값 : ${c2.first()}") println("마지막 값 : ${c2.last()}") println("30의 위치 : ${c2.indexOf(30)}") println("평균 : ${c2.average()}") println("합 : ${c2.sum()}") println("개수 : ${c2.count()}") println("개수 : ${c2.size}") println("30을 포함하는 가 : ${c2.contains(30)}") println("1000 을 포함하는 가 : ${c2.contains(1000)}") println("30을 포함하는 가 : ${30 in c2}") println("1000을 포함하는 가 : ${1000 in c2}") println("최대 : ${c2.max()}") println("최소 : ${c2.min()}") println("---------------------------") // 배열 내 저장된 값을 정렬하여 새로운 배열을 생성한다. var c3 = intArrayOf(100,300,200,600,500) println("기존 c3 : ${c3.contentToString()}") println("기존 c3에 저장된 객체의 ID : $c3") c3 = c3.sortedArray() println("c3.sortedArray() 결과 ${c3.contentToString()}") println("c3.sortedArray() 이후 객체의 ID : $c3") c3 = c3.sortedArrayDescending() println("c3.sortedArrayDescending() 결과 ${c3.contentToString()}") println("c3.sortedArrayDescending() 이후 객체의 ID : $c3") println("---------------------------") // 다 차원 배열 만들기 val c4 = arrayOf( arrayOf(10,20,30), arrayOf(40,50,60), arrayOf(70,60,90) ) println("array9 : $c4") println("array9 : ${c4.contentToString()}") println("array9 : ${c4.contentDeepToString()}") for(item in c4){ for(item2 in item){ println("item2 : $item2") } } }
출력결과
배열 내용 출력 방법 .contentToString() a1.contentToString() : [10, 20] --------------------------- b1 : [0, 0, 0, 0, 0] b2 : [5, 10, 15, 20, 25] --------------------------- c1 : [0, 5, 10, 15, 20] c2 : [0, 10, 20, 30, 40] --------------------------- 기존 c2 : [0, 10, 20, 30, 40] 기존 c2에 저장된 객체의 ID : [I@1d81eb93 c2 += 500 : [0, 10, 20, 30, 40, 500] c2 += 500 하고 난 후 c2에 저장된 객체의 ID: [I@506e1b77 --------------------------- 기존 c2 : [0, 10, 20, 30, 40, 500] c2[0] = 100 변경 : [100, 10, 20, 30, 40, 500] --------------------------- 기존 c2 : [100, 10, 20, 30, 40, 500] 기존 c2에 저장된 객체의 ID : [I@506e1b77 c2 : [10, 20, 30] c2 = c2.sliceArray(1 .. 3) 이후 c2에 저장된 객체의 ID: [I@6e2c634b --------------------------- 기존 c2 : [10, 20, 30] 첫 번째 값 : 10 마지막 값 : 30 30의 위치 : 2 평균 : 20.0 합 : 60 개수 : 3 개수 : 3 30을 포함하는 가 : true 1000 을 포함하는 가 : false 30을 포함하는 가 : true 1000을 포함하는 가 : false 최대 : 30 최소 : 10 --------------------------- 기존 c3 : [100, 300, 200, 600, 500] 기존 c3에 저장된 객체의 ID : [I@31cefde0 c3.sortedArray() 결과 [100, 200, 300, 500, 600] c3.sortedArray() 이후 객체의 ID : [I@1d56ce6a c3.sortedArrayDescending() 결과 [600, 500, 300, 200, 100] c3.sortedArrayDescending() 이후 객체의 ID : [I@5197848c --------------------------- array9 : [[Ljava.lang.Integer;@2e0fa5d3 array9 : [[Ljava.lang.Integer;@5010be6, [Ljava.lang.Integer;@685f4c2e, [Ljava.lang.Integer;@7daf6ecc] array9 : [[10, 20, 30], [40, 50, 60], [70, 60, 90]] item2 : 10 item2 : 20 item2 : 30 item2 : 40 item2 : 50 item2 : 60 item2 : 70 item2 : 60 item2 : 90
배열 다음으로는 문자열에 대하여 학습하였습니다.fun main(){ val str = "가나다라마바사" // 원하는 번째에 해당하는 글자를 가져온다. println("str[0] : ${str[0]}") println("str[5] : ${str[5]}") // 원하는 번째에 해당하는 글자를 변경하는 것은 불가능 하다. // str[6] = "가" // str[6] = '가' // 하지만 특정 문구를 바꾸고 싶다면 replace() 를 사용하여 // 새로운 문자열을 생성할 수 있다. val str2 = str.replace("사", "가") println("str.replace(\"사\", \"가\") : $str2") println("---------------------------------") // 특정 범위의 글자들을 추출하여 새로운 문자열로 받아온다. val str3 = str.substring(2,5) println("str.substring(2,5) : $str3") println("---------------------------------") // 문자열 비교 val str4 = "Hello World" val str5 = "hello world" val str6 = "Hello World" // 코틀린에서 == 가지고 비교를 하면 문자열 값 자체를 비교하는 작업을 수행한다. if(str4 == str5){ println("str3과 str4는 같습니다.") } if(str4 == str6){ println("str3과 str5는 같습니다.") } // compareTo : 같으면 0. 다르면 0 이 아닌 값이 나온다. // compareTo 는 문자영을 구성하는 각 글자의 코드 값을 합산한 결과를 뺀 값을 전달한다. println(str4.compareTo(str5)) println(str4.compareTo(str6)) // 두 번째 매개 변수에 true를 넣어주면 // 모두 소문자로 변환한 다음 코드값을 빼는 작업을 수행한다. // 대소문자를 구분하고 같은가를 확인한다. println(str4.compareTo(str5, true)) // 대소문자를 무시하고 같은지를 비교한다. if(str4.equals(str5, true)){ println("대소문자 무시하고 같습니다.") } println("------------------------------------") // 문자열 병합 val str7 = "abc" // 두 문자열을 합친 새로운 문자열을 만들어 준다. val str8 = str7 + "def" // 문자열이 아닌 값을 새로운 문자열로 만든 다음 // 두 문자열을 합친 새로운 문자열을 만들어준다. val str9 = str8 + 10 println("str7 : $str7") println("str8 : $str8") println("str9 : $str9") // String은 문자열 합치는 작업을 수행할 때 마다 새로운 문자열 객체가 // 계속 생성된다(String은 관리하는 문자열 수정이 불가능하기 때문에...) // 이럴 때는 StringBuffer를 사용한다. val buffer1 = StringBuffer() buffer1.append("abc") buffer1.append(100) buffer1.append(11.11) println("buffer1 : $buffer1") println("------------------------------------") // 구분자를 기준으로 문자열을 나눈다. -> 나누어 list 형태로 반환한다. val str10 = "가 나 다 라 마 바 사 아" // 공백을 기준으로 나누었다. val r1 = str10.split(" ") println("r1 : $r1") }
출력결과
str[0] : 가 str[5] : 바 str.replace("사", "가") : 가나다라마바가 --------------------------------- str.substring(2,5) : 다라마 --------------------------------- str3과 str5는 같습니다. -32 0 0 대소문자 무시하고 같습니다. ------------------------------------ str7 : abc str8 : abcdef str9 : abcdef10 buffer1 : abc10011.11 ------------------------------------ r1 : [가, 나, 다, 라, 마, 바, 사, 아]
다음은 컬렉션 입니다.
list,map,set 등 모두 깊게 들어가면 hashMap 등등 나오지만 기본 개념 위주로 학습하였습니다.
Listfun main(){ // 리스트 생성 // 불변형 리스트 // 리스트 생성 이후 값의 추가, 수정, 삽입, 삭제가 불가능하다. val list1 = listOf(10, 20 ,30, 40, 50) println("list1 : $list1") val list2 = listOf("문자열1", "문자열2", "문자열3") println("list2 : $list2") val list3 = listOf(100, 11.11, "문자열", true) println("list3 : $list3") // 수정 가능 한 리스트 // ArrayList로 생성된다. val list4 = mutableListOf<Int>() val list5 = mutableListOf("문자열1", "문자열2", "문자열3") println("list4 : $list4") println("list5 : $list5") // 비어있는 수정 불가능한 리스트 val list6 = emptyList<Int>() println("list6 : $list6") // null값을 제외하고 생성한다. val list7 = listOf(10, 20, null, 40, null, 60, 70) val list8 = listOfNotNull(10, 20, null, 40, null, 60, 70) println("list7 : $list7") println("list8 : $list8") println("---------------------------------------") // for 문 사용 for(item in list1){ println("item : $item") } // 개수 println("list1.size : ${list1.size}") // 관리할 객체들(값들)이 있고 나중에 추가, 삭제 등을 하지 않을 경우 : arrayOf // 관리할 객체들(값들)이 없으며, 나중에 추가, 삭제 등을 하는 경우 : ArrayList, mutableListOf // 관리할 객체들(값들)이 있고 나중에 추가, 삭제 등을 하는 경우 : mutableListOf // 관리할 객체들(값들)이 있고 나중에 추가, 삭제 등을 하지 않고 관리하는 값을 변경하지 못하게 강제하고 할 때 : listOf println("---------------------------------------") // 관리하는 객체(값)에 접근 // [ ] 연산자를 통해 순서값(0부터 1씩 증가)를 지정하여 접근한다. println("list1 0 : ${list1[0]}") println("list1 1 : ${list1[1]}") println("---------------------------------------") // 일부를 발췌하여 새로운 리스트로 생성한다. val list9 = listOf(10, 20, 30, 10, 20, 30) // 지정된 값이 앞에서 부터 몇 번째에 있는가 val index1 = list9.indexOf(20) println("index1 : $index1") // 지정된 값이 뒤에서 부터 찾아서 앞에서 부터 몇 번째에 있는가 val index2 = list9.lastIndexOf(20) println("index2 : $index2") // 일부를 발췌해 새로운 리스트로 만들어 준다. // 순서 값 1 ~ 3 -1 까지 val list10 = list9.subList(1, 3) println("list10 : $list10") println("---------------------------------------") val list20 = listOf(10, 20, 30) val list21 = mutableListOf(10, 20, 30) // 수정 불가능한 리스트에 값 추가 // 수정 불가능한 리스트에는 추가, 삭제, 수정, 삽입 등의 메서드가 없다. // list20.add(100) // list20[1] = 200 // 수정이 가능한 리스트에 대한 추가, 수정, 삭제, 삽입 // 추가 list21.add(40) list21.add(50) list21.addAll(listOf(60, 70, 80, 90, 100)) println("list21 : $list21") // 삽입 // 순서값 1(두 번째)에 1000을 삽입하고 그 이후의 값들은 뒤로 밀린다. list21.add(1, 1000) println("list21 : $list21") // 순서값 3(네 번째)에 지정된 요소가 관리하는 값드을 모두 추가하고 그 이후의 값들은 뒤로 밀린다. list21.addAll(3, listOf(2000, 3000, 4000, 5000)) println("list21 : $list21") // 제거 // 지정된 값을 제거한다. list21.remove(1000) println("list21 : $list21") // 제거 하고자 하는 값이 같은 것이 여러개가 있다면 제일 앞쪽에는 값 하나만 제거한다. list21.add(1000) list21.add(1000) list21.add(1000) println("list21 : $list21") list21.remove(1000) println("list21 : $list21") // 없는 값을 제거 // 아무 작업도 하지 않는다. list21.remove(10000) println("list21 : $list21") // 제거 하기 위해 지정한 것들을 모두 제거한다. list21.removeAll(listOf(2000, 3000, 4000, 5000)) println("list21 : $list21") // removeAll을 통해 같은 값이 다수 저장되어 있는 것을 제거 list21.removeAll(listOf(1000)) println("list21 : $list21") // 위치를 지정하여 제거한다. // 두 번재 값을 제거한다. list21.removeAt(1) println("list21 : $list21") // 값을 수정한다. // 두 번재 값을 200으로 덮어 씌운다. list21.set(1, 200) println("list21 : $list21") list21[2] = 300 println("list21 : $list21") println("---------------------------------------") val list100 = listOf(10, 20, 30, 40, 50) // list 안에 저장되어 있는 객체(값)을 추출하여 mutableList로 생성하여 반환한다. val list200 = list100.toMutableList() list200.add(60) println("list100 : $list100") println("list200 : $list200") // mutableList 안에 저장되어 있는 객체(값)을 추출하여 list로 생성하여 반환한다. val list300 = list200.toList() // list300.add(70) }
출력결과
list4 : [] list5 : [문자열1, 문자열2, 문자열3] list6 : [] list7 : [10, 20, null, 40, null, 60, 70] list8 : [10, 20, 40, 60, 70] --------------------------------------- item : 10 item : 20 item : 30 item : 40 item : 50 list1.size : 5 --------------------------------------- list1 0 : 10 list1 1 : 20 --------------------------------------- index1 : 1 index2 : 4 list10 : [20, 30] --------------------------------------- list21 : [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] list21 : [10, 1000, 20, 30, 40, 50, 60, 70, 80, 90, 100] list21 : [10, 1000, 20, 2000, 3000, 4000, 5000, 30, 40, 50, 60, 70, 80, 90, 100] list21 : [10, 20, 2000, 3000, 4000, 5000, 30, 40, 50, 60, 70, 80, 90, 100] list21 : [10, 20, 2000, 3000, 4000, 5000, 30, 40, 50, 60, 70, 80, 90, 100, 1000, 1000, 1000] list21 : [10, 20, 2000, 3000, 4000, 5000, 30, 40, 50, 60, 70, 80, 90, 100, 1000, 1000] list21 : [10, 20, 2000, 3000, 4000, 5000, 30, 40, 50, 60, 70, 80, 90, 100, 1000, 1000] list21 : [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 1000, 1000] list21 : [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] list21 : [10, 30, 40, 50, 60, 70, 80, 90, 100] list21 : [10, 200, 40, 50, 60, 70, 80, 90, 100] list21 : [10, 200, 300, 50, 60, 70, 80, 90, 100] --------------------------------------- list100 : [10, 20, 30, 40, 50] list200 : [10, 20, 30, 40, 50, 60]
Mapfun main(){ // 수정 불가능한 map // 이름 to 값(객체) // 이름은 꼭 문자열이 아니어도 된다. val map1 = mapOf("key1" to 10, "key2" to 20, "key3" to 30) println("map1 : $map1") val map2 = mapOf(10 to "str1", 20 to "str2", 30 to "str3") println("map2 : $map2") // 수정 가능한 map val map3 = mutableMapOf("key1" to 10, "key2" to 20, "key3" to 30) println("map3 : $map3") // mapOf 혹은 mutableMapOf를 사용할 때 제네릭을 설정하는 것을 권장하고 있다. // 이름과 값의 타입이 모두 같을 경우 val map4 = mapOf<String, Int>("key1" to 10, "key2" to 20, "key3" to 30) println("map4 : $map4") // 만약 이름이나 값의 타입이 다양하게 저장된다면 Any로 설정해준다. val map5 = mapOf<String, Any>("key1" to 10, "key2" to 11.11) println("map5 : $map5") // 제네릭은 어떠한 경우라도 생략이 가능하기 때문에 그냥 생략하고 사용해도 된다. val map6 = mapOf("key1" to 10, "key2" to 20, "key3" to 30) val map7 = mapOf("key1" to 10, "key2" to 11.11) println("map6 : $map6") println("map7 : $map7") // 비어있는 map // 비어있는 map을 만들 때는 값이 없기 때문에 제네릭을 자동으로 설정할 수 없다. // 따라서 제네릭을 무조건 작성해 줘야 한다. val map8 = mapOf<String,Int>() val map9 = mutableMapOf<String, Int>() println("-------------------------------") // 관리하는 객체(값)을 가지고 온다. val map10 = mapOf("key1" to 10, "key2" to 20, "key3" to 30) val map11 = mutableMapOf("key1" to 10, "key2" to 20, "key3" to 30) println("map10 key1 : ${map10.get("key1")}") println("map11 key1 : ${map11.get("key1")}") println("map10 key1 : ${map10["key1"]}") println("map11 key1 : ${map11["key1"]}") println("-------------------------------") // 관리하는 값(객체)의 개수 println("map1 size : ${map1.size}") // 이름들을 가져온다. println("map1 keys : ${map1.keys}") // 값들을 가져온다. println("map1 values : ${map1.values}") // 이 이름의 값이 있는지 확인하기 println("map1 contains ket - key1 : ${map1.containsKey("Key1")}") println("map1 contains ket - key100 : ${map1.containsKey("Key100")}") // 이 값이 저장되어 있는지 println("map1 contains value - 10 : ${map1.containsValue(10)}") println("map1 contains value - 100 : ${map1.containsValue(100)}") println("-------------------------------") val map12 = mutableMapOf("a1" to 10, "a2" to 20) println("map12 : $map12") // 추가 map12.put("a3",30) println("map12 : $map12") map12["a4"] = 40 println("map12 : $map12") // 수정 : 없는 이름으로 값을 넣어주면 추가가 되고 있는 이름으로 값을 넣어주면 // 수정된다. map12["a1"] = 100 println("map12 : $map12") // 삭제 map12.remove("a1") println("map12 : $map12") println("-------------------------------") // mapOf -> mutableMapOf val map13 = mapOf("a1" to 10, "a2" to 20, "a3" to 30) val map14 = map13.toMutableMap() map14["a4"] = 40 println("map14 : $map14") // mutableMapOf -> mapOf val map15 = map14.toMap() //map15["a5"] = 50 }
출력결과
map1 : {key1=10, key2=20, key3=30} map2 : {10=str1, 20=str2, 30=str3} map3 : {key1=10, key2=20, key3=30} map4 : {key1=10, key2=20, key3=30} map5 : {key1=10, key2=11.11} map6 : {key1=10, key2=20, key3=30} map7 : {key1=10, key2=11.11} ------------------------------- map10 key1 : 10 map11 key1 : 10 map10 key1 : 10 map11 key1 : 10 ------------------------------- map1 size : 3 map1 keys : [key1, key2, key3] map1 values : [10, 20, 30] map1 contains ket - key1 : false map1 contains ket - key100 : false map1 contains value - 10 : true map1 contains value - 100 : false ------------------------------- map12 : {a1=10, a2=20} map12 : {a1=10, a2=20, a3=30} map12 : {a1=10, a2=20, a3=30, a4=40} map12 : {a1=100, a2=20, a3=30, a4=40} map12 : {a2=20, a3=30, a4=40} ------------------------------- map14 : {a1=10, a2=20, a3=30, a4=40}
Setfun main(){ // 수정 불가능한 set val set1 = setOf(10, 20, 30, 10, 20, 30) // 수정 가능한 set val set2 = mutableSetOf(10, 20, 30, 10, 20, 30) println("set1 : $set1") println("set2 : $set2") // 추가 set2.add(40) println("set2 : $set2") set2.add(10) println("set2 : $set2") // set -> list val list1 = set2.toList() val list2 = set2.toMutableList() println("list1 : $list1") println("list2 : $list2") // list -> set val list3 = listOf(10, 20, 30, 10, 20, 30) val set3 = list3.toSet() val set4 = list3.toMutableSet() println("set3 : $set3") println("set4 : $set4") }
출력결과
set1 : [10, 20, 30] set2 : [10, 20, 30] set2 : [10, 20, 30, 40] set2 : [10, 20, 30, 40] list1 : [10, 20, 30, 40] list2 : [10, 20, 30, 40] set3 : [10, 20, 30] set4 : [10, 20, 30]
마무리
오늘은 알고리즘을 공부하면서 혹은 독학을 하면서 자연스럽게 알게 되었던 개념등을 다시 복습하여 좋았습니다.
이제 코틀린 문법 중 남은 것은 쓰레드, 예외처리, 스트림 등이 있고 아마 그에 따른 과제를 작성하게 될텐데 지난 번 자바보다는 좀 더 어려운 문제가 나올 것으로 예상이 되어 걱정이 되지만, 복기를 하다 보면 좋은 결과가 있을 거라 생각 됩니다.
오늘의 마음가짐
모르면 공부하고, 질문하고, 이해하여 발전하는 개발자가 되자~!'[THEC!T] 앱 스쿨2기 : Android' 카테고리의 다른 글
TECHIT 앱 스쿨 2기: Android 22일차 (23.05.25) (0) 2023.05.26 TECHIT 앱 스쿨 2기: Android 21일차 (23.05.24) (0) 2023.05.25 TECHIT 앱 스쿨 2기: Android 19일차 (23.05.22) (0) 2023.05.23 TECHIT 앱 스쿨 2기: Android 18일차 (23.05.18) (0) 2023.05.18 TECHIT 앱 스쿨 2기: Android 17일차 (23.05.17) (0) 2023.05.17