Ricerca…
Creazione di DTO (POJO / POCO)
Le classi di dati in kotlin sono classi create per non fare altro che contenere i dati. Tali classi sono contrassegnate come data
:
data class User(var firstname: String, var lastname: String, var age: Int)
Il codice sopra crea una classe User
con i seguenti generati automaticamente:
- Getter e setter per tutte le proprietà (getter solo per
val
s) -
equals()
-
hashcode()
-
toString()
-
copy()
-
componentN()
(doveN
è la proprietà corrispondente in ordine di dichiarazione)
Proprio come con una funzione, è possibile specificare anche i valori predefiniti:
data class User(var firstname: String = "Joe", var lastname: String = "Bloggs", var age: Int = 20)
Maggiori dettagli possono essere trovati qui Classi di dati .
Filtrare un elenco
val list = listOf(1,2,3,4,5,6)
//filter out even numbers
val even = list.filter { it % 2 == 0 }
println(even) //returns [2,4]
Delegare a una classe senza fornirla nel costruttore pubblico
Si supponga di voler delegare a una classe ma non si desidera fornire la classe delegata al parametro costruttore. Invece, si vuole costruirlo privatamente, rendendo il chiamante del costruttore inconsapevole. All'inizio questo potrebbe sembrare impossibile perché la delega delle classi consente di delegare solo ai parametri del costruttore. Tuttavia, c'è un modo per farlo, come indicato in questa risposta :
class MyTable private constructor(table: Table<Int, Int, Int>) : Table<Int, Int, Int> by table {
constructor() : this(TreeBasedTable.create()) // or a different type of table if desired
}
Con questo, puoi semplicemente chiamare il costruttore di MyTable
questo modo: MyTable()
. La Table<Int, Int, Int>
a cui i delegati MyTable
verranno creati privatamente. Il chiamante del costruttore non ne sa nulla.
Questo esempio è basato su questa domanda SO .
Serializable e serialVersionUid in Kotlin
Per creare serialVersionUID
per una classe in Kotlin hai a disposizione alcune opzioni che prevedono l'aggiunta di un membro all'oggetto companion della classe.
Il bytecode più conciso proviene da un private const val
che diventerà una variabile statica privata sulla classe MySpecialCase
, in questo caso MySpecialCase
:
class MySpecialCase : Serializable {
companion object {
private const val serialVersionUID: Long = 123
}
}
È inoltre possibile utilizzare questi moduli, ciascuno con un effetto collaterale di avere metodi getter / setter che non sono necessari per la serializzazione ...
class MySpecialCase : Serializable {
companion object {
private val serialVersionUID: Long = 123
}
}
Questo crea il campo statico ma crea anche un getSerialVersionUID
sull'oggetto companion che non è necessario.
class MySpecialCase : Serializable {
companion object {
@JvmStatic private val serialVersionUID: Long = 123
}
}
Questo crea il campo statico ma crea anche un getter statico e getSerialVersionUID
sulla classe contenente MySpecialCase
che non è necessaria.
Ma tutto funziona come metodo per aggiungere serialVersionUID
ad una classe Serializable
.
Metodi fluidi in Kotlin
I metodi fluenti in Kotlin possono essere gli stessi di Java:
fun doSomething() {
someOtherAction()
return this
}
Ma puoi anche renderli più funzionali creando una funzione di estensione come:
fun <T: Any> T.fluently(func: ()->Unit): T {
func()
return this
}
Che consente quindi più ovviamente le funzioni fluenti:
fun doSomething() {
return fluently { someOtherAction() }
}
Usare let o anche per semplificare il lavoro con oggetti nullable
let
in Kotlin crea un binding locale dall'oggetto su cui è stato chiamato. Esempio:
val str = "foo"
str.let {
println(it) // it
}
Questo stamperà "foo"
e restituirà Unit
.
La differenza tra let
e also
è che puoi restituire qualsiasi valore da un blocco let
. also
nell'altra mano sarà sempre Reutrn Unit
.
Ora, perché questo è utile, chiedi? Perché se chiami un metodo che può restituire null
e vuoi eseguire qualche codice solo quando quel valore di ritorno non è null
puoi usare let
o also
così:
val str: String? = someFun()
str?.let {
println(it)
}
Questo pezzo di codice eseguirà solo il blocco let
quando str
non è null
. Notare l'operatore di sicurezza null
( ?
).
Utilizzare applica per inizializzare oggetti o per ottenere il concatenamento del metodo
La documentazione di apply
dice quanto segue:
chiama il blocco funzione specificato con
this
valore come ricevitore e restituiscethis
valore.
Mentre il kdoc non è così utile apply
è davvero una funzione utile. In parole povere si apply
stabilisce un ambito in cui this
è legato all'oggetto che hai chiamato apply
. Ciò ti consente di risparmiare del codice quando devi chiamare più metodi su un oggetto che poi restituirai in seguito. Esempio:
File(dir).apply { mkdirs() }
Questo è come scrivere questo:
fun makeDir(String path): File {
val result = new File(path)
result.mkdirs()
return result
}