2. Зачем нужен Kotlin для
Android?
• Ограничения языка Java и его проблемы
• Нельзя добавить методы для типов,
определенных платформой либо сторонней
библиотекой (ад из “*Util” классов)
• Проблемы с null
• Отсутсвие немодифицируемых коллекций
3. Зачем нужен Kotlin для
Android?
• Android поддерживает только Java 6
• Нет Java 8 Date API
• Нет Stream API для коллекций
• Нет лямбда выражений, ссылок на методы,
замыканий
• Try-with-resource (только для Android 4.4+)
• Проверка на null повсюду
4. Зачем нужен Kotlin для
Android?
• Проблемы дизайна Android API
• Сложная иерархия
• NPE повсюду
• Сложное в использование API
18. Extension Functions
String name = null;
int nameColumnIndex =
cursor.getColumnIndexOrThrow("nameColumn");
if (!cursor.isNull(nameColumnIndex)) {
name = cursor.getString(nameColumnIndex);
}
fun Cursor.getStringOrNull(columnName: String): String? {
val nameColumnIndex = getColumnIndexOrThrow(columnName)
return if (isNull(nameColumnIndex)) null else getString(nameColumnIndex)
}
fun Cursor.getString(columnName: String) = getStringOrNull(columnName)!!
19. Extension Functions
fun Cursor.getStringOrNull(columnName: String): String? {
val nameColumnIndex = getColumnIndexOrThrow(columnName)
return if (isNull(nameColumnIndex)) null else getString(nameColumnIndex)
}
fun Cursor.getString(columnName: String) = getStringOrNull(columnName)!
val firstName = cursor!!.getString("nameColumn")
20. Function Expressions
{ it.toString() }
{ x, y -> x + y }
{ x: Int, y: Int -> x + y }
val sum: (Int, Int) -> Int = { x, y -> x + y }
val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
21. High-order Functions
public fun <T> Array<T>.filter(predicate: (T) -> Boolean): Array<T> {
return …
}
val versions = arrayOf("Gingerbread", “Honeycomb",
"Ice Cream Sandwich”,"Jelly Bean", "Lollipop")
val versionsWithBigLength = versions.filter { it.length > 10 }
23. Extension Function Expressions
• Extension Function - Функция, которая
добавляется к типу не модифицируя его.
• Function Expression - Необъявляемая функция,
которую можно использовать в качестве
выражения (например для передачи параметров
в метод)
• High-order function - Функция, которую
используют другую функцию как параметр либо
возвращает функция
29. public class Student {
private int course;
private String name;
private final Date birthday;
public Student(int course, @NotNull String name, @NotNull Date birthday) {
this.course = course;
this.name = name;
this.birthday = birthday;
}
public int getCourse() { return course; }
public void setCourse(int course) { this.course = course; }
@NotNull public String getName() { return name; }
public void setName(@NotNull String name) { this.name = name; }
@NotNull public Date getBirthday() { return birthday; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return course == student.course
&& name.equals(student.name)
&& birthday.equals(student.birthday);
}
@Override
public int hashCode() {
int result = course;
result = 31 * result + name.hashCode();
result = 31 * result + birthday.hashCode();
return result;
}
}
30. Kotlin class
class Student(var course: Int,
var name: String,
val birthday: Date) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as Student
return course == other.course
&& name == other.name
&& birthday != other.birthday
}
override fun hashCode(): Int {
var result = course
result += 31 * result + name.hashCode()
result += 31 * result + birthday.hashCode()
return result
}
}
31. Data class
data class Student(var course: Int,
var name: String,
val birthday: Date)
32. Singleton
public final class Singleton {
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
public void sayHello() {
System.out.println("Hello!");
}
private Singleton() {}
}
34. Коллекции
val names = listOf<String>(..) // Список только для чтения
names
.filter { it.startsWith("A") }
.sortedBy { it }
.map { it.toUpperCase() }
.forEach { print(it) }
35. Что еще
• Перегрузка операторов
• Type smart cast
• Range
• Расширенное API рефлексии
• Делегирование классов
• Делегирование свойств (Lazy, Observable и др.)
• Destructuring declarations
• Named arguments in function
• Tail recursive functions
• Нет проверяемых исключений