Sobes.tech
Senior

Java 1.5-წინა დროის თანამედროვე enum-ის (enum) მსგავსი საკუთარი ტიპის განხორციელება. უნდა შეესაბამებოდეს თანამედროვე Java-enum-ის კონტრაქტს: • ადვილი წვდომა ნებისმიერ enum მნიშვნელობაზე • უსაფრთხო შედარება მნიშვნელობებს რეფერენციის მიხედვით (==) • თითოეულ მნიშვნელობას აქვს სტრინგის სახელი, რომელიც ემთხვევა მნიშვნელობის სახელწოდებას • თითოეულ მნიშვნელობას აქვს მთელი რიცხვის `ordinal` იდენტიფიკატორი, რომელიც შეიცავს მნიშვნელობის ნომერს მისი გამოქვეყნების წესში enum-ში • შესაძლებელია მიიღოთ ყველა მნიშვნელობის სია • შესაძლებელია მიიღოთ მნიშვნელობა მისი `ordinal`-ის მიხედვით • შესაძლებელია მიიღოთ მნიშვნელობა მისი სახელის მიხედვით მაგალითად, შეგიძლიათ აიღოთ ვალუტების სია. მნიშვნელოვანია, რომ სია პოტენციურად გაფართოებადი იყოს, რადგან კოდის ხარისხი განსაზღვრავს, რამდენად უპრობლემოდ იქნება მომავალში მნიშვნელობების დამატება enum-ში. class Currency { // TODO } --- მიწოდებულია user_orders ცხრილი |ts|user_id|order_value| მიუხედავად იმისა, რომ თითოეული მომხმარებლისთვის, დააბრუნეთ მისი პირველი შეძენის ჯამი.

sobes.tech AI

პასუხი AI-სგან

До появления enum в Java 1.5 можно было реализовать перечислимый тип с помощью класса и статических констант. Вот пример реализации класса Currency, который удовлетворяет перечисленным требованиям:

import java.util.*;

public class Currency {
    private static final List<Currency> VALUES = new ArrayList<>();
    private final String name;
    private final int ordinal;

    // Приватный конструктор
    private Currency(String name) {
        this.name = name;
        this.ordinal = VALUES.size();
        VALUES.add(this);
    }

    // Определение значений
    public static final Currency USD = new Currency("USD");
    public static final Currency EUR = new Currency("EUR");
    public static final Currency GBP = new Currency("GBP");

    // Получить имя
    public String name() {
        return name;
    }

    // Получить ordinal
    public int ordinal() {
        return ordinal;
    }

    // Получить все значения
    public static Currency[] values() {
        return VALUES.toArray(new Currency[0]);
    }

    // Получить по имени
    public static Currency valueOf(String name) {
        for (Currency c : VALUES) {
            if (c.name.equals(name)) {
                return c;
            }
        }
        throw new IllegalArgumentException("No enum constant Currency." + name);
    }

    @Override
    public String toString() {
        return name;
    }
}

Такой класс:

  • Хранит все значения в списке VALUES.
  • Присваивает каждому значению уникальный ordinal по порядку создания.
  • Позволяет получить все значения через метод values().
  • Позволяет получить значение по имени через valueOf(String).
  • Сравнение по ссылке работает, так как все значения — это статические константы.

Для SQL-запроса, чтобы для каждого пользователя получить сумму первой покупки из таблицы user_orders:

SELECT user_id, SUM(order_value) AS first_order_sum
FROM user_orders uo1
WHERE ts = (
    SELECT MIN(ts) FROM user_orders uo2 WHERE uo2.user_id = uo1.user_id
)
GROUP BY user_id;

Этот запрос находит минимальную дату покупки для каждого пользователя и суммирует значения заказов, сделанных в этот момент (если несколько заказов в одно время).