Работа с данным - Kotlin vs Java

March 30, 2024

Этот пост - краткий ответ на комментарий к посту в канале и здесь я привожу несколько примеров того, что назвал "утилит манипуляции данными", но это далеко не исчерпвывающий список.

Поехали.

Java 21 + DOP-стиль

Упражнение №1 - достаём значение по цепочке нуллабельных объектов

KotlinJava
1
2
3
4
5
6
7
data class MultiLangValue(val ru: String?, val en: String?)

data class ValueHolder(val value: MultiLangValue?)

fun getRuValue(valueHolder: ValueHolder?): String {
    return valueHolder?.value?.ru ?: ""
}
1
2
3
4
5
6
7
8
9
public record MultiLangValue(String ru, String en) {
}

public record ValueHolder(@Nullable MultiLangValue value) {
}

public @NotNull String getRuValue(@Nullable ValueHolder valueHolder) {
    return valueHolder != null ? valueHolder.value() != null ? valueHolder.value().ru() : "" : "";
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public record MultiLangValue(String ru, String en) {
}

public record ValueHolder(@Nullable MultiLangValue value) {
}

public @NotNull String getRuValue(@Nullable ValueHolder valueHolder) {
    return Optional.ofNullable(valueHolder)
        .flatMap(holder -> Optional.ofNullable(holder.value()))
        .map(MultiLangValue::ru)
        .orElse("");
}

Упражнение №2 - Группировка элементов списка по ключу

KotlinJava
1
2
3
fun groupBy(values: List<ValueHolder>): Map<String, List<ValueHolder>> {
    return values.groupBy { it.value?.ru ?: "" }
}
1
2
3
4
public Map<String, List<ValueHolder>> groupBy(List<ValueHolder> values) {
    return values.stream()
            .collect(groupingBy(v -> ofNullable(v.value).map(MultiLangValue::ru).orElse("")));
}

Упражнение №3 - упражнения со списками

KotlinJava
2024 03 31 14 10 15
2024 03 31 14 11 32
2024 03 31 14 12 25

И так практически по всей стандартной библиотеки.

Упражнение №4 - приведение к подтипу и получение значения

KotlinJava
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
interface Value {
    val value: String
}

data class SingleValue(override val value: String) : Value

class MultiLangValue3(val ru: String, val en: String) : Value {
    override val value: String = ru
}

fun getIfInstanceOf(value: Value) =
    (value as? MultiLangValue3)?.en
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface Value {
    String getValue();
}

record SingleValue(String value) implements Value {
    @Override
    public String getValue() {
        return null;
    }
}

public record MultiLangValue3(String ru, String en) implements Value{
    @Override
    public String getValue() {
        return ru;
    }
}

public static String getIfInstanceOf(Value value) {
    if (!(value instanceof MultiLangValue3)) {
        return null;
    }
    return value.en;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface Value {
    String getValue();
}

record SingleValue(String value) implements Value {
    @Override
    public String getValue() {
        return null;
    }
}

public record MultiLangValue3(String ru, String en) implements Value {
    @Override
    public String getValue() {
        return ru;
    }
}

public static String getIfInstanceOfSwitch(Value value) {
    return switch (value) {
        case MultiLangValue(var _, var en) -> en;
        default -> null;
    };
}

Упражнение №5 - маппинг списков

Маппинг списков в Java уже почти догнал Kotlin, но всё равно чуть более многословный.

KotlinJava
1
2
3
4
fun mapList() {
    val values = listOf(MultiLangValue(null, null))
    val mappedValues = values.map { it.ru }
}
1
2
3
4
public void mapList() {
    var values = List.of(new MultiLangValue(null, null));
    var mappedValues = values.stream().map(MultiLangValue::ru).toList();
}
1
2
3
4
public void mapList() {
    var values = List.of(new MultiLangValue(null, null));
    var mappedValues = values.stream().map(it -> it.ru()).toList();
}

Java 8+классический* Java-стиль

* классический в моём опыте

Создание объектов

KotlinJava
1
2
3
4
5
6
7
data class MultiLangValue(val ru: String?, val en: String?)

data class ValueHolder(val value: MultiLangValue?)

fun create(): List<ValueHolder> = listOf(
    ValueHolder(MultiLangValue("ru", "en"))
)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class MultiLangValue2 {

    private String ru;
    private String en;

    public String getRu() {
        return ru;
    }

    public void setRu(String ru) {
        this.ru = ru;
    }

    public String getEn() {
        return en;
    }

    public void setEn(String en) {
        this.en = en;
    }

}

public class ValueHolder2 {

    private MultiLangValue2 value;

    public MultiLangValue2 getValue() {
        return value;
    }

    public void setValue(MultiLangValue2 value) {
        this.value = value;
    }

}

public List<ValueHolder2> instantiate() {
    List<ValueHolder2> result = new ArrayList<>();

    ValueHolder2 valueHolder = new ValueHolder2();

    MultiLangValue2 value = new MultiLangValue2();
    value.setRu("ru");
    value.setEn("en");

    valueHolder.setValue(value);

    result.add(valueHolder);

    return result;
}