
코틀린 강의 끝나고 자바의 쓰레드, 스트림 공부할 예정
미니프로젝트 학생정보관리프로그램 만들 예정
라이브러리 배포를 위한 서버
Maven
Gradle
안드로이드는 Gradle을 사용하고 있음
Reflection 라이브러리도 Gradle에서 이용
import kotlin.reflect.KClass
fun main(){
// 클래스 타입
// 코틀린에서의 클래스
val a1:KClass<String> = String::class
println("String의 클래스 이름(코틀린) : $a1")
// 자바에서의 클래스
val a2:Class<String> = String::class.java
println("String의 클래스 이름(자바) : $a2")
// 변수를 통해 접근할 수 있는 객체의 클래스 타입을 파악한다.
val str1 = "안녕하세요"
val a3:KClass<out String> = str1::class
println("str1을 통해 접근할 수 있는 객체의 클래스 타입(코틀린) : $a3")
val a4:Class<out String> = str1::class.java
println("str1을 통해 접근할 수 있는 객체의 클래스 타입(자바) : $a4")
val test1 = TestClass(100,200,300)
val a5 = test1::class
val a6 = test1::class.java
println("test1의 클래스 타입(코틀린) : $a5")
println("test1의 클래스 타입(자바) : $a6")
}
class TestClass(var number1:Int, var number2:Int, var number3:Int){
var number4:Int = 0
var number5:Int = 0
constructor(a1:Int) : this(100,200,300)
constructor(a1:Int, a2:Int) : this(100,200,300)
fun testMethod1(){
}
fun testMethod2(a1:Int, a2:Int){
}
}
String의 클래스 이름(코틀린) : class kotlin.String
String의 클래스 이름(자바) : class java.lang.String
str1을 통해 접근할 수 있는 객체의 클래스 타입(코틀린) : class kotlin.String
str1을 통해 접근할 수 있는 객체의 클래스 타입(자바) : class java.lang.String
test1의 클래스 타입(코틀린) : class TestClass
test1의 클래스 타입(자바) : class TestClass
fun main(){
val test1 = TestClass(100,200,300)
// 클래스 정보 분석
println("추상 클래스 인가 : ${test1::class.isAbstract}")
println("Companion 인가 : ${test1::class.isCompanion}")
println("Data 클래스 인가 : ${test1::class.isData}")
println("Final 클래스 인가 : ${test1::class.isFinal}")
println("open 클래스 인가 : ${test1::class.isOpen}")
println("중첩 클래스 인가 : ${test1::class.isInner}")
println("Sealed 클래스 인가 : ${test1::class.isSealed}")
}
class TestClass(var number1:Int, var number2:Int, var number3:Int){
var number4:Int = 0
var number5:Int = 0
constructor(a1:Int) : this(100,200,300)
constructor(a1:Int, a2:Int) : this(100,200,300)
fun testMethod1(){
}
fun testMethod2(a1:Int, a2:Int){
}
}
추상 클래스 인가 : false
Companion 인가 : false
Data 클래스 인가 : false
Final 클래스 인가 : true
open 클래스 인가 : false
중첩 클래스 인가 : false
Sealed 클래스 인가 : false
fun main(){
val test1 = TestClass(100,200,300)
// 생성자 정보
// 생성자의 정보를 가지고 있는 객체가 리스트에 담겨져서 전달된다.
val constructors = test1::class.constructors
println(constructors)
for(con in constructors){
println("생성자 : $con")
// 생성자의 매개 변수 목록을 가져온다.
for(param in con.parameters){
println("매개변수 순서 : ${param.index}")
println("매개변수 타입 : ${param.type}")
println("매개변수 이름 : ${param.name}")
}
}
}
class TestClass(var number1:Int, var number2:Int, var number3:Int){
var number4:Int = 0
var number5:Int = 0
constructor(a1:Int) : this(100,200,300)
constructor(a1:Int, a2:Int) : this(100,200,300)
fun testMethod1(){
}
fun testMethod2(a1:Int, a2:Int){
}
}
[fun `<init>`(kotlin.Int): TestClass, fun `<init>`(kotlin.Int, kotlin.Int): TestClass, fun `<init>`(kotlin.Int, kotlin.Int, kotlin.Int): TestClass]
생성자 : fun `<init>`(kotlin.Int): TestClass
매개변수 순서 : 0
매개변수 타입 : kotlin.Int
매개변수 이름 : a1
생성자 : fun `<init>`(kotlin.Int, kotlin.Int): TestClass
매개변수 순서 : 0
매개변수 타입 : kotlin.Int
매개변수 이름 : a1
매개변수 순서 : 1
매개변수 타입 : kotlin.Int
매개변수 이름 : a2
생성자 : fun `<init>`(kotlin.Int, kotlin.Int, kotlin.Int): TestClass
매개변수 순서 : 0
매개변수 타입 : kotlin.Int
매개변수 이름 : number1
매개변수 순서 : 1
매개변수 타입 : kotlin.Int
매개변수 이름 : number2
매개변수 순서 : 2
매개변수 타입 : kotlin.Int
매개변수 이름 : number3
fun main(){
val test1 = TestClass(100,200,300)
// 주생성자
val primaryCon = test1::class.primaryConstructor
// 없으면 null이 반환된다.
if(primaryCon != null){
println("주 생성자 : $primaryCon")
// 주 생성자의 매개변수들
for(param in primaryCon.parameters){
println("매개변수 순서 : ${param.index}")
println("매개변수 타입 : ${param.type}")
println("매개변수 이름 : ${param.name}")
}
}
}
class TestClass(var number1:Int, var number2:Int, var number3:Int){
var number4:Int = 0
var number5:Int = 0
constructor(a1:Int) : this(100,200,300)
constructor(a1:Int, a2:Int) : this(100,200,300)
fun testMethod1(){
}
fun testMethod2(a1:Int, a2:Int){
}
}
주 생성자 : fun `<init>`(kotlin.Int, kotlin.Int, kotlin.Int): TestClass
매개변수 순서 : 0
매개변수 타입 : kotlin.Int
매개변수 이름 : number1
매개변수 순서 : 1
매개변수 타입 : kotlin.Int
매개변수 이름 : number2
매개변수 순서 : 2
매개변수 타입 : kotlin.Int
매개변수 이름 : number3
fun main(){
val test1 = TestClass(100,200,300)
// 프로퍼티
val properties = test1::class.declaredMemberProperties
for(prop in properties){
println("프로퍼티 이름 : ${prop.name}")
}
}
class TestClass(var number1:Int, var number2:Int, var number3:Int){
var number4:Int = 0
var number5:Int = 0
constructor(a1:Int) : this(100,200,300)
constructor(a1:Int, a2:Int) : this(100,200,300)
fun testMethod1(){
}
fun testMethod2(a1:Int, a2:Int){
}
}
프로퍼티 이름 : number1
프로퍼티 이름 : number2
프로퍼티 이름 : number3
프로퍼티 이름 : number4
프로퍼티 이름 : number5
fun main(){
val test1 = TestClass(100,200,300)
// 메서드
val methods = test1::class.declaredMemberFunctions
for(met in methods){
println("메서드 이름 : ${met.name}")
println("메서드 반환타입 : ${met.returnType}")
println("메서드의 매개변수들 : ${met.parameters}")
}
}
class TestClass(var number1:Int, var number2:Int, var number3:Int){
var number4:Int = 0
var number5:Int = 0
constructor(a1:Int) : this(100,200,300)
constructor(a1:Int, a2:Int) : this(100,200,300)
fun testMethod1(){
}
fun testMethod2(a1:Int, a2:Int){
}
}
메서드 이름 : testMethod1
메서드 반환타입 : kotlin.Unit
메서드의 매개변수들 : [instance parameter of fun TestClass.testMethod1(): kotlin.Unit]
메서드 이름 : testMethod2
메서드 반환타입 : kotlin.Unit
메서드의 매개변수들 : [instance parameter of fun TestClass.testMethod2(kotlin.Int, kotlin.Int): kotlin.Unit, parameter #1 a1 of fun TestClass.testMethod2(kotlin.Int, kotlin.Int): kotlin.Unit, parameter #2 a2 of fun TestClass.testMethod2(kotlin.Int, kotlin.Int): kotlin.Unit]
fun main() {
val obj1 = TestClass1(100,200)
val obj2 = TestClass1(10,20)
// 더하기
val obj3 = obj1 + obj2
println("obj3.a1 : ${obj3.a1}")
println("obj3.a2 : ${obj3.a2}")
// 빼기
val obj4 = obj1 - obj2
println("obj4.a1 : ${obj4.a1}")
println("obj4.a2 : ${obj4.a2}")
}
class TestClass1(var a1:Int, var a2:Int){
// 더하기 연산자를 사용하면 호출되는 메서드
// 연산자를 기준으로 좌측의 객체를 통해 메서드가 호출되고
// 매개변수로 우측에 있는 객체의 주소값이 전달된다.
operator fun plus(target:TestClass1) : TestClass1{
val r1 = this.a1 + target.a1
val r2 = this.a2 + target.a2
val result = TestClass1(r1, r2)
return result
}
operator fun minus(target:TestClass1) : TestClass1{
val r1 = this.a1 - target.a1
val r2 = this.a2 - target.a2
val result = TestClass1(r1, r2)
return result
}
}
obj3.a1 : 110
obj3.a2 : 220
obj4.a1 : 90
obj4.a2 : 180
fun main() {
val r1 = testFun1(100,200)
println("r1 : $r1")
val r2 = testFun2(100,200)
println("r2 : $r2")
}
// 매개변수로 들어오는 값을 계산하여 반환하는 함수
fun testFun1(a1:Int, a2:Int) : Int{
return a1 + a2
}
// 위의 함수는 다음과 같이 작성할 수 있다.
// = 다음에 작성한 수식을 계산하여 반환해준다.
fun testFun2(a1:Int, a2:Int):Int = a1 + a2
r1 : 300
r2 : 300
fun main() {
val r3 = testFun3(100,200)
println("r3 : $r3")
}
// 만약 매개변수로 들어오는 값을 계산하여 반환하는 함수 내부의 코드가 여러 줄이라면...
fun testFun3(a1:Int, a2:Int) : Int{
val r1 = a1 + 100
val r2 = a2 + 200
val r3 = r1 + r2
return r3
}
r3 : 600
fun testFun4(a1:Int, a2:Int) : Int = {
val r1 = a1 + 100
val r2 = a2 + 200
val r3 = r1 + r2
r3
} // 에러
val lambda1 : (Int, Int) -> Int = {a1:Int, a2:Int -> a1 + a2}
//매개변수 타입 //반환타입 //매개변수의 이름 정의 //반환값
(Int, Int) : 매개변수의 타입을 정의-> Int : 반환 타입을 정의{a1:Int, a2:Int : 매개변수의 이름을 정의. 앞서 정의한 매개변수의 타입과 일치해야 함-> a1 + a1} : 반환할 값을 작성한 부분fun main() {
val r4 = lambda1(100, 200)
println("r4 : $r4")
}
r4 : 300
val lambda2 = {a1:Int, a2:Int -> a1 + a2}
fun main() {
val r5 = lambda2(100, 200)
println("r5 : $r5")
}
r5 : 300
val lambda3 : (Int, Int) -> Int = {a1, a2 -> a1 + a2}
fun main() {
val r6 = lambda3(100, 200)
println("r6 : $r6")
}
r6 : 300
-> 다음에 나오는 코드 중에 제일 마지막에 작성한 수식의 결과를 반환한다.testFun3과 같이 코드가 여러줄인 것을 람다로 대체할 수 있다.fun testFun3(a1:Int, a2:Int) : Int{
val r1 = a1 + 100
val r2 = a2 + 200
val r3 = r1 + r2
return r3
}
val lambda4 = {a1:Int, a2:Int ->
val r1 = a1 + 100
val r2 = a2 + 200
// 제일 마지막에 작성한 값, 변수의 값, 수식의 결과를 최종 결과로 반환해준다.
a1 + a2
}
fun main() {
val r7 = lambda4(100,200)
println("r7 : $r7")
}
r7 : 300
val testFunction2 = testFunction1 // 에러
fun main() {
// 익명함수 호출
// 익명함수를 가지고 있는 변수를 통해 호출
testFunction3()
}
// 익명함수
val testFunction3 = fun(){
println("익명함수입니다")
}
익명함수입니다
fun main() {
testFunction1()
testFunction1()
testFunction2()
testFunction2()
}
fun testFunction1(){
println("-----------------------")
println("testFunction1")
println("-----------------------")
}
inline fun testFunction2(){
println("-----------------------")
println("testFunction2")
println("-----------------------")
}
-----------------------
testFunction1
-----------------------
-----------------------
testFunction1
-----------------------
-----------------------
testFunction2
-----------------------
-----------------------
testFunction2
-----------------------
testFunction1 은 자바 코드 변환시 함수 그대로 있지만, testFunction2는 자바 코드 변환 시 함수 안의 코드가 풀어져 나온다.
// 확장 함수 : 클래스에 메서드를 추가하는 개념
fun main() {
val str1 = "abcd"
str1.printString()
}
// 확장 함수
// 클래스 이름.함수이름
fun String.printString(){
// 확장함수 안에서 this를 통해 객체 자체에 접근할 수 있다.
println("관리하는 문자열은 : ${this} 입니다")
}
관리하는 문자열은 : abcd 입니다
// infix 함수 : 함수의 호출을 연산자 사용하듯이 할 수 있는 함수
fun main() {
// infix 함수 호출
val r1 = 100 add2 200
println("r1 : $r1")
val r2 = 10 isMultiple 2
println("r2 : $r2")
}
// 기본 자료형에 대한 infix 함수
// 자료형.함수이름(매개변수)
infix fun Int.add2(a1:Int) : Int {
// 여기에서 this는 첫 번째 값을 의미한다.
return this + a1
}
infix fun Int.isMultiple(a1:Int) : Boolean{
val r1 = this % a1 == 0
return r1
}
r1 : 300
r2 : true
fun main() {
val t1 = TestClass1(100, 200)
val t2 = TestClass1(10,20)
val t3 = t1 add2 t2
println(t3.number1)
println(t3.number2)
}
class TestClass1(var number1:Int, var number2:Int){
infix fun add2(target:TestClass1) : TestClass1{
val r1 = this.number1 + target.number1
val r2 = this.number2 + target.number2
val obj1 = TestClass1(r1, r2)
return obj1
}
}
110
220
컴퓨터에서만 돌아가던 자바가 90년대 이후 Web의 등장으로 Web에 진출함
자바의 성공으로 JVM도 업데이트 됨
코틀린은 1990년대 만들어진 JVM을 기초로 함(안정화)
람다의 등장(람다 사용 시 람다를 관리하는 객체가 생성됨)
상속받은 클래스를 만들어 메서드를 오버라이딩하고 객체를 전달하는 과정이
람다식을 만들어 변수로 전달하면 과정이 간단하게 바뀜
람다식과 고차함수를 같이 사용하면 코드를 쉽게 짤 수 있다
자바 기반보다 코틀린 기반의 안드로이드 개발이 훨씬 빨라짐
// 고차 함수 : 매개 변수로 함수를 받거나 함수를 반환하는 함수
fun main(){
// 고차함수에 전달하는 함수는 익명함수를 사용한다.
val t1 = fun(x1:Int, x2:Int) : Int{
return x1 + x2
}
testFunc1(100,200,t1)
val t2 = fun(x1:Int, x2:Int) : Int{
return x1 - x2
}
testFunc1(100,200,t2)
testFunc1(100,200,fun(x1:Int, x2:Int):Int{
return x1 * x2
})
// 람다식을 받는 것도 가능하다.
val lambda1 = {x1:Int, x2:Int -> x1 / x2}
testFunc1(200,100, lambda1)
testFunc1(100,200,{x1:Int, x2:Int -> x1 % x2})
}
// 매개변수로 함수를 받는 함수
// 함수를 받는 매개변수의 타입은 (매개변수 타입) -> 반환값타입 형태로 작성한다.
fun testFunc1(a1:Int, a2:Int, m1:(Int, Int) -> Int){
val r1 = m1(a1, a2)
println("testFunc1 r1 : $r1")
}
testFunc1 r1 : 300
testFunc1 r1 : -100
testFunc1 r1 : 20000
testFunc1 r1 : 2
testFunc1 r1 : 100
fun main(){
// 함수를 반환하는 함수
val m2 = testFunc2(100)
val result1 = m2(200,300)
println(result1)
val m3 = testFunc3(100)
val result2 = m3(200,300)
println(result2)
}
// 함수를 반환하는 함수
// 함수의 반환타입을 (반환할 함수의 매개변수들의 타입) -> 반환타입 형태로 작성해준다.
fun testFunc2(a1:Int) : (Int, Int) -> Int {
// 함수 내부에 선언된 변수
// val a1 = 100
return fun(x1:Int, x2:Int):Int{
// 반환되는 함수 안에서 함수를 반환하는 함수의 변수나 매개변수를 사용하는 것이 가능하다.
return x1 + x2 + a1
}
}
// 람다식 사용
fun testFunc3(a1:Int) : (Int, Int) -> Int{
return {x1:Int, x2:Int -> x1 + x2 + a1}
}
600
600
fun main(){
// testFunc1처럼 매개변수들 중에 제일 마지막에 있는 것이 함수나 람다를 받는 매개변수일 경우
testFunc1(100,200,{x1:Int, x2:Int -> x1 + x2})
// 제일 마지막 매개변수가 람다나 함수를 받는 매개변수이고 람다를 전달할 경우 다음과 같이 작성할 수 있다.
testFunc1(100, 200){x1: Int, x2: Int ->
x1 + x2
}
}
testFunc1 r1 : 300
testFunc1 r1 : 300
fun main(){
testFunc4({x1, x2 -> x1 + x2})
// 클래스의 init함수도 동일한 모양으로 고차함수이다.
testFunc4 {x1, x2 ->
x1 + x2
}
}
// 함수나 람다식을 받는 매개변수만 있는 함수
fun testFunc4(m1:(Int, Int) -> Int){
val r1 = m1(100,200)
println(r1)
}
300
300
it을 사용하면 된다.fun main(){
// testFunc5{x1 ->
// println(x1)
// 100
// }
testFunc5{
println(it)
100
}
}
// 매개변수를 하나만 가지고 있는 함수나 람다를 받는 함수
fun testFunc5(m1:(Int)->Int){
m1(100)
}
100
fun main() {
val t1 = TestClass1(100,200)
t1.a3 = 300
t1.a4 = 400
t1.testMethod1()
}
class TestClass1(var a1:Int, var a2:Int){
var a3:Int = 0
var a4:Int = 0
fun testMethod1(){
println("a1 : $a1")
println("a2 : $a2")
println("a3 : $a3")
println("a4 : $a4")
}
}
a1 : 100
a2 : 200
a3 : 300
a4 : 400
fun main() {
// 이미 생성되어 있는 객체에 코틀린 범위 지정함수를 사용한다.
// let
val t2 = TestClass1(100, 200)
// 첫 번째 매개변수로 객체의 주소값이 들어온다.
// it을 통해 객체의 프로퍼티나 메서드를 사용하면 된다.
t2.let{
it.a3 = 300
it.a4 = 400
it.testMethod1()
}
}
a1 : 100
a2 : 200
a3 : 300
a4 : 400
fun main() {
// 이미 생성되어 있는 객체에 코틀린 범위 지정함수를 사용한다.
// apply
val t3 = TestClass1(100,200)
// apply에 작성한 코드는 apply를 호출한 객체의 메서드로 포함된다.
// this나 아무것도 통하지 않고 프로퍼티나 메서드를 사용하는 것이 가능하다.
t3.apply{
a3 = 300
a4 = 400
testMethod1()
}
}
a1 : 100
a2 : 200
a3 : 300
a4 : 400
fun main() {
// 이미 생성되어 있는 객체에 코틀린 범위 지정함수를 사용한다.
// run
val t4 = TestClass1(100, 200)
t4.run{
a3 = 300
a4 = 400
testMethod1()
}
}
a1 : 100
a2 : 200
a3 : 300
a4 : 400
fun main() {
// 이미 생성되어 있는 객체에 코틀린 범위 지정함수를 사용한다.
// also
val t5 = TestClass1(100, 200)
t5.also{
it.a3 = 300
it.a4 = 400
it.testMethod1()
}
}
a1 : 100
a2 : 200
a3 : 300
a4 : 400
fun main() {
// 이미 생성되어 있는 객체에 코틀린 범위 지정함수를 사용한다.
// with
val t6 = TestClass1(100, 200)
with(t6){
a3 = 300
a4 = 400
testMethod1()
}
}
a1 : 100
a2 : 200
a3 : 300
a4 : 400
fun main() {
val t7 = TestClass1(100,100).let{
it.a3 = 300
it.a4 = 400
it // let 마지막에 it을 작성하여 객체의 주소값이 반환될 수 있도록 해줘야 한다.
}
}
it이 아닌 100을 넣었다면 변수 t7에는 객체의 주소값이 아닌 정수 100이 담긴다.fun main() {
val t8 = TestClass1(100, 200).apply{
a3 = 300
a4 = 400
}
println(t8)
t8.testMethod1()
}
this(혹은 생략)을 통해 프로퍼티나 메서드에 접근할 수 있다.t9)에 담기게 하기 위해서는 람다식 마지막에 this를 명시하여 객체의 주소값을 반환하게 해야 한다.fun main() {
val t9 = TestClass1(100, 200).run{
a3 = 300
a4 = 400
this
}
println(t9)
t9.testMethod1()
}
fun main() {
val t10 = TestClass1(100, 200).also{
it.a3 = 300
it.a4 = 400
}
println(t10)
t10.testMethod1()
}
fun main() {
val t11 = with(TestClass1(100,200)){
a3 = 300
a4 = 400
this
}
println(t11)
t11.testMethod1()
}
fun main() {
// 배열 생성
// 배열이 관리하는 값들을 지정해준다.
// 지정한 값 만큼의 기억장소가 생성되고 그 기억장소들을 관리하는 배열이 생성된다.
// 배열이 관리하는 기억장소의 개수는 변경될 수 없다.
val array1 = arrayOf(10,20,30,40,50)
println("array1: $array1")
}
array1: [Ljava.lang.Integer;@14d9a52c
fun main() {
val array1 = arrayOf(10,20,30,40,50)
println("array1: ${array1.contentToString()}")
}
array1: [10, 20, 30, 40, 50]
fun main() {
val array2 = arrayOf(100, 11.11, "문자열", true)
println("array2 : $array2")
println("array2 : ${array2.contentToString()}")
}
array2 : [Ljava.lang.Object;@21dfaea8
array2 : [100, 11.11, 문자열, true]
fun main() {
val array3 = intArrayOf(10, 20, 30, 40)
// val array3 = intArrayOf(10,20,30,"40") // 에러
val array4 = doubleArrayOf(11.11, 22.22, 33.33, 44.44, 55.55)
// ~~ArrayOf로 생성 못하는 타입의 경우에는 제네릭을 사용
val array5 = arrayOf<String>("문자열1", "문자열2", "문자열3")
println("array3 : ${array3.contentToString()}")
println("array4 : ${array4.contentToString()}")
println("array5 : ${array5.contentToString()}")
}
array3 : [10, 20, 30, 40]
array4 : [11.11, 22.22, 33.33, 44.44, 55.55]
array5 : [문자열1, 문자열2, 문자열3]
fun main() {
// 람다식을 통한 배열 생성
// 람다식 내부의 코드를 수행하여 얻어진 결과를 배열에 담아준다.
// Array(기억장소의 개수)
// 지정된 숫자 만큼 기억장소가 만들어지고 람다식의 제일 마지막에 작성한 값을 담아준다.
// 주어진 람다식을 지정한 개수만큼 반복한다. 첫 번째 기억장소에 담을 값을 결정하기 위해
// 람다식을 수행하고 람다식의 제일 마지막에 작성한 값이 첫 번째 기억 장소에 담기게 된다.
// 이런식으로 모든 기억장소의 수 만큼 람다식이 수행되고 람다식이 전달하는 값은 각각의 기억장소에 담기게 된다.
val array6 = Array(5){
0 // 0이 5개 담긴 배열 생성
}
println("array6 : ${array6.contentToString()}")
}
array6 : [0, 0, 0, 0, 0]
fun main() {
// 람다식에 있는 it에는 0부터 1씩 증가되는 값이 들어온다.
val array7 = Array(5){
it
}
println("array7 : ${array7.contentToString()}")
}
array7 : [0, 1, 2, 3, 4]
fun main() {
// 3부터 3의 배수 10개를 가지고 있는 배열을 생성한다.
val array8 = Array(10){
(it + 1) * 3
}
println("array8 : ${array8.contentToString()}")
}
array8 : [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
fun main() {
// 다차원 배열 생성
// 배열 안에 배열들이 들어가 있는 것
val array9 = arrayOf(
arrayOf(10, 20, 30),
arrayOf(40, 50, 60),
arrayOf(70, 80, 90)
)
println("array9 : ${array9.contentToString()}")
// 다차원 배열일 때는 contentDeepToString메서드를 사용하면 됨
// 배열 안에 있는 배열까지 모두 문자열로 변환해줌
println("array9 : ${array9.contentDeepToString()}")
}
array9 : [[Ljava.lang.Integer;@89a5d042, [Ljava.lang.Integer;@5385da85, [Ljava.lang.Integer;@57b91da8]
array9 : [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
fun main() {
val array1 = arrayOf(10,20,30,40,50)
println("array1[0] : ${array1[0]}")
println("array1[1] : ${array1[1]}")
// [ ] 연산자는 get 메서드를 호출하기 때문에 [ ]를 사용한 것과 동일하다.
println("array1.get(0) : ${array1.get(0)}")
println("array1.get(1) : ${array1.get(1)}")
}
array1[0] : 10
array1[1] : 20
array1.get(0) : 10
array1.get(1) : 20
fun main() {
val array9 = arrayOf(
arrayOf(10, 20, 30),
arrayOf(40, 50, 60),
arrayOf(70, 80, 90)
)
// 다차원 배열 접근
println("array9[0][0] : ${array9[0][0]}")
println("array9[1][1] : ${array9[1][1]}")
}
array9[0][0] : 10
array9[1][1] : 50
fun main() {
val array1 = arrayOf(10,20,30,40,50)
println("array1 : ${array1.contentToString()}")
// 0번째 기억 장소 새로운 값을 저장한다.
array1[0] = 100
println("0번째에 100 설정 : ${array1.contentToString()}")
// [ ] = 값의 문법을 사용하면 set을 호출한다.
array1.set(1, 200)
println("1번째에 200 설정 : ${array1.contentToString()}")
// 배열에 추가한다.
// 원본 배열에 1000이 추가된 새로운 배열을 생성하여 반환한다.
// 배열은 절대 관리하는 기억장소의 개수를 변경시킬 수 없다.
val array10 = array1.plus(1000)
println("1000 추가(원본 유지) : ${array1.contentToString()}")
println("1000 추가(새롭게 생성된 배열) : ${array10.contentToString()}")
}
array1 : [10, 20, 30, 40, 50]
0번째에 100 설정 : [100, 20, 30, 40, 50]
1번째에 200 설정 : [100, 200, 30, 40, 50]
fun main() {
val array1 = arrayOf(10,20,30,40,50)
// 배열에 추가한다.
// 원본 배열에 1000이 추가된 새로운 배열을 생성하여 반환한다.
// 배열은 절대 관리하는 기억장소의 개수를 변경시킬 수 없다.
val array10 = array1.plus(1000)
println("1000 추가(원본 유지) : ${array1.contentToString()}")
println("1000 추가(새롭게 생성된 배열) : ${array10.contentToString()}")
}
1000 추가(원본 유지) : [100, 200, 30, 40, 50]
1000 추가(새롭게 생성된 배열) : [100, 200, 30, 40, 50, 1000]
fun main() {
val array1 = arrayOf(10,20,30,40,50)
// 일부분을 가져온다.
// 지정된 순서값 범위에 해당하는 값들을 가지고 있는 새로운 배열을 생성한다.
// 순서값 1 ~ 3 까지
val array11 = array1.sliceArray(1..3)
println("array11 : ${array11.contentToString()}")
}
array11 : [20, 30, 40]
fun main() {
val array1 = arrayOf(10,20,30,40,50)
// for문과 같이 사용
for(a1 in array1){
println(a1)
}
}
10
20
30
40
50
fun main() {
val array1 = arrayOf(10,20,30,40,50)
// 배열이 제공하는 메서드들
println("첫 번째 값 : ${array1.first()}")
println("마지막 값 : ${array1.last()}")
println("30의 위치(존재하는 값) : ${array1.indexOf(30)}")
println("10000의 위치(없는 값) : ${array1.indexOf(10000)}")
println("평균 : ${array1.average()}")
println("총합 : ${array1.sum()}")
println("관리하는 기억장소의 개수 : ${array1.count()}")
println("관리하는 기억장소의 개수 : ${array1.size}") // 메서드가아니라 프로퍼티임
println("30을 포함하는가 : ${array1.contains(30)}")
println("10000을 포함하는가 : ${array1.contains(10000)}")
}
첫 번째 값 : 100
마지막 값 : 50
30의 위치(존재하는 값) : 2
10000의 위치(없는 값) : -1
평균 : 84.0
총합 : 420
관리하는 기억장소의 개수 : 5
관리하는 기억장소의 개수 : 5
30을 포함하는가 : true
10000을 포함하는가 : false
fun main() {
val array12 = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// 배열이 관리하는 값의 순서를 랜덤하게 섞어 준다.
array12.shuffle()
println(array12.contentToString())
// 정렬(오름 차순)
// 정렬된 배열을 새롭게 생성해서 반환한다.
val array13 = array12.sortedArray()
println(array13.contentToString())
// 정렬(내림 차순)
val array14 = array12.sortedArrayDescending()
println(array14.contentToString())
}
[2, 1, 7, 5, 4, 3, 8, 10, 6, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
※ 출처 : 멋쟁이사자 앱스쿨 2기, 소프트캠퍼스