it-swarm.com.de

So erstellen Sie einen leeren Konstruktor für die Datenklasse in Kotlin Android

Ich habe 10+ Parameter in einer Datenklasse. Ich möchte die Datenklasse mit einem leeren Konstruktor initialisieren und die Werte nur für wenige Parameter mit Setter festlegen und das Objekt an den Server übergeben.

data class Activity(
        var updated_on: String,
        var tags: List<String>,
        var description: String,
        var user_id: List<Int>,
        var status_id: Int,
        var title: String,
        var created_at: String,
        var data: HashMap<*, *>,
        var id: Int,
        var counts: LinkedTreeMap<*, *>,
)

Verwendungszweck:

So etwas wird leicht sein

                val activity =  Activity();
                activity.title = "New Computer"
                sendToServer(activity)

Es ist jedoch erforderlich, dass alle Argumente während des Erstellungskonstruktors übergeben werden. Wie kann ich das wie oben vereinfachen?

                val activity =  Activity(null,null,null,null,null,"New Computer",null,null,null,null);
                sendToServer(activity)
95
Sai Kiran

Sie haben hier 2 Möglichkeiten:

  1. Weisen Sie jedem Parameter primary constructor einen Standardwert zu:

    data class Activity(
        var updated_on: String = "",
        var tags: List<String> = emptyList(),
        var description: String = "",
        var user_id: List<Int> = emptyList(),
        var status_id: Int = -1,
        var title: String = "",
        var created_at: String = "",
        var data: HashMap<*, *> = hashMapOf<Any, Any>(),
        var id: Int = -1,
        var counts: LinkedTreeMap<*, *> = LinkedTreeMap<Any, Any>()
    ) 
    
  2. Deklarieren Sie einen sekundären Konstruktor , der keine Parameter enthält:

    data class Activity(
        var updated_on: String,
        var tags: List<String>,
        var description: String,
        var user_id: List<Int>,
        var status_id: Int,
        var title: String,
        var created_at: String,
        var data: HashMap<*, *>,
        var id: Int,
        var counts: LinkedTreeMap<*, *>
    ) {
        constructor() : this("", emptyList(), 
                             "", emptyList(), -1, 
                             "", "", hashMapOf<Any, Any>(), 
                             -1, LinkedTreeMap<Any, Any>()
                             )
    }
    

Wenn Sie sich nicht auf copy oder equals der Activity-Klasse verlassen oder die automatisch generierten data class-Methoden überhaupt nicht verwenden, können Sie reguläre Klassen wie folgt verwenden:

class ActivityDto {
    var updated_on: String = "",
    var tags: List<String> = emptyList(),
    var description: String = "",
    var user_id: List<Int> = emptyList(),
    var status_id: Int = -1,
    var title: String = "",
    var created_at: String = "",
    var data: HashMap<*, *> = hashMapOf<Any, Any>(),
    var id: Int = -1,
    var counts: LinkedTreeMap<*, *> = LinkedTreeMap<Any, Any>()
}

Nicht jeder DTO muss ein data class sein und umgekehrt. Nach meiner Erfahrung finde ich, dass Datenklassen besonders in Bereichen nützlich sind, in denen komplexe Geschäftslogik erforderlich ist. 

139
miensol

Wenn Sie allen Feldern Standardwerte zuweisen , generiert Kotlin automatisch einen leeren Konstruktor.

data class User(var id: Long = -1,
                var uniqueIdentifier: String? = null)

und du kannst einfach anrufen:

val user = User()

Lassen Sie mich neben der Antwort von @miensol noch einige Details hinzufügen:

Wenn Sie einen mit Java sichtbaren leeren Konstruktor verwenden möchten, der Datenklassen verwendet, müssen Sie ihn explizit definieren.

Die Verwendung von Standardwerten + Konstruktorkennzeichner ist recht einfach:

data class Activity(
    var updated_on: String = "",
    var tags: List<String> = emptyList(),
    var description: String = "",
    var user_id: List<Int> = emptyList(),
    var status_id: Int = -1,
    var title: String = "",
    var created_at: String = "",
    var data: HashMap<*, *> = hashMapOf<Any, Any>(),
    var id: Int = -1,
    var counts: LinkedTreeMap<*, *> = LinkedTreeMap<Any, Any>()
) {
    constructor() : this(title = "") // this constructor is an explicit
                                     // "empty" constructor, as seen by Java.
}

