Integer a = 100;
a = null;
//int 는 primitive 자료형으로 null로 초기화 할 수 없지만
//Integer 는 Wrapper 클래스(객체) 이르모 null로 초기화 가능
///중략///
a.sum(); //NullPointException 발생 가능
if(a != null){ // null safe 한 코드 구성
a.sum();
}
//혹은 try catch 문으로 예외 처리 해야
val b : Int? = 100 //null 허용하는 Int형
val c : Int = 100 //null 허용하지 않는 Int형
///중략///
b?.sum() //b = null인 경우 실행 X
c.sum() //애초에 nullsafe
코틀린 표준 라이브러리에 포함된 함수
객체의 컨텍스트 내에서 코드 블럭을 실행하기 위한 목적만을 가진 여러가지 함수 제공
-> 이런 함수들을 람다식으로 호출할 때, 이는 임시로 범위(scope)를 형성
-> 이 범위 내에서는 객체의 이름이 없어도 객체에 접근할 수 있다
this
this 키워드로 람다 수신자로서의 컨텍스트 객체를 참조합니다
대부분의 경우, 수신 객체의 멤버에 접근할 때 this를 생략 가능하지만
it
컨텍스트 객체를 람다 인자(argument)로 가지는 경우, 인자의 이름이 정해지지 않았다면 해당 객체는 암시적인 기본 이름인 it으로 접근할 수 있다
fun main(args: Array<String>){
val sum: Int.(num : Int) -> Int = {this + it}
print(1.sum(2))
// 출력 : 3
}
Person person = new Person();
person.firstName = "First";
person.lasttName = "Last";
val person = Person.apply(){
this.firstName = "First"
this.lastName = "Last"
}
int value = Random.nextInt(100);
System.out.print(value);
Random 클래스는 난수를 생성하는 클래스로 객체를 생성하여 사용한다
int nextInt(): int형 난수 반환
int nextInt(int n): 0~n 미만의 정수형 난수 반환
Random.nextInt(100).also{
//인자의 이름 정해진 경우
value -> print("getRandomInt() generated value $value")
}
Random.nextInt(100).also{
//인자의 이름 정해지지 않은 경우
print("getRandomInt() generated value $it")
}
Integer number = null;
String sumNumberStr = null;
if(number != null){
sumNumberStr = " "+ sum(10, number);
}
Integer number = null;
String sumNumberStr = null;
if(number != null){
sumNumberStr = ""+ sum(10, number);
}else{
sumNumberStr = "";
}
val = number : Int?
val sumNumberStr = number?.let{
"${sum(10, it)}"
}
val = number : Int?
val sumNumberStr = number?.let{
"${sum(10, it)}"
}.orEmpty() //null인 String을 null이 아닌 ""로 초기화하는 String 멤버 함수
Person person = new Person();
person.work();
person.sleep();
System.out.println(person.age);
val person = Person()
with(person){
this.work()
this.sleep()
print(this.age)
}
service.port = 8080;
Result result = service.query();
val result = service.run{
this.port = 8080
query()
}
public class JavaObject{
private String s;
//생성자
JavaObject(String s){
this.s = s;
}
//getter
public String getS(){
return s;
}
//setter
public void setS(String s){
this.s = s;
}
//copy
//toString
//hashCode
//equal 등등 생략
}
data class JavaObject(val s : String)
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onCLick(View view){
...
}
})
button.setOnClickListener{
v-> ...
}
nullsafe한 코드를 사용하기 위해 non-null Type으로 변수 선언할 때
초기값이 없는 변수는 어떻게 선언해야할까?
lateinit: 변수의 값 초기화를 뒤로 미룸
var nullableNumber: Int? = null
lateinit var lateinitNumber : Int
//추후 초기화하는 코드
lateinitNumber = 10
//사용할 때
nullableNumber?.add()
lateinitNumber.add() //초기화를 하지 않으면 에러 발생
val lazyNumber : Int by lazy{
100
}
//사용하기 전까지는 lazyNumber라는 변수에 100이 할당되지 않는다
lazyNumber.add()
//사용할 때 100이 할당됨
코틀린 컴파일
https://kotlinlang.org/
자바 자료형 (primitive vs Wrapper)
https://includestdio.tistory.com/1
람다(Lambda)란?
익명 클래스가 이름없이 정의되어 사용될 수 있듯이 함수도 이름없이 사용되는 형태를 말한다 (Anonymous Function)(People p1, People p2) -> p1.getAge().compareTo(p2.getAge());
- Parameter list: (people p1, people p2)
- 화살표: 람다의 파라미터와 바디를 구분
- Lambda body: 람다의 반환값에 해당하는 표현식
(parameters) -> expression (parameters) -> { statements; }
동작 파라미터화 (Behavior parameterization)
람다를 이용하면 함수의 인자로 어떤 동작을 하는 함수를 받을 수 있다
이 동작은 함수를 호출하기 전까지는 아직 정해지지 않은 상태이며, 함수를 호출할 때 전달해 준 동작을 이용해서 함수 내부가 구현된다
java.util.function package에서 가장 많이 사용하는 형태에 대한 interface를 framework단에서 제공한다 (Java8에서 추가된 package)
- Predicate
Lamda signature: (T) -> boolean
Abstract method: boolean test(T t);- Consumer
Lamda signature: (T) -> void
Abstract method: void accept(T t);- Function<T,R>
Lamda signature: (T) -> R
Abstract method: R apply(T t);- Supplier
Lamda signature: () -> T
Abstract method: T get();- UnaryOperator
Lamda signature: (T) -> T
Abstract method: T apply(T t);
...은 매개변수를 받긴하지만 몇개인지 모른다라는 의미
즉, 몇 개의 매개변수를 넣어도 다 받을 수 있다
자바 람다식과 유사하다
fun main(args: Array) { val sum = { x: Int, y: Int -> println("Computing the sum of $x and $y...") x + y } println(sum(1, 2)) }
- 중괄호로 감싼다 { .. }
- 인자와 본문은 ->로 구분한다
- 인자는 ()로 감싸지 않는다
- 인자는 형식추론이 가능하므로 타입을 생략할 수 있다
- 변수에 람다식을 담는경우에는 인자의 타입을 생략할 수 없다
코드의 간결성을 위한 규칙 존재
- 함수의 맨 마지막 인자가 람다라면 () 안에서 빼내서 밖에 람다를 표현할 수 있다
- 인자가 하나라면 그 인자는 람다식 내부에서 it으로 받을 수 있다
- 인자가 하나이면서 그 인자가 람다타입 이라면 ()를 생략할 수 있다
people.maxBy ({p: Person -> p.age}) people.maxBy () {p: Person -> p.age} people.maxBy {p: Person -> p.age} people.maxBy {it.age}