Jerry
Jerry

Reputation: 1197

Java Stream with ::new to Kotlin

I'm trying to convert the following Spring Security code from Java to Kotlin.

Java:

Collection<? extends GrantedAuthority> authorities =
        Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
            .map(SimpleGrantedAuthority::new)
            .collect(Collectors.toList());

Kotlin:

val authorities = Arrays.stream(claims[AUTHORITIES_KEY].toString().split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
        .map(SimpleGrantedAuthority())
        .collect(Collectors.toList<SimpleGrantedAuthority>())

I get a Type mismatch error (Required: Function<in String!, out (???..???)>!) on .map(SimpleGrantedAuthority()). How do I convert the above Java code to Kotlin with a ::new keyword correctly?

Upvotes: 3

Views: 1385

Answers (2)

Grzegorz Piwowarek
Grzegorz Piwowarek

Reputation: 13783

You need to pass a lambda expression to map's body. What you did there was creating a new instance of SimpleGrantedAuthority instead of creating a function that returns a new instance of SimpleGrantedAuthority.

It's a subtle difference.

In order to fix your problems, you can use a reference to the constructor:

.map(::SimpleGrantedAuthority)

or define a lambda expression by hand:

.map({ SimpleGrantedAuthority() })

Also, instead of:

claims.get(AUTHORITIES_KEY)

you can do:

claims[AUTHORITIES_KEY]

You do not really need to use Stream API in Kotlin. Native Collections API is powerful enough:

 val auths = claims[AUTHORITIES_KEY].toString()
   .split(",")
   .filterNot(String::isEmpty)
   .map(::SimpleGrantedAuthority)

Upvotes: 1

miensol
miensol

Reputation: 41638

Using Arrays.stream doesn't make the code super readable:

val authorities = Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(",").toTypedArray())
     .map(::SimpleGrantedAuthority).collect(Collectors.toList<SimpleGrantedAuthority>())

However in Kotlin you can do better:

val authorities = claims.get(AUTHORITIES_KEY).toString()
                .split(",").filterNot { it.isEmpty() }
                .map(::SimpleGrantedAuthority)

Upvotes: 6

Related Questions