Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property include/exclude on Kotlin data classes

Suppose I only want one or two fields to be included in the generated equals and hashCode implementations (or perhaps exclude one or more fields). For a simple class, e.g.:

data class Person(val id: String, val name: String) 

Groovy has this:

@EqualsAndHashCode(includes = 'id') 

Lombok has this:

@EqualsAndHashCode(of = "id") 

What is the idiomatic way of doing this in Kotlin?

My approach so far

data class Person(val id: String) {    // at least we can guarantee it is present at access time    var name: String by Delegates.notNull()     constructor(id: String, name: String): this(id) {       this.name = name    } } 

Just feels wrong though... I don't really want name to be mutable, and the extra constructor definition is ugly.

like image 754
Jonathan Schneider Avatar asked Apr 12 '15 22:04

Jonathan Schneider


People also ask

Can Kotlin data classes have functions?

Kotlin generates the basic functions that must be overloaded for a good model class, giving us good toString(), hashCode(), and equals() functions. Kotlin also provides some extra functionality in the form of a copy() function, and various componentN() functions, which are important for variable destructuring.

How do I inherit from Kotlin data class?

By default, in Kotlin, classes are final and cannot be subclassed. You are only allowed to inherit from abstract classes or classes that are marked with the open keyword. Hence you need to mark the RoundHut class with the open keyword to allow it to be inherited from.

Which method is not automatically added to a data class?

Data Class Limitations They can't be open , abstract , sealed or inner classes. The compiler forbids manually implementing copy() and componentN() methods. Any parent interface or class of a data class must not have a copy() method.

What is a property of a class Kotlin?

Properties are the variables (to be more precise, member variables) that are declared inside a class but outside the method. Kotlin properties can be declared either as mutable using the “var” keyword or as immutable using the “val” keyword.


2 Answers

I've used this approach.

data class Person(val id: String, val name: String) {    override fun equals(other: Person) = EssentialData(this) == EssentialData(other)    override fun hashCode() = EssentialData(this).hashCode()    override fun toString() = EssentialData(this).toString().replaceFirst("EssentialData", "Person") }  private data class EssentialData(val id: String) {    constructor(person: Person) : this(id = person.id)  } 
like image 102
Duncan McGregor Avatar answered Sep 20 '22 01:09

Duncan McGregor


This approach may be suitable for property exclusion:

class SkipProperty<T>(val property: T) {   override fun equals(other: Any?) = true   override fun hashCode() = 0 } 

SkipProperty.equals simply returns true, which causes the embeded property to be skipped in equals of parent object.

data class Person(     val id: String,      val name: SkipProperty<String> ) 
like image 27
Fartab Avatar answered Sep 23 '22 01:09

Fartab