Как преобразовать java. sql .Array в List <MyCustomEnum>? - PullRequest
0 голосов
/ 17 июня 2020

У меня есть rs.getArray("lang");, то есть java.sql.Array, а поле lang - character varying[]. Я хочу преобразовать его в List<MyEnumLanguage>. В качестве примера у меня есть {fr_FR,en_US}, и я использовал следующий код для преобразования того, что моя IDE не показывала никаких ошибок

List<MyEnumLanguage> myEnumLanguageList = (List<MyEnumLanguage>) rs.getArray("lang");

, но выдает исключение org.postgresql.jdbc.PgArray cannot be cast to java.util.List.

Мой MyEnumLanguage выглядит так:

public enum MyEnumLanguage {
    en_US {
        public String getCode() { return "en_US" }
    },
    de_DE {
        public String getCode() { return "de_DE" }
    };

    private MyEnumLanguage() {
    }
}

1 Ответ

1 голос
/ 17 июня 2020

Вы не можете преобразовать массив в список. В вашей среде IDE не отображается никаких ошибок, поскольку приведение типов происходит во время выполнения.

Вместо этого вы должны использовать метод Arrays.asList(array), который возвращает список, содержащий все элементы массива. Обратите внимание: если вы хотите сопоставить элементы массива с другим типом, вы можете легко сделать это с потоками. Пример:

List<MyEnumLanguage> myEnumLanguageList = Arrays.asList(rs.getArray("lang"))
                .stream()
                .map(arrayElement -> convertToMyEnumLanguage(arrayElement))
                .collect(Collectors.toList());

где convertToMyEnumLanguage() принимает элемент вашего массива и возвращает соответствующий MyEnumLanguage.

Взгляните на этот пост: https://stackify.com/streams-guide-java-8/

ОБНОВЛЕНИЕ

Сначала я не прочитал вопрос. Вы должны сначала преобразовать свой PgArray в обычный массив java, прежде чем вы сможете использовать его в Arrays.asList ().

Это можно сделать, используя метод PgArray.getArray(), а затем преобразовать возвращаемый объект в массив типа, содержащего pgArray.

UPDATE 2

Улучшенный пример:

Прежде всего вы должны определить свое перечисление следующим образом:

public enum MyEnumLanguage {

    en_US("en_US"),
    de_DE("de_DE");

    private final String code;

    private MyEnumLanguage(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public static MyEnumLanguage getEnumByCode(String code) {
        if(code == null || code.isEmpty()) {
            return null;
        }
        for(MyEnumLanguage e : values()) {
            if(e.getCode().equals(code)) {
                return e;
            }
        }

        return null;
    }
}

Затем, чтобы сопоставить ваш pgArray со списком:

Array pgArray = rs.getArray("lang");
String[] langJavaArray = (String[]) pgArray.getArray(); //this returns an Object, so we cast it to a String array

List<MyEnumLanguage> myEnumLanguageList =
        Arrays.stream(langJavaArray)
        .map(MyEnumLanguage::getEnumByCode)
        .collect(Collectors.toList())
;

Обратите внимание что функция сопоставления не проверяет наличие нулей. Поэтому, если будут переданы неправильные коды, ваш список будет содержать нули. Если это не желаемый результат, вы должны выполнить соответствующие проверки и обработать пустые случаи в вашей функции карты.

...