Apache Spark, имеющий набор данных параметризованного / универсального класса в Java

#java #apache-spark #generics #parameterized-class

#java #apache-spark #общие #параметризованный класс

Вопрос:

Я всегда сомневался, возможно ли наличие набора данных параметризованного / универсального класса в Java. Чтобы было более понятно, чего я хочу достичь, это что-то вроде этого:

 Dataset<MyClass<Integer>> myClassInteger;
Dataset<MyClass<String>> myClassString;
  

Пожалуйста, дайте мне знать, если это возможно. Если бы вы также могли показать мне, как этого добиться, я был бы очень признателен. Спасибо!

Ответ №1:

Извините, этот вопрос устарел, но я хотел бы записать некоторые заметки, поскольку я смог работать с универсальными / параметризованными классами для наборов данных в Java, создав универсальный класс, который принимал параметр типа, а затем помещал методы внутри этого параметризованного класса. Т.е., class MyClassProcessor<T1> где T1 может быть Integer или String .

К сожалению, в этом случае вы не сможете воспользоваться всеми преимуществами универсальных типов, и вам придется выполнить некоторые обходные пути:

  • Мне пришлось использовать Encoders.kryo() , иначе универсальные типы стали Object с некоторыми операциями и не могли быть правильно приведены к универсальному типу.
    • Это приводит к некоторым другим неприятностям, т. Е. Не может присоединиться. Мне пришлось использовать трюки, такие как использование кортежей, чтобы разрешить некоторые операции объединения.
  • Я не пробовал читать универсальные типы, мои параметризованные классы были введены позже с помощью map . Например, я прочитал TypeA и позже работал с Dataset<MyClass>.
  • Я смог использовать более сложные пользовательские типы в общих чертах, а не только целое число, строку и т.д…
  • Были некоторые раздражающие детали, такие как необходимость передавать литералы класса, т. Е. TypeA.class И использование необработанных типов для определенных функций карты и т.д…

Ответ №2:

Да, у вас может быть набор данных вашего собственного класса. Это выглядело бы как Dataset<MyOwnClass>

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

 import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Encoder;
import org.apache.spark.sql.Encoders;
import org.apache.spark.sql.SparkSession;

import java.io.Serializable;

public class FileDataset {
    public static class Employee implements Serializable {
        public int key;
        public int value;
    }

    public static void main(String[] args) {
        // configure spark
        SparkSession spark = SparkSession
                .builder()
                .appName("Reading JSON File into DataSet")
                .master("local[2]")
                .getOrCreate();

        final Encoder<Employee> employeeEncoder = Encoders.bean(Employee.class);

        final String jsonPath = "/Users/ajaychoudhary/Documents/student.txt";

        // read JSON file to Dataset
        Dataset<Employee> ds = spark.read()
                .json(jsonPath)
                .as(employeeEncoder);
        ds.show();
    }
}
  

Содержимое моего student.txt файла

 { "key": 1, "value": 2 }
{ "key": 3, "value": 4 }
{ "key": 5, "value": 6 }
  

Он выдает следующий вывод на консоль:

  --- ----- 
|key|value|
 --- ----- 
|  1|    2|
|  3|    4|
|  5|    6|
 --- ----- 
  

Я надеюсь, что это дает вам первоначальное представление о том, как вы можете иметь набор данных вашего собственного пользовательского класса.

Комментарии:

1. Я знаю, что у меня может быть набор данных моего собственного класса. Вопрос был в том, можете ли вы иметь набор данных параметризованного / универсального класса. Например, предположим, что ваш класс employee имеет поле «IDNumber», которое может быть любого типа String of Long. В этом случае вы можете параметризовать класс следующим образом: class Employee<T> {}. Впоследствии вы можете объявлять объекты в зависимости от ваших потребностей. Например. Employee<Long> employee1 = новый сотрудник <> (1,2,3L); Employee<String> employee2 = новый сотрудник<> (1,2, «A1B2C3»);. Пожалуйста, скажите мне, ясно ли я выразился.

2. Это требование не очень понятно из вопроса. Или я не получил его таким образом. Пожалуйста, отредактируйте свой вопрос с примером. Кто-нибудь может помочь с этим. Я не знаю, как это сделать.