Я просто не могу понять типы Groovy с мышлением Java

Я изо всех сил пытаюсь понять, почему код, который работает на Java, не работает в groovy. Например:

Я обнаружил, что если я использую Tuple2.of(..., я получу ошибку компиляции, но new Tuple2(.. работает. Почему?

    static Stream<Tuple2<LocalDate, Double>> forecastEachMonth(Tuple2<LocalDate, Double> openingBalance, Double rate){

        Stream<Tuple2<LocalDate, Double>> stream = Stream.iterate(
                openingBalance,
                {

                    LocalDate current = it.first
                    LocalDate nextDate = it.first.plusMonths(1)

                    int days = Days.daysBetween(current, nextDate).days
                    double years = days / 365.0
                    double interest = it.second * rate * years
                    double nextBalance = it.second + interest

                    // return Tuple2.of(nextDate, nextBalance) // exception after 2 iterations, Have no idea why.
                    return new Tuple2(nextDate, nextBalance)
                }
        )
        return stream
    }

Вы можете проверить это:

        Stream<Tuple2<LocalDate,Double>> test = forecastEachMonth(
                        LocalDate.now(),
                        200000.0d,
                0.05d
        )
        println test.limit(200).collect(Collectors.toList())

Выдает ошибку:

Expected earlier checking to detect generics parameter arity mismatch
Expected: groovy.lang.Tuple<E> 
Supplied: groovy.lang.Tuple<org.joda.time.LocalDate,java.lang.Double> 

Но Intellij знает правильный тип, когда я навожу курсор на локальную переменную.

Я также преобразовал проект в Java, и он просто работает. Что серьезно мешает моему опыту кодирования в Groovy, так как я теряю кучу времени на код, который работает на Java, но не на Groovy. (Хотя в Java нет кортежа, я просто использовал другую библиотеку с коллекцией Pair). Но я просто не могу понять, почему Groovy вдруг не знает тип данной переменной, возвращается к Object, а затем просто выдает исключение, как это желательно?

Какая версия groovy+java?

daggett 06.12.2022 11:48

«Я обнаружил, что если я использую Tuple2.of(..., я получу ошибку компиляции» — было бы хорошо знать, что такое ошибка компиляции и откуда вы ожидаете, что этот метод будет исходить.

Jeff Scott Brown 06.12.2022 16:38

Пожалуйста, смотрите обновление, если необходимо, обратите внимание, хотя версия Java не имеет Tuple, но проблема больше в том, что я не ожидаю, что семантика, подобная этой, полностью разрушит мой код, а затем будет стоить мне кучу времени на отслеживание проблемы. Я хотел бы понять, почему Groovy делает то, что делает.

Derrops 07.12.2022 05:20

Где вы нашли метод Type2.of? В groovy doc такого метода нет...

daggett 07.12.2022 10:54
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
4
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

не могу понять вашу "джавскую" боль.

следующий пример кода хорошо работает даже со статической компиляцией:

@groovy.transform.CompileStatic
def f(){
  Tuple2<Date, Double> a = new Tuple2(new Date(), 1)
  Tuple2<Date, Double> b = new Tuple2(new Date(), 2)

  List<Tuple2<Date, Double>> list = [a,b]
  List<Tuple2<Date, Double>> result = list.takeWhile{Tuple2<Date, Double> e-> e.getV2()<2}

  assert result instanceof List
  assert result.size()==1
  assert result[0].getV2()<2
  assert result[0] instanceof Tuple2
}

f()

ваши вопросы:

Я обнаружил, что если я использую Tuple2.of(..., я получу ошибку компиляции, но new Tuple2(.. работает. Почему?

такого метода нет Tuple2.of(... в классе Tuple2

почему Groovy внезапно не знает тип данной переменной, возвращается к Object, а затем просто выдает исключение, как это желательно?

я использовал ваш код с минимальными изменениями, чтобы сделать его работоспособным, и он работает без ошибок:

import java.time.*
import java.util.stream.*

static Stream<Tuple2<LocalDate, Double>> forecastEachMonth(Tuple2<LocalDate, Double> openingBalance, Double rate){

    Stream<Tuple2<LocalDate, Double>> stream = Stream.iterate(
            openingBalance,
            {

                LocalDate current = it.first
                LocalDate nextDate = it.first.plusMonths(1)

                int days = nextDate - current
                double years = days / 365.0
                double interest = it.second * rate * years
                double nextBalance = it.second + interest

                return new Tuple2(nextDate, nextBalance)
            }
    )
    return stream
}


Stream<Tuple2<LocalDate,Double>> test = forecastEachMonth(
    new Tuple2(LocalDate.now(),200000.0d),
    0.05d
)
println test.limit(200).collect(Collectors.toList())

Я обновил, теперь вы увидите, что если вы запустите мой метод, вы обнаружите, что it переходит от кортежа к объекту. Хотелось бы знать, почему. Обратите внимание, что здесь я использую Jodatime.

Derrops 07.12.2022 05:17

Метод создает поток будущей стоимости банковских счетов каждый месяц с учетом процентной ставки с ежемесячным начислением процентов, надеюсь, имеет смысл.

Derrops 07.12.2022 05:18

попробовал ваш код - работает хорошо

daggett 07.12.2022 14:30

Вам нужно изменить возврат на: return Tuple2.of(nextDate, nextBalance) Вы обнаружите ошибки после второй итерации.

Derrops 10.12.2022 11:33

у меня ошибка на первой итерации: groovy.lang.MissingMethodException: No signature of method: static groovy.lang.Tuple2.of() is applicable for argument types: (java.time.LocalDate, Double) values: [2023-01-10, 200849.315068]. какое сообщение об ошибке вы видите? опять же - функции Tuple2.of() нет, однако ее можно определить в какой-нибудь библиотеке вот так: Tuple2.metaClass.static.of = {a,b-> new Tuple2(a,b)}.

daggett 10.12.2022 14:53

Хорошо, @daggett, я знаю, в чем была проблема. Tuple расширяет AbstractList, реализует List, в котором есть метод of. Таким образом, у Tuple также есть этот метод. Это подпись <E> List<E> of(E e1, E e2), поэтому, если ваши аргументы разных типов, вы получите ошибку компиляции, у меня не было @TypeChecked. Хорошо, чтобы отследить проблему, но я в конечном итоге отказался от groovym, у меня действительно нет времени отслеживать этот материал, когда это происходит.

Derrops 11.12.2022 10:58

Вот почему я спросил вас о версии java/groovy. Но ты проигнорил)

daggett 11.12.2022 11:57

Прости Даггет! Я приму ваш ответ и проголосую за вас, за усилия, продолжайте в том же духе, ха-ха. Но да, я действительно не получил прироста производительности с Groovy, возможно, попробую еще раз в будущем, но на данный момент без IDE я борюсь.

Derrops 12.12.2022 10:57

Другие вопросы по теме