|
| 1 | +// Data classes can't be abstract, open, sealed, or inner. |
| 2 | +// The primary constructor must have at least one parameter. |
| 3 | + |
| 4 | +package codecollection.kotlinfeatures |
| 5 | + |
| 6 | +data class Person( |
| 7 | + val firstName: String, |
| 8 | + val age: Int, |
| 9 | + val email: String, |
| 10 | +) |
| 11 | + |
| 12 | +// Attention! Using 'var' is not recommended in the data classes. See the example. |
| 13 | +data class MutablePerson( |
| 14 | + var firstName: String, |
| 15 | + var age: Int, |
| 16 | + var email: String, |
| 17 | +) |
| 18 | + |
| 19 | +data class Address( |
| 20 | + var city: String, |
| 21 | + var street: String, |
| 22 | +) |
| 23 | + |
| 24 | +data class Employee( |
| 25 | + val position: String = "Intern", // default property |
| 26 | + val person: Person, |
| 27 | + val address: Address, |
| 28 | +) |
| 29 | + |
| 30 | +fun main() { |
| 31 | + println("=== BASIC DATA CLASS FEATURES ===") |
| 32 | + |
| 33 | + // Create instances |
| 34 | + val person1 = Person(firstName = "Alice", age = 30, email = "[email protected]") |
| 35 | + val person2 = Person(firstName = "Bob", age = 32, email = "[email protected]") |
| 36 | + val person3 = Person(firstName = "Alice", age = 30, email = "[email protected]") |
| 37 | + |
| 38 | + demonstrateToString(person1, person2) |
| 39 | + demonstrateToEquals(person1, person2, person3) |
| 40 | + demonstrateToHashCode(person1, person2, person3) |
| 41 | + demonstrateToCopy(person1) |
| 42 | + demonstrateToDestructuring(person1) |
| 43 | +} |
| 44 | + |
| 45 | +fun demonstrateToString(person1: Person, person2: Person) { |
| 46 | + // toString() - automatically generated |
| 47 | + println("\n=== toString() ===") |
| 48 | + println("Person 1: $person1") |
| 49 | + println("Person 2: $person2") |
| 50 | + // Output: |
| 51 | + // Person 1: Person(firstName=Alice, age=30, [email protected]) |
| 52 | + // Person 2: Person(firstName=Bob, age=32, [email protected]) |
| 53 | +} |
| 54 | + |
| 55 | +fun demonstrateToEquals(person1: Person, person2: Person, person3: Person) { |
| 56 | + // equals() - automatically generated |
| 57 | + println("\n=== equals() ===") |
| 58 | + println("person1 == person3: ${person1 == person3}") // true |
| 59 | + println("person1 == person2: ${person1 == person2}") // false |
| 60 | +} |
| 61 | + |
| 62 | +fun demonstrateToHashCode(person1: Person, person2: Person, person3: Person) { |
| 63 | + // hashCode() - automatically generated |
| 64 | + println("\n=== hashCode() ===") |
| 65 | + println("person1.hashCode() equals person3.hashCode(): ${person1.hashCode() == person3.hashCode()}") // true |
| 66 | + |
| 67 | + // Checking in HashSet |
| 68 | + println("\n=== Checking in HashSet ===") |
| 69 | + val peopleSet = hashSetOf(person1, person2) |
| 70 | + println("set contains person1: ${peopleSet.contains(person1)}") // true |
| 71 | + println("set contains person3: ${peopleSet.contains(person3)}") // true, because hashCode() and equals() are the same |
| 72 | + // Output: |
| 73 | + // set contains person1: true |
| 74 | + // set contains person3: true |
| 75 | + |
| 76 | + // Checking in HashMap |
| 77 | + println("\n=== Checking in HashMap ===") |
| 78 | + |
| 79 | + val salary = |
| 80 | + hashMapOf( |
| 81 | + person1 to 30000, |
| 82 | + person2 to 27000, |
| 83 | + ) |
| 84 | + |
| 85 | + println("person1 salary: ${salary[person1]}") // 30000 |
| 86 | + println("person3 salary: ${salary[person3]}") // 30000, because person3 equals person1 (same hashCode and equals) |
| 87 | + |
| 88 | + // Important! The use "var" is not recommended in the data classes. |
| 89 | + println("\n=== Mutation properties: ===") |
| 90 | + val mutablePerson = MutablePerson( "Charlie", 35, "[email protected]") |
| 91 | + val roleMap = hashMapOf(mutablePerson to "Developer") |
| 92 | + println("before mutation: ${mutablePerson.hashCode()}") |
| 93 | + mutablePerson.age = 36 |
| 94 | + println("after mutation: ${mutablePerson.hashCode()}") // Different! |
| 95 | + println("Map size: ${roleMap.size}") // Map still contains the entry but can't find it. |
| 96 | +} |
| 97 | + |
| 98 | +fun demonstrateToCopy(person1: Person) { |
| 99 | + // copy() - automatically generated. |
| 100 | + // Attention! It is shallow copy. See example |
| 101 | + println("\n=== copy() ===") |
| 102 | + |
| 103 | + val person1Updated = person1.copy(age = 31, email = "[email protected]") |
| 104 | + |
| 105 | + println("Updated person 1: $person1Updated") |
| 106 | + // Output: Updated person 1: Person(firstName=Alice, age=31, [email protected]) |
| 107 | + |
| 108 | + println("\n=== Shallow copy: ===") |
| 109 | + val originalAddress = Address("New York", "Washington Street") |
| 110 | + val employee1 = Employee("Developer", person1, originalAddress) |
| 111 | + val employee2 = employee1.copy() |
| 112 | + println("before mutation:") |
| 113 | + println("employee1: $employee1") |
| 114 | + println("employee2: $employee2") |
| 115 | + // employee1: Employee(position=Developer, person=Person(firstName=Alice, age=30, [email protected]), address=Address(city=New York, street=Washington Street)) |
| 116 | + // employee2: Employee(position=Developer, person=Person(firstName=Alice, age=30, [email protected]), address=Address(city=New York, street=Washington Street)) |
| 117 | + |
| 118 | + employee2.address.street = "Park Avenue" |
| 119 | + println("after mutation:") |
| 120 | + println("employee1: $employee1") // The street has changed too! |
| 121 | + println("employee2: $employee2") |
| 122 | + // employee1: Employee(position=Developer, person=Person(firstName=Alice, age=30, [email protected]), address=Address(city=New York, street=Park Avenue)) |
| 123 | + // employee2: Employee(position=Developer, person=Person(firstName=Alice, age=30, [email protected]), address=Address(city=New York, street=Park Avenue)) |
| 124 | +} |
| 125 | + |
| 126 | +fun demonstrateToDestructuring(person1: Person) { |
| 127 | + // Destructuring - automatically generated componentN() functions corresponding to the properties in their order of declaration. |
| 128 | + println("\n=== Destructuring: ===") |
| 129 | + val (name, age, email) = person1 |
| 130 | + println("Destructured: name=$name, age=$age, email=$email") |
| 131 | + // Output: Destructured: name=Alice, age=30, [email protected] |
| 132 | + |
| 133 | + // You can also use componentN() functions directly |
| 134 | + println("name: ${person1.component1()}") |
| 135 | + println("age: ${person1.component2()}") |
| 136 | + println("email: ${person1.component3()}") |
| 137 | + // Output: |
| 138 | + // name: Alice |
| 139 | + // age: 30 |
| 140 | + |
| 141 | +} |
0 commit comments