Kotlin

[Kotlin] ์ฝ”ํ‹€๋ฆฐ ๋ฌธ๋ฒ• ๊ณ ๊ธ‰ 1

soogoori 2024. 7. 8. 14:26

์ปฌ๋ ‰์…˜

  • ๊ธฐ๋ณธ ์ปฌ๋ ‰์…˜ ํƒ€์ž… ๐Ÿ‘‰ List, Set, Map
fun main(){
	
    // immutable
    val currencyList = listOf("๋‹ฌ๋Ÿฌ", "์œ ๋กœ", "์›") // add ๋ถˆ๊ฐ€
    val numberSet = setOf(1, 2, 3, 4)
    val numberMap = mapOf("one" to 1, "two" to 2) // to ์ค‘์œ„ํ•จ์ˆ˜๋กœ key-value ๊ตฌ์กฐ ์ „๋‹ฌ
    
    // mutable
    
    // 1) List
    val mutableCurrencyList = mutableListOf<String>()
    mutableCurrencyList.add("๋‹ฌ๋Ÿฌ")
    mutableCurrencyList.add("์œ ๋กœ")
    mutableCurrencyList.add("์›")
    
    // 2) Set
    val mutableSet = mutableSetOf<Int>()
    
    // 3) Map
    val mutableNumberMap = mutableMapOf<String, Int>()
    mutableNumberMap["one"] = 1
    mutableNumberMap["two"] = 2
    mutableNumberMap["three"] = 3
}

 

  • apply ํ•จ์ˆ˜ ์‚ฌ์šฉ ์‹œ ๊ฐ€๋…์„ฑ ์ข‹์•„์ง
val mutableCurrencyList = mutableListOf<String>().apply {
    add("๋‹ฌ๋Ÿฌ")
    add("์œ ๋กœ")
    add("์›")
}

 

  • ์ปฌ๋ ‰์…˜ ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•ด ์ปฌ๋ ‰์…˜ ์ƒ์„ฑ ๊ฐ€๋Šฅ ๐Ÿ‘‰ buildList, buildSet, buildMap
val numberList: List<Int> = buildList {
    // buildMap ๋‚ด๋ถ€์—” MutableMap
    add(1)
    add(2)
    add(3)
}

 

 

 

๐Ÿ”ท ์ปฌ๋ ‰์…˜ ๋ฐ˜๋ณต

  • ์ปฌ๋ ‰์…˜์€ Iterable ๊ตฌํ˜„์ฒด์ด๋ฏ€๋กœ ์ˆœ์ฐจ์  ๋ฐ˜๋ณต ๊ฐ€๋Šฅ 
val iterator = currencyList.iterator()
while (iterator.hasNext()) {
	println(iterator.next())
}
for (currency in currencyList) {
	println(currency)	
}
  • forEach, map, filter์™€ ๊ฐ™์€ ์ธ๋ผ์ธ ํ•จ์ˆ˜ ์ œ๊ณต
currency.forEach {
	println(it)
}

 

  • for loop๋ฅผ map์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์ „
val lowerList = listOf("a", "b", "c", "d")
val upperList = mutableListOf<String>()

for(lowerCase in lowerList){
	upperList.add(lowercase.uppercase())
}

println(upperList)
// // [A, B, C, D]
  • map์œผ๋กœ ๋ณ€ํ™˜ ํ›„
val upperList = lowerList.map { it.uppercase() }
println(upperList)
// [A, B, C, D]

 

  • filter ๋ณ€ํ™˜ ์ „
val filteredList = mutableListOf<String>()
for (upperCase in upperList) {
    if (upperCase == "A" || upperCase == "C") {
    	filteredList.add(upperCase)
    }
}
println(filteredList)
// [A, C]
  • filter ๋ณ€ํ™˜ ํ›„
val filteredList = upperList.filter { it == "A" || it == "C" }
println(filteredList)
// [A, C]

 

 

๐Ÿ’ฅ ์ž๋ฐ” 8์˜ ์ŠคํŠธ๋ฆผ๊ณผ ๋น„๊ต
val filteredList = upperList.stream().filter { it == "A" || it == "C" }

