Знак доллара при вызове функции в Java с использованием Spark SQL

У меня есть следующий код (Java с Spark SQL) -

    import static org.apache.spark.sql.functions.col;
    ...

    System.out.println("=== Filtering records with average age more than 20 ===");
    Dataset<Row> result = df.filter(col("age").$less(20));

Я никогда не встречал вызов функции в Java, который начинается с доллара. Попробовал поискать его в Google, но мое лучшее предположение пока что то, что это результат Java, вызывающего код Scala (но в исходном коде Scala нет функции $ less)

Не могли бы вы дать убедительное объяснение этому?

Ответы

Ответ 1

потому что каждый допустимый символ в синтаксисе метода Scalas имеет соответствующий перевод формы "$ trans". так что для вашего вопроса есть метод в Scala, который называется < и соответствующий метод в Java будет $less

Другие операторы будут скомпилированы в:

╔═══════════════════╦══════════════╗
║ Scala Operator    ║ Compiles To  ║
╠═══════════════════╬══════════════╣
║=                  ║$eq           ║
║>                  ║$greater      ║
║<                  ║$less         ║
║+                  ║$plus         ║
║-                  ║$minus        ║
║*                  ║$times        ║
║/                  ║$div          ║
║!                  ║$bang         ║
║@                  ║$at           ║
║#                  ║$hash         ║
║%                  ║$percent      ║
║^                  ║$up           ║
║&                  ║$amp          ║
║~                  ║$tilde        ║
║?                  ║$qmark        ║
║║                  ║$bar          ║
║\                  ║$bslash       ║
║:                  ║$colon        ║
╚═══════════════════╩══════════════╝

Более подробную информацию об этом можно найти здесь: http://www.codecommit.com/blog/java/interop-between-java-and-scala

Ответ 2

Ответ можно найти здесь - http://www.codecommit.com/blog/java/interop-between-java-and-scala

Операторы Методы

Одним из наиболее очевидных различий между Java и Scala является то, что Scala поддерживает перегрузку операторов. Фактически, Scala поддерживает вариант перегрузки операторов, который намного сильнее, чем что-либо, предложенное C++, С# или даже Ruby. За очень немногими исключениями, любой символ может использоваться для определения пользовательского оператора. Это обеспечивает огромную гибкость в DSL и даже в среднем ежедневном API (например, List и Map).

Очевидно, что эта особенная языковая особенность не собирается переводить на Java так хорошо. Java не поддерживает перегрузки операторов любого вида, тем более сверхмощной формы, определенной в Scala. Таким образом, операторы Scala должны быть скомпилированы в совершенно несимвольную форму на уровне байт-кода, иначе взаимодействие Java будет непоправимо нарушено, а сама JVM не сможет усвоить результат.

Хорошим отправным пунктом для принятия решения о таком переводе является способ объявления операторов в Scala: как методы. Каждый оператор Scala (включая унарные операторы, такие как !) Определяется как метод внутри класса:

abstract class List[+A] {
  def ::[B >: A](e: B) = ...

  def +[B >: A](e: B) = ...
}

Поскольку классы Scala становятся классами Java, а методы Scala становятся методами Java, наиболее очевидным переводом было бы использование каждого метода оператора и создание соответствующего метода Java с сильно переведенным именем. На самом деле, это именно то, что делает Scala. Приведенный выше класс скомпилируется в эквивалент этого кода Java:

public abstract class List<A> {
  public <B super A> List<B> $colon$colon(B e) { ... }

  public <B super A> List<B> $plus(B e) { ... }
}

Каждый допустимый символ в синтаксисе метода Scalas имеет соответствующий перевод вида " $trans ". Список поддерживаемых переводов - это одна из тех частей документации, которую вы ожидаете найти на веб-сайте Scala. Однако, увы, его нет. Ниже приводится таблица всех переводов, о которых я знаю:

┌────────────────┬─────────────┐
│ Scala Operator │ Compiles To │
├────────────────┼─────────────┤
│  =             │  $eq        │
├────────────────┼─────────────┤
│  >             │  $greater   │
├────────────────┼─────────────┤
│  <             │  $less      │
├────────────────┼─────────────┤
│  +             │  $plus      │
├────────────────┼─────────────┤
│  -             │  $minus     │
├────────────────┼─────────────┤
│  *             │  $times     │
├────────────────┼─────────────┤
│  /             │  div        │
├────────────────┼─────────────┤
│  !             │  $bang      │
├────────────────┼─────────────┤
│  @             │  $at        │
├────────────────┼─────────────┤
│  #             │  $hash      │
├────────────────┼─────────────┤
│  %             │  $percent   │
├────────────────┼─────────────┤
│  ^             │  $up        │
├────────────────┼─────────────┤
│  &             │  $amp       │
├────────────────┼─────────────┤
│  ~             │  $tilde     │
├────────────────┼─────────────┤
│  ?             │  $qmark     │
├────────────────┼─────────────┤
│  |             │  $bar       │
├────────────────┼─────────────┤
│  \             │  $bslash    │
├────────────────┼─────────────┤
│  :             │  $colon     │
└────────────────┴─────────────┘

Используя эту таблицу, вы сможете получить "настоящее имя" любого оператора Scala, что позволяет использовать его изнутри Java. Конечно, идея будет заключаться в том, что Java действительно поддерживает перегрузку операторов и может напрямую использовать операторы Scalas, но я почему-то сомневаюсь, что это произойдет в ближайшее время.

**** Этот ответ был опубликован кем-то, но по какой-то причине удален (очень хотелось бы, если бы его владелец мог опубликовать его повторно)