https://kotlinlang.org logo
Docs
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
codereview
  • g

    gildor

    08/23/2018, 10:22 AM
    You cannot use SAM conversion for interfaces with more than one method (Single Abstract Method) Instead you can write extension function where you pass 2 lambdas (also works good with default argument)
    a
    • 2
    • 7
  • b

    beholder

    08/26/2018, 6:19 PM
    It is a good idea?
    @Suppress("NOTHING_TO_INLINE")
    inline infix fun Int.hasBits(bits: Int): Boolean = (this and bits) != 0
    How would you name it?
    l
    d
    • 3
    • 3
  • c

    christophsturm

    08/29/2018, 1:47 PM
    what do you think about this pattern:
    object Jackson : ObjectMapper() {
         init {
             enable(SerializationFeature.INDENT_OUTPUT)
             ....
             }
    }
    t
    k
    • 3
    • 4
  • b

    beholder

    09/06/2018, 12:32 PM
    Does anyone use function like this?
    inline fun <reified T> Any._as() = this as T
    Or it's just noise?
    r
    o
    u
    • 4
    • 3
  • t

    tipsy

    09/13/2018, 11:25 PM
    thanks @Pavlo Liapota, i actually ended up doing this:
    private val converters = mapOf<Class<*>, (String) -> Any>(
            Int::class.java to { s -> s.toInt() },
            Integer::class.java to { s -> s.toInt() },
            Double::class.java to { s -> s.toDouble() },
            Long::class.java to { s -> s.toLong() },
            Date::class.java to { s -> Date(s) }
    )
    
    fun <T> getAs(clazz: Class<T>, converter: ((String) -> T)? = null): T {
        val c = converter ?: converters[clazz] ?: throw IllegalArgumentException("Can't auto-cast to $clazz. Add a converter as a second argument.")
        return try {
            c.invoke(value)
        } catch (e: Exception) {
            ...
        } as T
    }
    g
    • 2
    • 3
  • d

    Daniel Tam

    09/19/2018, 5:44 AM
    It's hard to give an answer without getting more context in this situation
    s
    • 2
    • 3
  • s

    Sudhir Singh Khanger

    09/25/2018, 4:59 PM
    class CustomApplication: Application() {
    
        companion object {
            private var INSTANCE: CustomApplication? = null
    
            @JvmStatic
            fun get(): CustomApplication = INSTANCE!!
        }
    
        override fun onCreate() {
            super.onCreate()
            INSTANCE = this
        }
    }
    Or
    class CustomApplication : Application() {
    
        companion object {
            lateinit var instance: CustomApplication
                private set
        }
    
        override fun onCreate() {
            super.onCreate()
            instance = this
        }
    }
    Not sure if this is more appropriate for #android. Which one would you prefer for creating an Android Application class? And why?
    2️⃣ 4
    🤯 1
    e
    • 2
    • 1
  • t

    tipsy

    09/29/2018, 6:46 PM
    i'm looking for some help on how to simplify a concept i've been working on. currently i have a
    Validator
    class, which can be turned into a
    TypedValidator
    class by calling
    asInt
    ,
    asDouble
    , etc: https://github.com/tipsy/javalin/blob/master/src/main/java/io/javalin/validation/Validator.kt the problem is that i have some duplicated functionality that i'd like to get rid of, but i can't think of any (simple) way of doing that
    a
    u
    a
    • 4
    • 16
  • s

    Sam

    10/05/2018, 3:59 PM
    This is more of Android specific. I need a reference to dialog for further handling. "with" or "run"?
    dialog = with( AlertDialog.Builder( this ) ) {
            setTitle( "foo" )
            setMessage( "bar" )
            setCancelable(true)
            create()
        }.also {
            it.show()
        }
    
        or
    
        dialog = AlertDialog.Builder( this ).run {
            setTitle( "foo" )
            setMessage( "bar" )
            setCancelable(true)
            create()
        }.also {
            it.show()
        }
    d
    a
    +5
    • 8
    • 19
  • j

    Joris PZ

    10/13/2018, 7:13 PM
    Hi all, I am playing around with actors and channels, and I am wondering about the best way to structure my code. I have an actor that needs to read messages from two incoming sources, and as usual it needs to process messages one at a time so it can safely update internal state without further synchronization. I have wrapped my actor in a class, and expose a
    .run()
    method to start its internal loop:
    class MyActor {
    
      suspend fun run() {
        while(true) {
          select<Unit> {
            one.onReceive { ... }
            two.onReceive { ... }
          }
        }
      } 
    
    }
    Now, I am wondering about two things. First, where do I define the necessary channels? Do I do it in some configuration code and inject them as properties through a constructor, like so:
    class MyActor(private val one: ReceiveChannel<Query>, private val two: ReceiveChannel<Command>)
    Or do I define them in the actor itself, and expose them for outside clients to use?
    class MyActor {
      private val _one = Channel<Query>()
    
      val one: SendChannel<Query>
        get() = _one
    }
    My second question is related - is it a good idea (or even idiomatic) to use Channels to define the API to my actor? Or is it better/more common to offer message functions hiding the channels for the client, like
    suspend fun query(query: Query) {
        one.send(query)
      }
    Thanks for any feedback!
    g
    • 2
    • 2
  • a

    arve

    10/18/2018, 8:43 AM
    Trying to convert a table structure into a hierarchy. Given the following code
    data class Record(val first: String, val second: String, val third: String)
    
    val input = listOf(
            Record("a", "aa", "aaa"),
            Record("a", "aa", "aab"),
            Record("a", "ab", "aba"),
            Record("b", "ba", "baa"),
            Record("b", "ba", "bab"),
            Record("b", "bb", "bba"),
            Record("b", "bb", "bbb")
    )
    
    val expected = mapOf(
            "a" to mapOf(
                    "aa" to listOf("aaa", "aab"),
                    "ab" to listOf("aba")
            ),
            "b" to mapOf(
                    "ba" to listOf("baa", "bab"),
                    "bb" to listOf("bba", "bbb")
            )
    )
    How would you approach it? Currently I'm doing
    input.groupBy({ it.first })
            .mapValues {
                it.value.groupBy({ it.second }, { it.third })
            }
    , but nesting the `groupBy`s feels less than ideal, especially if you consider more than 2 levels.. Any suggestions for better approaches?
    j
    • 2
    • 1
  • t

    tipsy

    10/26/2018, 2:07 PM
    which of these would you prefer:
    when (targetHandler) {
        is HandlerCollection -> targetHandler.apply { addHandler(defaultHandlers) }
        is HandlerWrapper -> targetHandler.apply { handler = defaultHandlers}
    }
    and
    (targetHandler as? HandlerCollection)?.apply { addHandler(defaultHandlers) }
    (targetHandler as? HandlerWrapper)?.apply { handler = defaultHandlers }
    1️⃣ 19
    s
    • 2
    • 2
  • o

    oday

    10/31/2018, 3:04 PM
    val newFragment: Fragment? = if (fragment is CarSearchFragment? && fragment == null) {
                CarSearchFragment()
            } else if (fragment is CarValuationFragment? && fragment == null) {
                CarValuationFragment()
            } else if (fragment is HotDealsFragment? && fragment == null) {
                HotDealsFragment()
            } else if (fragment is FavoritesFragment? && fragment == null) {
                FavoritesFragment()
            } else {
                fragment
            }
    l
    d
    +2
    • 5
    • 13
  • k

    kingsley

    11/04/2018, 4:50 PM
    if an entry isn’t in the base map, it won’t exist in the final one
    Yes. Which is why I iterated through
    mapOverride
    instead. This is a union of both maps with the assumption that they only contain sets/other values and a key always points to values of similar type (or null) in both maps. Entries in
    mapOverride
    are always preferred except for sets where both will get merged I suppose that is what you’re trying to achieve?
    d
    • 2
    • 17
  • o

    Omar Mohamed

    11/04/2018, 4:54 PM
    I am trying to use Fountain (https://github.com/xmartlabs/fountain) in order to help me handle pagination and local/remote datasource
    m
    • 2
    • 1
  • m

    mersan

    11/04/2018, 11:01 PM
    Is there a better way to do this? I'm trying to create distinct function for functions
    fun <T, B> distinct(body: (T) -> B): (T) -> B {
      val lastInput = AtomicReference<T>()
      val lastReturn = AtomicReference<B>()
      return {
        if (lastInput.get() != it) {
          lastInput.set(it)
          lastReturn.set(body(it))
        }
        lastReturn.get()
      }
    }
    e
    t
    • 3
    • 3
  • o

    oday

    11/13/2018, 2:36 PM
    how can I fix this? 😄 https://pastebin.com/9iLG5E6B
    a
    g
    • 3
    • 22
  • u

    ursus

    11/17/2018, 5:39 PM
    About statemachines? If I have certain actions, which are allowed in certain state, where they dont change it state, however those actions are async, so need to change "some" state to pending, in order to avoid multiple calls until the async is finished i.e. I have call states, for example one of which is Activated, and I have actions like MuteMic, where this action is only allowed in Activated state but lets say MuteMic is heavy / or async, so I need to surround it with pending state, should that pending state be part of the call state hierarchy, i.e. on the same level as Activated is, or somehow nested inside it, or separate state machine?,
    when state == Activated
       when action == MuteMic
          state = ActivatedMuteMicPending
          effect(Effect.DoMuteMic)
          state = Activated
    sealed class State {
       object Activated,
       object ActivatedMuteMicPending
    }
    im not sure if this is good design
    l
    t
    • 3
    • 16
  • b

    BMG

    11/20/2018, 12:41 PM
    I need to do a set of list operations and I want those methods to be pure with taking List as input and giving List as output and they have to be chained. Can this be improved?
    val updatedDataElementsOne = removeExtraElements(info)
    val updatedDataElementsTwo = updateExistingElements(updatedDataElementsOne)
    return populateEmptyElements(updatedDataElementsTwo)
    b
    a
    d
    • 4
    • 10
  • z

    zokipirlo

    11/21/2018, 12:48 PM
    Hi! Still learning functional things in Kotlin and would need some help. Can someone please check my example and tell me if this example can be done better? https://try.kotlinlang.org/#/UserProjects/h9ra2isjl4vudcq3mmo8gii4n8/fb6lvfgtq7ppf3es5tt36b5h0o Thanks! [moved from #general]
    h
    a
    e
    • 4
    • 5
  • d

    Daniel

    11/22/2018, 3:15 PM
    Hello and a big thanks in advance! I need advice from kotlin collection specialists 🙂 Is there an more elegant way to extract two elements out of a list which are equal given a predicate? I came up with this:
    object TwoLikelyVariablesMatcher : CondensingMatcher {
        override fun matches(operands: Terms): Boolean {
            operands.filterIsInstance<AnyVariable>()
                    .groupBy { it.unsignedName }
                    .forEach { (_, variablesWithSameName) ->
                        if(variablesWithSameName.size > 1) return true
                    }
    
            return false
        }
    
        override fun matches(source: Terms, target: Terms): Boolean {
            TODO("not implemented")
        }
    }
    
    @Test
        fun `A two likely variables matcher matches with operands containing exactly two likely variables`() {
            // GIVEN
            val operands = termsOf(
                    PositiveVariable("x"),
                    mock(),
                    PositiveVariable("y"),
                    mock(),
                    NegativeVariable("x"))
    
            // THEN
            assertTrue(TwoLikelyVariablesMatcher.matches(operands))
        }
    
        @Test
        fun `A two likely variables matcher doesn't match with operands containing zero likely variables`() {
            // GIVEN
            val operands = termsOf(
                    PositiveVariable("x"),
                    PositiveVariable("y"),
                    PositiveVariable("z"))
    
            // THEN
            assertFalse(TwoLikelyVariablesMatcher.matches(operands))
        }
    What it does is the following: I have a list of mathematical terms and I want to filter out two variables which have the same unsigned Name (for example
    x
    or
    y
    .
    t
    • 2
    • 2
  • r

    rezenebe

    11/23/2018, 3:53 AM
    Is it bad practice to pass a fragment in as an adapter's parameter so you can access it's methods?
    e
    d
    t
    • 4
    • 10
  • d

    dMusicb

    11/30/2018, 6:25 PM
    What do you find easier to read:
    completedAlert?.let { updatedAlerts += it }
    // or
    if (completedAlert != null) updatedAlerts += completedAlert
    2️⃣ 5
    1️⃣ 12
    s
    c
    +9
    • 12
    • 16
  • s

    Slackbot

    12/09/2018, 5:35 PM
    This message was deleted.
    b
    • 2
    • 1
  • j

    jurajsolarml

    12/18/2018, 1:53 PM
    Hello,please solve the problems.Registration does not work where can be an error ? /Kotlin/ Thanks https://hastebin.com/punafomaze.cpp
    t
    • 2
    • 3
  • d

    Dalinar

    12/26/2018, 9:54 AM
    could someone proof-read this? it seems to work, I just want to make sure that I understand
    CompletableFuture
    correctly if I hammer (just from a single thread)
    asyncDumpReport()
    then am I correct to assume that there is no chance of
    dumpReport()
    firing until the previous call to
    dumpReport()
    has completed?
    `
        /**
         * calls [dumpReport] asynchronously, _if there is not currently such a call in progress_
         */
        private fun asyncDumpReport() {
            val p = promise
            if (p == null || p.getNow(false))
                promise = CompletableFuture.supplyAsync {
                    try {
                        dumpReport()
                    } finally {}
                    true
                }
        }
        private var promise: CompletableFuture<Boolean>? = null
    `
    a
    t
    • 3
    • 3
  • d

    digitalsanctum

    01/03/2019, 11:53 PM
    What would be a better way of doing the following:
    listOf(
      CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>).launch { ddbTools.deleteTableInRegions(destinationTable, destinationRegions) },
      CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>).launch { jobService.deleteJobTable() },
      CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>).launch { jobService.deleteCheckpointTable() }).joinAll()
    l
    • 2
    • 6
  • b

    breandan

    01/11/2019, 11:38 PM
    Is it always possible to convert extensions to members? https://stackoverflow.com/questions/54155416/how-to-convert-an-extension-into-a-member
    🇳🇴 1
    h
    • 2
    • 3
  • g

    ghosalmartin

    01/15/2019, 4:31 PM
    You just implement GenericAdapterViewModel and override buildView and bindViewHolder, sealed classes lend themselves nicely to this kinda of thing. Pair it with Anko and awayy you go
    o
    • 2
    • 2
  • e

    edwardwongtl

    01/16/2019, 6:04 AM
    I got a simpler version but only support one viewType at a time
    class SimpleViewHolder<T>(view: View) : RecyclerView.ViewHolder(view)
    
    class RxAdapter<T>(
        @LayoutRes private val layoutId: Int,
        private val binding: (View, T) -> Unit
    ) : ListAdapter<T, SimpleViewHolder<T>>(DiffCallback<T>()) {
        private val signal by lazy { PublishSubject.create<Pair<Int, T>>() }
        val itemClicks by lazy { signal as Observable<Pair<Int, T>> }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SimpleViewHolder<T> =
            SimpleViewHolder(parent.inflate(layoutId, false))
    
        override fun onBindViewHolder(holder: SimpleViewHolder<T>, position: Int) {
            binding(holder.itemView, getItem(position))
            holder.itemView.setOnClickListener { signal.onNext(holder.adapterPosition to getItem(holder.adapterPosition)) }
        }
    
        private class DiffCallback<T> : DiffUtil.ItemCallback<T>() {
            override fun areItemsTheSame(oldItem: T, newItem: T): Boolean = oldItem == newItem
    
            override fun areContentsTheSame(oldItem: T, newItem: T): Boolean = oldItem == newItem
        }
    }
    Forgive me for combining Rx into it, as it suits my need.
    a
    • 2
    • 4