println(filteredList)
// java.util.stream.ReferencePipeline$2@77b52d12โ€‹

 

๐Ÿ‘‰ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ž(map, filter, flatMap ๋“ฑ)๋งŒ ์‚ฌ์šฉ์‹œ ์•„๋ฌด๋Ÿฐ ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๊ฐ’์„ ์–ป๊ณ  ์‹ถ์œผ๋ฉด ์ตœ์ข… ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
val filteredList = upperList.stream()
    .filter { it == "A" || it == "C" }
    .collect(Collectors.toList())
    
println(filteredList)
// [A, C]โ€‹


๐Ÿ”น ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” sequence๋ฅผ ์‚ฌ์šฉํ•ด ์ž๋ฐ” 8 ์ŠคํŠธ๋ฆผ๊ณผ ๊ฐ™์ด Lazyํ•˜๊ฒŒ ๋™์ž‘์‹œํ‚ฌ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‹œํ€€์Šค API๋„ ์ตœ์ข… ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ž๊ฐ€ ๋™์ž‘

val filteredList = upperList
    .asSequence()
    .filter { it == "A" || it == "C" }
    .filter {it == "C" }
    .filter {it == "C" }
    .filter {it == "C" }
    .filter {it == "C" }
    .toList()
    
println(filteredList)
// [A, C]


๐Ÿ‘‰ ์‹œํ€€์Šค API๋Š” ๊ฐ๊ฐ์˜ ํ•จ์ˆ˜๊ฐ€ ๋™์ž‘ํ•  ๋•Œ ์‹œํ€€์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ตœ์ข… ์—ฐ์‚ฐ์ž๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ 1๊ฐœ์˜ ์ปฌ๋ ‰์…˜ ์ƒ์„ฑ
๐Ÿ‘‰ ์ผ๋ฐ˜์ ์œผ๋กœ ์ธ๋ผ์ธ ํ•จ์ˆ˜๊ฐ€ ๋น ๋ฅด๋ฏ€๋กœ ์ธ๋ผ์ธ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋‚˜, ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๊ฑฐ๋‚˜ ์ฒด์ธ์ด ๋งŽ์•„์งˆ ๋•Œ๋Š” ์‹œํ€€์Šค  API ์‚ฌ์šฉ ์ถ”์ฒœ

 

 

 

๋ฐ์ดํ„ฐ ํด๋ž˜์Šค

๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ด€ํ•˜๊ฑฐ๋‚˜ ์ „๋‹ฌํ•˜๋Š” ๋ชฉ์ ์„ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉ ๐Ÿ‘‰ DTO
data class Person(val name: String, val age: Int)
  • ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค ์‚ฌ์šฉ ์‹œ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํ•จ์ˆ˜
    • equals()
    • hashCode()
    • toString()
    • componentN(), copy()
  • ๊ธฐ์กด ์ž๋ฐ”์—์„œ๋Š” ์ฃผ๋กœ Lombok ์‚ฌ์šฉ ๐Ÿ‘‰ @Data
  • JDK 15์—์„œ๋Š” record
@Data
public class Person {
    private final String name;
    private final int age;
}

public record Person(String name, int age) {
}

 

โœจ Kotlin decomplie to Java

์ธํ…”๋ฆฌ์ œ์ด์—์„œ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์ฝ”ํ‹€๋ฆฐ ํŒŒ์ผ์„ ์ž๋ฐ”๋กœ decompile ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.


Tools > Kotlin > Show Kotlin Bytecode > decompile ์„ ๋ˆ„๋ฅด๋ฉด

์ด๋ ‡๊ฒŒ ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์–ด ์ž๋ฐ” ์ฝ”๋“œ๋กœ๋Š” ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

๐Ÿ”ท ๋ฐ์ดํ„ฐํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

  • ๊ฐ์ฒด ๋™๋“ฑ์„ฑ ๋น„๊ต (equals)
// ์ผ๋ฐ˜ ํด๋ž˜์Šค
class Person(val name: String, val age: Int)

