Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Давайте начнем с некоторых фиктивных данных:
val transactions = Seq((1, 2), (1, 4), (2, 3)).toDF("user_id", "category_id")
val transactions_with_counts = transactions
.groupBy($"user_id", $"category_id")
.count
transactions_with_counts.printSchema
// root
// |-- user_id: integer (nullable = false)
// |-- category_id: integer (nullable = false)
// |-- count: long (nullable = false)
Существует несколько способов получить доступ к значениям Row
и сохранить ожидаемые типы:
import org.apache.spark.sql.Row
transactions_with_counts.map{
case Row(user_id: Int, category_id: Int, rating: Long) =>
Rating(user_id, category_id, rating)
}
get*
, такие как getInt
, getLong
: transactions_with_counts.map(
r => Rating(r.getInt(0), r.getInt(1), r.getLong(2))
)
getAs
метод, который может использовать как имена, так и индексы: transactions_with_counts.map(r => Rating(
r.getAs[Int]("user_id"), r.getAs[Int]("category_id"), r.getAs[Long](2)
))
Это может быть используется для правильного извлечения определенных пользователем типов, включая mllib.linalg.Vector
. Очевидно, что для доступа по имени требуется схема. Dataset
(Spark 1.6+ / 2.0+): transactions_with_counts.as[(Int, Int, Long)]
Используя Datasets, вы можете определить рейтинги следующим образом:
case class Rating(user_id: Int, category_id:Int, count:Long)
Класс Rating здесь имеет имя столбца «count» вместо «rating», как предлагалось в качестве нулевого323. Таким образом, рейтинговая переменная присваивается следующим образом:
val transactions_with_counts = transactions.groupBy($"user_id", $"category_id").count
val rating = transactions_with_counts.as[Rating]
Таким образом, вы не будете запускать ошибки времени выполнения в Spark, потому что имя столбца вашего рейтинга совпадает с именем столбца «count», сгенерированным Spark во время выполнения.
getAs[_]
иget*
должны быть похожими, но больны в использовании. – zero323 11 August 2017 в 11:33DataFrame
, имеющий нулевых столбцов , подобных этомуcase Row(usrId: Int, usrName: String, null, usrMobile: Int) => ...
иcase Row(usrId: Int, usrName: String, usrAge: Int, null) => ...
, что приводит к длинным case-выражениям i> (и у меня есть несколько случаев). Есть ли более чистый способ (более сжатый, менее шаблонный / повторяющийся материал), чтобы сделать это? Пожалуйста, ответьте на пример. – y2k-shubham 22 January 2018 в 08:53