Powered by Linen
Title
e

edwardwongtl

01/16/2019, 6:04 AM
I got a simpler version but only support one viewType at a time
class SimpleViewHolder<T>(view: View) : RecyclerView.ViewHolder(view)

class RxAdapter<T>(
    @LayoutRes private val layoutId: Int,
    private val binding: (View, T) -> Unit
) : ListAdapter<T, SimpleViewHolder<T>>(DiffCallback<T>()) {
    private val signal by lazy { PublishSubject.create<Pair<Int, T>>() }
    val itemClicks by lazy { signal as Observable<Pair<Int, T>> }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SimpleViewHolder<T> =
        SimpleViewHolder(parent.inflate(layoutId, false))

    override fun onBindViewHolder(holder: SimpleViewHolder<T>, position: Int) {
        binding(holder.itemView, getItem(position))
        holder.itemView.setOnClickListener { signal.onNext(holder.adapterPosition to getItem(holder.adapterPosition)) }
    }

    private class DiffCallback<T> : DiffUtil.ItemCallback<T>() {
        override fun areItemsTheSame(oldItem: T, newItem: T): Boolean = oldItem == newItem

        override fun areContentsTheSame(oldItem: T, newItem: T): Boolean = oldItem == newItem
    }
}
Forgive me for combining Rx into it, as it suits my need.
a

arekolek

01/16/2019, 8:46 AM
that
DiffCallback
doesn’t handle modifying an item
e

edwardwongtl

01/16/2019, 8:47 AM
When using data class, it actually can handle modified items, as the equals in data class is deep equal.
a

arekolek

01/16/2019, 8:48 AM
I’m saying your implementation of
DiffCallback
doesn’t handle it, think of what happens if an item changes one field
(it’s going to be treated as a removal + addition)
View count: 3