fun main() {
    val person1 = Person(name = "tony", age = 12)
    val person2 = Person(name = "tony", age = 12)
    println(person1 == person2)
}
// false
// ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค
data class Person(val name: String, val age: Int)

fun main() {
    val person1 = Person(name = "tony", age = 12)
    val tony2 = Person(name = "tony", age = 12)
    println(person1 == person2)
}
// true

 

  • hashCode
    • equals ์žฌ์ •์˜ํ•  ๋•Œ ๋ฐ˜๋“œ์‹œ hashCode๋„ ์žฌ์ •์˜
data class Person(val name: String, val age: Int)

fun main() {
    val person1 = Person(name = "tony", age = 12)
    val person2 = Person(name = "tony", age = 12)
    println(person1 == person2)
    // true
    
    val set = hashSetOf(person1)
    println(set.contains(person2))
    // true
}

 

  • toString
data class Person(val name: String, val age: Int)

fun main() {
    val person1 = Person(name = "tony", age = 12)
    println(person1.toString())
}
// Person(name=tony, age=12)
  • copy
    • ํ”„๋กœํผํ‹ฐ๋ฅผ val๋กœ ์œ ์ง€ํ•ด ๋ถˆ๋ณ€์„ฑ ์œ ์ง€
    • ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด์„œ ์ƒˆ๋กœ์šด ๋ถˆ๋ณ€ ๊ฐ์ฒด ์ƒ์„ฑ
data class Person(val name: String, val age: Int)

fun main() {
    val person1 = Person(name = "tony", age = 12)
    val person2 = person1.copy(name= "strange")
    
    println(person2.toString())
    // Person(name=strange, age=12)
}
  • componentN ๐Ÿ‘‰ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๊ฐ€์ ธ์˜ด
fun main() {
    val person1 = Person(name = "tony", age = 12)
    
    println("์ด๋ฆ„=${person1.component1()}, ๋‚˜์ด=${person1.component2()}")
    // ์ด๋ฆ„=tony, ๋‚˜์ด=12
}

 

 

 

 

์‹ฑ๊ธ€ํ†ค๊ณผ ๋™๋ฐ˜๊ฐ์ฒด

ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜์˜ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋กœ ์ œํ•œ
๊ฐ์ฒด ์„ ์–ธ
์„ ํ†ตํ•ด ์‹ฑ๊ธ€ํ†ค ๊ธฐ๋ณธ ์ง€์› ๐Ÿ‘‰ object ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ

 

๐Ÿ”ท ์‹ฑ๊ธ€ํ†ค

object Singleton {
	val a = 1234
    	
	fun printA() = println(a)
}

fun main() {
    println(Singleton.a)
    Singleton.printA()
}

 

๐Ÿ”ท ๋™๋ฐ˜๊ฐ์ฒด

ํด๋ž˜์Šค ๋‚ด๋ถ€์— ์ •์˜๋˜๋Š” ๊ฐ์ฒด๋กœ, ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉค๋ฒ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•จ
๐Ÿ‘‰ ์ž๋ฐ”์˜ static ๋ฉค๋ฒ„์™€ ์œ ์‚ฌํ•œ ์—ญํ•  

companion
ํ‚ค์›Œ๋“œ ์‚ฌ์šฉํ•ด ํด๋ž˜์Šค ๋‚ด๋ถ€์— ๊ฐ์ฒด ์„ ์–ธ ์‚ฌ์šฉ

 

class MyClss{
	private constructor()
    
    companion object {
    	val a = 1234
        
        fun newInstance() = MyClass()
    }
}

fun main() {
	println(MyClass.a)
    println(MyClass.newInstance())
    
    // ์ด๋ ‡๊ฒŒ๋„ ๊ฐ€๋Šฅํ•˜๋‚˜ ์ƒ๋žต ๊ฐ€๋Šฅ
    println(MyClass.Companion.a)
    println(MyClass.Companion.newInstance())
}

๐Ÿ‘‰ ์ƒ์„ฑ์ž๋ฅผ private์œผ๋กœ ์ˆจ๊ธฐ๊ณ  newInstance ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๊ฐ์ฒด ์ƒ์„ฑ ๊ฐ€๋Šฅ