Das bedeutet, dass Sie mit diesem Trick dieses Objekt jetzt mit den Standard-Java-Serialisierern (Jackson, Gson usw.) serialisieren/deserialisieren können.

10
Gui13

Wenn Sie jedem primären Konstruktorparameter einen Standardwert zuweisen:

data class Item(var id: String = "",
            var title: String = "",
            var condition: String = "",
            var price: String = "",
            var categoryId: String = "",
            var make: String = "",
            var model: String = "",
            var year: String = "",
            var bodyStyle: String = "",
            var detail: String = "",
            var latitude: Double = 0.0,
            var longitude: Double = 0.0,
            var listImages: List<String> = emptyList(),
            var idSeller: String = "")

und von der Klasse, in der die Instanzen ohne Argumente oder mit den Argumenten aufgerufen werden können, die Sie in diesem Moment haben

var newItem = Item()

var newItem2 = Item(title = "exampleTitle",
            condition = "exampleCondition",
            price = "examplePrice",
            categoryId = "exampleCategoryId")
1
yOshi

Aus der Dokumentation

ANMERKUNG: Wenn in der JVM alle Parameter des primären Konstruktors Standardwerte haben, generiert der Compiler einen zusätzlichen parameterlosen Konstruktor, der die Standardwerte verwendet. Dies erleichtert die Verwendung von Kotlin mit Bibliotheken wie Jackson oder JPA, die Klasseninstanzen über parameterlose Konstruktoren erstellen.

1

Ich würde vorschlagen, den primären Konstruktor zu ändern und jedem Parameter einen Standardwert hinzuzufügen:

data class Activity(
    var updated_on: String = "",
    var tags: List<String> = emptyList(),
    var description: String = "",
    var user_id: List<Int> = emptyList(),
    var status_id: Int = -1,
    var title: String = "",
    var created_at: String = "",
    var data: HashMap<*, *> = hashMapOf<Any, Any>(),
    var id: Int = -1,
    var counts: LinkedTreeMap<*, *> = LinkedTreeMap<Any, Any>()
)

Sie können Werte auch auf null setzen, indem Sie ? hinzufügen und dann null zuweisen:

data class Activity(
    var updated_on: String? = null,
    var tags: List<String>? = null,
    var description: String? = null,
    var user_id: List<Int>? = null,
    var status_id: Int? = null,
    var title: String? = null,
    var created_at: String? = null,
    var data: HashMap<*, *>? = null,
    var id: Int? = null,
    var counts: LinkedTreeMap<*, *>? = null
)

Im Allgemeinen wird empfohlen, nullfähige Objekte zu vermeiden. Schreiben Sie den Code so, wie wir ihn nicht benötigen. Nicht nullfähige Objekte sind einer der Vorteile von Kotlin im Vergleich zu Java. Daher ist die erste Option oben vorzuziehen .

Mit beiden Optionen erhalten Sie das gewünschte Ergebnis:

val activity = Activity()
activity.title = "New Computer"
sendToServer(activity)
0
Micer

Nicht leerer sekundärer Konstruktor für Datenklasse in Kotlin:

data class ChemicalElement(var name: String,
                           var symbol: String,
                           var atomicNumber: Int,
                           var atomicWeight: Double,
                           var nobleMetal: Boolean?) {

    constructor(): this("Silver",
                        "Ag", 
                        47,
                        107.8682,
                        true)
}

fun main() {
    var chemicalElement = ChemicalElement()
    println("RESULT: ${chemicalElement.symbol} means ${chemicalElement.name}")
    println(chemicalElement)
}

// RESULT: Ag means Silver
// ChemicalElement(name=Silver, symbol=Ag, atomicNumber=47, atomicWeight=107.8682, nobleMetal=true)

Leerer sekundärer Konstruktor für Datenklasse in Kotlin:

data class ChemicalElement(var name: String,
                           var symbol: String,
                           var atomicNumber: Int,
                           var atomicWeight: Double,
                           var nobleMetal: Boolean?) {

    constructor(): this("",
                        "", 
                        -1,
                        0.0,
                        null)
}

fun main() {
    var chemicalElement = ChemicalElement()
    println(chemicalElement)
}

// ChemicalElement(name=, symbol=, atomicNumber=-1, atomicWeight=0.0, nobleMetal=null)
0
ARGeo