0

I am new to Scala and trying to explore how I can use Java functionalities with Scala.

I am having stream of LocalDate which is a Java class and I am trying to find maximum date out of my list.

var processedResult : Stream[LocalDate] =List(javaList)
      .toStream
      .map { s => {
        //some processing
        LocalDate.parse(str, formatter)
        }
      }

I know we can do easily by using .compare() and .compareTo() in Java but I am not sure how do I use the same thing over here.

Also, I have no idea how Ordering works in Scala when it comes to sorting.

Can anyone suggest how can get this done?

2 Answers2

2

First of all, a lot of minor details that I will point out since it seems you are pretty new to the language and I expect those to help you with your learning path.

First, avoid var at all costs, especially when learning.
While mutability has its place and is not always wrong, forcing you to avoid it while learning will help you. Particularly, avoid it when it doesn't provide any value; like in this case.

Second, this List(javaList) doesn't do what you think it does. It creates a single element Scala List whose unique element is a Java List. What you probably want is to transform that Java List into a Scala one, for that you can use the CollectionConverters.

import scala.jdk.CollectionConverters._ // This works if you are in 2.13
// if you are in 2.12 or lower use: import scala.collection.JavaConverters._

val scalaList = javaList.asScala.toList

Third, not sure why you want to use a Scala Stream, a Stream is for infinite or very large collections where you want all the transformations to be made lazily and only produce elements as they are consumed (also, btw, it was deprecated in 2.13 in favour of LazyList).
Maybe, you are confused because in Java you need a "Stream" to apply functional operations like map? If so, note that in Scala all collections provide the same rich API.

Fourth, Ordering is a Typeclass which is a functional pattern for Polymorphism. On its own, this is a very broad question so I won't answer it here, but I hope the two links provide insight.
The TL;DR; is simple, it is just that an Ordering for a type T knows how to order (sort) elements of type T. Thus operations like max will work for any collection of any type if, and only if, the compiler can prove the existence of an Ordering for that type if it can then it will pass such value implicitly to the method call for you; again the implicits topic is very broad and deserves its own question.


Now for your particular question, you can just call max or maxOption in the List or Stream and that is all.
Note that max will throw if the List is empty, whereas maxOption returns an Option which will be empty (None) for an empty input; idiomatic Scala favour the latter over the former.

If you really want to use compareTo then you can provide your own Ordering.

scalaList.maxOption(Ordering.fromLessThan[LocalDate]((d1, d2) => d1.compareTo(d2) < 0))
2

Ordering[A] is a type class which defines how to compare 2 elements of type A. So to compare LocalDates you need Ordering[LocalDate] instance.

LocalDate extends Comparable in Java and Scala conveniently provides instances for Comparables so when you invoke:

Ordering[java.time.LocalDate]

in REPL you'll see that Scala is able to provide you the instance without you needing to do anything (you could take a look at the list of methods provided by this typeclass).

Since you have and Ordering in implicit scope which types matches the Stream's type (e.g. Stream[LocalDate] needs Ordering[LocalDate]) you can call .max method... and that's it.

val processedResult : Stream[LocalDate] = ...
val newestDate: LocalDate = processedResult.max
Mateusz Kubuszok
  • 18,063
  • 3
  • 33
  • 53