Kotlin 목록 유형에는 두 가지가 있다.
List
는 수정할 수 없다.MutableList
는 수정할 수 있다. 즉 요소를 추가, 삭제, 업데이트할 수 있다.list를 사용하는 방법은 다음과 같다. kotlin은 변수 유형을 추론할 수 있기 때문에 2번째 표현 방식으로 작성할 수 있다.
val numbers: List<Int> = listOf(1,2,3,4,5,6)
val numbers = listOf(1,2,3,4,5,6) // 똑같은 표현
println("Size: ${numbers.size}")
index로 element 접근
println("First element: ${numbers[0]}")
first(), last()
println("First: $numbers.first()")
println("Last: $numbers.last()")
contains() 존재하는지 확인하기
println("${numbers.contains(4)}")
→ true
println("${numbers.contains(7)}")
→ false
reversed()
println("${colors.reversed()}")
배열이 역순으로 출력된다. 실제 배열의 순서는 그대로.
sorted()
println("${colors.sorted()}")
사전순으로 정렬되어 출력된다. 실제 배열의 순서는 그대로.
대표적인 예제를 살펴봤는데 이것을 전부 외워야하는 것은 아니다. 안드로이드 스튜디오에서 사용할 수 있는 함수와 속성을 확인할 수 있다.
val entrees = mutablelistOf()
이 코드는 에러가 발생한다. 변수 유형을 추론할 수 없기 때문.
아래 두 코드 중 하나로 수정할 수 있다.
val entrees = mutableListOf<String>()
val entrees: MutableList<String> = mutableListOf()
참고: 변경 가능한 목록에
val
를 사용할 수 있습니다.entrees
변수에 목록 참조가 포함되어 있고 이 참조는 목록의 내용이 변경되더라도 변경되지 않기 때문입니다.
add()
println("${entrees.add("noodles")}")
→ true가 출력되고, noodles가 entrees에 추가된다.
addAll()
val moreItems = listOf("ravioli", "lasagna", "fettuccine")
entrees.addAll(moreItems)
이렇게 별도의 list를 만들어서 한 번에 여러 요소를 추가할 수 있다.
다른 데이터 유형 추가하면 오류가 발생한다.
remove()
entrees.remove("noodles")
noodles가 제거된다.
목록에 없는 항목을 remove하려고 하면 오류는 없지만 false를 반환한다.
removeAt()
println("${entrees.removeAt(0)}")
→ entrees의 첫번째 요소가 출력되고, 삭제된다.
clear()
전체 목록 삭제
isEmpty()
비어있다면 true 리턴
while 루프를 돌며 목록의 요소를 순서대로 접근할 수 있다.
val guestsPerFamily = listOf(2, 4, 1, 3)
var totalGuests = 0
var index = 0
while (index < guestsPerFamily.size) {
totalGuests += guestsPerFamily[index]
index++
}
println("Total Guest Count: $totalGuests")
for 루프
val names = listOf("Jessica", "Henry", "Alicia", "Jose")
for (name in names) {
println(name)
}
참고: 다음은 특정 단계의 범위(매번 1씩 증분하는 대신)와 함께 사용하는 등
for
루프로 할 수 있는 다른 작업입니다.
for (item in list) print(item) // Iterate over items in a list
for (item in 'b'..'g') print(item) // Range of characters in an alphabet
for (item in 1..5) print(item) // Range of numbers
for (item in 5 downTo 1) print(item) // Going backward
for (item in 3..6 step 2) print(item) // Prints: 35
open class Item(val name: String, val price: Int)
class Noodles : Item("Noodles", 10){
override fun toString(): String{
return name
}
}
fun main() {
val noodles = Noodles()
println(noodles)
}
println(noodles)
객체 인스턴스를 출력하면 toString() 메소드가 호출된다.채소에 옵션을 추가하는 방법은 다양하다.
// 방법1
class Vegetables(val topping1: String,
val topping2: String,
val topping3: String) : Item ("Vegetables", 5){}
fun main(){
val vegetables = Vegetables("Cabbage", "Sprouts", "Onion")
}
// 방법2
class Vegetables(val toppings: List<String>) : Item("Vegetables", 5){}
fun main(){
val vegetables = Vegetables(listOf("Cabbage", "Sprouts", "Onion"))
}
가장 좋은 방법은 vararg를 사용하는 것이다.
매개변수 하나만 vararg로 표시할 수 있고 일반적으로 마지막에 쓴다.
open class Item(val name: String, val price: Int)
class Noodles : Item("Noodles", 10){
override fun toString(): String{
return name
}
}
class Vegetables(vararg val toppings: String) : Item("Vegetables", 5){
override fun toString(): String{
return name+" "+toppings.joinToString("/")
}
}
fun main() {
val noodles = Noodles()
val vegetables = Vegetables("Cabbage","Sprouts","Onion")
println(noodles)
println(vegetables)
}
/* 출력
Noodles
Vegetables Cabbage/Sprouts/Onion
*/
joinToString()
괄호안 문자로 구분자를 지정할 수 있다.
사용자가 토핑을 입력하지 않았을 때를 처리한다.
class Vegetables(vararg val toppings: String) : Item("Vegetables", 5){
override fun toString(): String{
if(toppings.isEmpty()){
return "$name Option not selected, Chef's Choice"
}else{
return name+" "+toppings.joinToString("/")
}
}
}
class Order(val orderNumber: Int){
private val itemList = mutableListOf<Item>()
fun addItem(newItem: Item){
itemList.add(newItem)
}
fun addAll(newItems: List<Item>){
itemList.addAll(newItems)
}
fun print(){
println("Order #${orderNumber}")
var total = 0
for (item in itemList) {
println("${item}: $${item.price}")
total += item.price
}
println("Total: $${total}")
}
}
Kotlin 코드를 더 간결하게 하려면 주문을 만드는 데 빌더 패턴을 사용할 수 있다. 빌더 패턴은 단계별 접근 방식으로 복잡한 객체를 빌드할 수 있는 프로그래밍의 디자인 패턴이다.
fun addItem(newItem: Item): Order {
itemList.add(newItem)
return this
}
fun addAll(newItems: List<Item>): Order {
itemList.addAll(newItems)
return this
}
main에서 아래 코드처럼 연달아 addItem()을 호출할 수 있다.
val order3 = Order(3)
.addItem(Noodles())
.addItem(Vegetables("chickpeas", "onion"))
ordersList.add(order3)
open class Item(val name: String, val price: Int)
class Noodles : Item("Noodles", 10) {
override fun toString(): String {
return name
}
}
class Vegetables(vararg val toppings: String) : Item("Vegetables", 5){
override fun toString(): String{
if(toppings.isEmpty()){
return "$name Option not selected, Chef's Choice"
}else{
return name+" "+toppings.joinToString("/")
}
}
}
class Order(val orderNumber: Int){
private val itemList = mutableListOf<Item>()
fun addItem(newItem: Item): Order{
itemList.add(newItem)
return this
}
fun addAll(newItems: List<Item>): Order{
itemList.addAll(newItems)
return this
}
fun print(){
println("Order #${orderNumber}")
var total = 0
for (item in itemList) {
println("${item}: $${item.price}")
total += item.price
}
println("Total: $${total}")
}
}
fun main() {
// 주문 목록 기록
val ordersList = mutableListOf<Order>()
val order1 = Order(1)
order1.addItem(Vegetables())
ordersList.add(order1)
val order2 = Order(2)
val items = listOf(Noodles(), Vegetables("Carrots", "Beans"))
order2.addAll(items)
ordersList.add(order2)
val order3 = Order(3).addItem(Noodles()).addItem(Vegetables("chickpeas", "onion"))
ordersList.add(order3)
// 주문 목록 출력
for (order in ordersList){
order.print()
println()
}
}