Конечно, это может быть реализовано на Java.Это потребует больше усилий, хотя.Давайте рассмотрим некоторые моменты здесь.
def linearBiggestMaxSubseq[N](l: List[N])(implicit n: Numeric[N]) = {
Здесь объявляется метод, который получает List
из N
и неявный параметр Numeric[N]
.Неявные параметры обычно выводятся самим компилятором путем поиска определенных мест для объявлений, которые соответствуют обязательному параметру - почти как внедрение зависимостей.
В этом случае Numeric[N]
- это класс, который обеспечивает базовые математические операциии для которых есть экземпляры для всех числовых типов, представленных в стандартной библиотеке.Единственные вещи, которые этот метод использует из Numeric
, это plus
и zero
.
Java не имеет последствий, поэтому эквивалентный Java API будет немного более громоздким в использовании, требуя его передачидополнительный параметр.
Кроме того, я не помню ни одного эквивалента Numeric
в Java.java.lang.Number
не предоставляет методы, подобные тем, которые встречаются в BigInt
и BigDecimal
.Вы должны написать свой собственный эквивалент Numeric
, а затем написать экземпляры, чтобы охватить все числовые типы, и тогда клиентский код должен был бы передать экземпляр явно.Если в Java есть альтернатива тому, чтобы пойти на все эти усилия, я бы хотел услышать об этом.
import n._
Все, что это делает, это позволяет коду делать acc + el
вместо n.plus(acc, el)
, иzero
вместо n.zero
.Как это происходит, выходит за рамки этого вопроса.
l.scanRight((zero, Nil : List[N])) {
В Java нет эквивалента scanRight
.Вы должны превратить это в цикл while
, но это не особенно сложно сделать.scanRight
будет проходить по списку справа налево (хотя я не вижу причин, почему код делает это справа налево вместо более простого и эффективного слева направо).
По мере его обходасписок (l
), он вызовет функцию, передающую два параметра: текущий элемент и «аккумулятор».Здесь аккумулятор представляет собой Pair
, мелкий объект с парой геттеров и сеттеров для двух элементов в контейнере.В первый раз эта пара инициализируется с помощью zero
и Nil
(пустой список).
Метод, вызываемый scanRight
, должен возвращать что-то того же типа, что и аккумулятор -поэтому, передав Pair[N, List[N]]
, он должен вернуть новый Pair[N, List[N]]
.
Наконец, scanRight
создаст коллекцию с результатами метода, который он вызывает.
case (el, (acc, _)) if acc + el < zero => (zero, Nil)
case (el, (acc, ss)) => (acc + el, el :: ss)
В этом коде много совпадений, которые должны быть заменены серией операторов if
/ else
.Подробно, но не особенно хлопотно.
В данном конкретном случае (el, (acc, _))
и (ec, (acc, ss))
- это просто передаваемые параметры.Они могут воплощать тесты, но здесь они этого не делают.Единственный проводимый тест - acc + el < zero
.Если это так, он возвращает (zero, Nil)
, если нет, он возвращает (acc + el, el :: ss)
.Как я уже говорил ранее, Nil
- пустой список.Здесь el :: ss
возвращает новый список с el
, добавленным перед списком ss
.
} max Ordering.by((t: (N, List[N])) => (t._1, t._2.length)) _2
По крайней мере, числовые классы Java обычно реализуют Comparable
, даже если онине реализуйте интерфейс, обеспечивающий числовые операции.Существует множество Ordering.by
экземпляров, для каждого из которых потребуется эквивалент Comparator
или какое-то другое специальное решение.
В любом случае это вернет максимальный элемент (max
), используя Ordering
(эквивалент Comparator
), в котором сначала рассматривается значение первого элемента пары, а длина второго элемента пары (который является списком).
Наконец, _2
отбросит первый элемент пары и вернет второй элемент.
Это самый сложный из всех методов.Предыдущие являются более простыми, за счет того, что они менее универсальны и эффективны.
Итак, версия Java, конечно, будет более многословной, но, кроме проблемы Numeric
, она должна быть довольно простой.написать.Опять же, проблема Numeric
довольно критична.