is there a way to simplify this? ```fun isEmptyCol...
# codereview
s
is there a way to simplify this?
Copy code
fun isEmptyCollection(any: Any): Boolean = when(any) {
  is Collection<*> -> any.isEmpty()
  is Map<*, *> -> any.isEmpty()
  else -> false
}
smart-casting doesn't seem to recognize union types (or at least, support calling methods with identical signatures on a union instance)
yes, I could make it an extension function, but that's not really in the spirit of the question
Copy code
fun Any.isEmptyCollection() = when(this) {
  is Collection<*> -> isEmpty()
  is Map<*, *> -> isEmpty()
  else -> false
}
s
I think that's as concise as you can get with parameter/receiver of type
Any
. That being said, is there a reason you need parameter to be of
Any
type? Do you have some generic functionality that works on both collections and maps and passed object's type is not know in compile-time? Would that be just some private helper function? (wider context would be helpful)
1
s
Generically deserializing row data from Cassandra—decoded objects are just
Any
until you cast them, and cass supports a few different column data types, so at this level, there really isn't much type data known ahead of time
m
From Copilot AI:
Copy code
fun isEmptyCollection(any: Any): Boolean = (any as? Collection<*> ?: any as? Map<*, *>)?.isEmpty() ?: false
However, I personally prefer having a when expression cause it is easier to read and understand.
c
That doesn't even compile?
😂 3
m
Told you, AI 😅
k
I would leave "collection" out of the name because maps are usually not considered collections in Java/Kotlin (but your application's common terminology might do so).
1
c
Actually, you're right, this would work no?
Copy code
(yourAny as? Iterable<*>)?.isEmpty() ?: false
k
No,
Iterable
doesn't implement
isEmpty
, and I therefore deleted that sentence from my previous post.
c
Then
(yourAny as? Iterable<*>)?.iterator()?.hasNext() != true
s
I thought about doing that, but I wasn't sure what the performance of
as?
and the cost of
.iterator()
would be like, or at least, whether it would be worth it over the
when
c
I believe the performance is going to be the same between both alternatives (or at least, the difference is so small that it probably isn't worth paying attention to)
s
🤔 that's probably true, yeah
c
Well, the thing that's costly here is the
is
check on an interface. Everything else I believe is virtually free. But
sealed interface
was introduced to the language, and it's meant to be used like this, so…
k
There may be some exotic collection type (perhaps one that lazily retrieves from a database) for which
iterator().hasNext()
is more expensive than
isEmpty()
c
I'd argue this is an implementation bug to have different performance characteristics between
iterator.hasNext()
and
isEmpty()
, but fair, in the grand scheme of things it could happen. However, I believe OP wanted to call this on the return value of a DB driver to parse the values, so this isn't a risk in this case.
👆 1
s
the row data is being fetched in this case—the level at which I'm doing this is where the retrieval is happening