Как использовать MapElements и KV вместе в Apache Beam? - PullRequest
0 голосов
/ 10 ноября 2018

Я хотел сделать что-то вроде:

PCollection<String> a = whatever;
PCollection<KV<String, User>> b = a.apply(
        MapElements.into(TypeDescriptor.of(KV<String, User>.class))
        .via(s -> KV.of(s, new User(s))));

Где пользователь - это пользовательский тип данных с кодировщиком Arvo и конструктором, который учитывает строку.

Однако я получаю следующую ошибку:

Невозможно выбрать из параметризованного типа

Вместо этого я попытался изменить его на TypeDescriptor.of(KV.class), но затем я получил:

несовместимые типы; Обязательно PCollection> но 'apply' было выведено для OutputT: не существует экземпляра (ов) переменной типа (типов), так что PCollection соответствует PCollection>

Итак, как мне предположить использовать KV с MapElements?

Я знаю, что то, что я хочу сделать, выполнимо, используя ParDo, где я мог бы явно указать, как сделать стирание типа, объявив new DoFn<String, KV<String, User>>, но ParDo не поддерживает лямбда-функцию. Поскольку мы используем Java 8, это выглядит менее элегантно ....

1 Ответ

0 голосов
/ 05 июня 2019

Из-за стирания типа в Java во время компиляции KV<String, User>.class преобразуется в KV.class, а во время выполнения KV.class недостаточно информации для вывода кодера, поскольку переменные типа были стерты.

Чтобы обойти это ограничение, вам нужно использовать механизм, который сохраняет информацию о типе после компиляции. Например, вы можете использовать:

TypeDescriptors.kvs(TypeDescriptors.strings(), TypeDescriptor.of(User.class))

, что аналогично предоставлению собственного анонимного класса:

new TypeDescriptor<KV<String, User>> {}

Предоставление анонимных классов с привязкой к переменным типа является одним из способов обойти стирание типов в Java в настоящее время.

...