Skip to content

Commit 435c72c

Browse files
authored
Merge branch 'main' into feat/is-palindrome
2 parents 067c55f + a9098f1 commit 435c72c

File tree

9 files changed

+344
-9
lines changed

9 files changed

+344
-9
lines changed

.github/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ newIssueWelcomeComment: >
44
We're glad to have you with us!
55
66
newPRWelcomeComment: >
7-
🚀 Thanks for your PR great to have you here!
7+
🚀 Thanks for your PR, great to have you here!
88
99
We’ll review it shortly. Stay awesome! 💪
1010
1111
firstPRMergeComment: >
12-
🎉 Your first PR is merged welcome aboard!
12+
🎉 Your first PR is merged - welcome aboard!
1313
14-
Thanks for contributing we’d love to see you again. 💜
14+
Thanks for contributing, we’d love to see you again. 💜

build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
2-
kotlin("jvm") version "2.2.0"
3-
id("org.jlleitschuh.gradle.ktlint") version "13.0.0"
2+
kotlin("jvm") version "2.2.10"
3+
id("org.jlleitschuh.gradle.ktlint") version "13.1.0"
44
}
55

66
repositories {
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package codecollection.algorithms
22

3-
import java.util.Collections
4-
53
fun selectionSort(list: List<Int>): List<Int> {
64
if (list.size <= 1) return list
75
val result = list.toMutableList()
@@ -10,7 +8,7 @@ fun selectionSort(list: List<Int>): List<Int> {
108
for (j in i + 1 until result.size) {
119
if (result[j] < result[minIndex]) minIndex = j
1210
}
13-
if (minIndex != i) Collections.swap(result, minIndex, i)
11+
if (minIndex != i) result[minIndex] = result[i].also { result[i] = result[minIndex] }
1412
}
1513
return result
1614
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# 🛠️ Kotlin Features
2+
3+
This package contains examples of **Kotlin features**.
4+
5+
Each feature is implemented in its own file and is tested with a corresponding unit test - keeping the code clean, minimal, and easy to understand.
6+
7+
Whether you're learning, referencing, or contributing - this collection is for you.
8+
9+
---
10+
11+
## 🗂️ Available Features
12+
13+
| Feature Name | Description | File |
14+
|-----------------------|----------------------------|--------------------------------|
15+
| Data classes | Kotlin data class features | [`DataClass.kt`](DataClass.kt) |
16+
| _...more coming soon_ |
17+
18+
---
19+
20+
## 🙌 Want to Help?
21+
22+
- Check out the [issues labeled `type: kotlinfeature`](https://github.com/e5LA/kotlin-code-collection/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22type%3A%20kotlinfeature%22)
23+
- Or submit your own idea as new [Issue](https://github.com/e5LA/kotlin-code-collection/issues/new)!
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package codecollection.snippets.numbers
2+
3+
fun isEven(n: Int): Boolean = n % 2 == 0

src/main/kotlin/codecollection/snippets/numbers/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ Each snippet is implemented as an extension function or utility method, and test
1111
| File | Description |
1212
|----------------------------------|---------------------------------------|
1313
| [`DigitCount.kt`](DigitCount.kt) | Returns the number of digits in an integer |
14-
| _More coming soon..._ | |
14+
| [`IsEven.kt`](IsEven.kt) | Returns true if the given numberis Even |
15+
| _More coming soon..._ | |
1516

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package codecollection.kotlinfeatures
2+
3+
import kotlin.test.Test
4+
import kotlin.test.assertEquals
5+
import kotlin.test.assertNotEquals
6+
import kotlin.test.assertNotSame
7+
import kotlin.test.assertNull
8+
import kotlin.test.assertSame
9+
import kotlin.test.assertTrue
10+
11+
class DataClassTest {
12+
val person1 = Person(firstName = "Alice", age = 30, email = "[email protected]")
13+
val person2 = Person(firstName = "Bob", age = 32, email = "[email protected]")
14+
val person3 = Person(firstName = "Alice", age = 30, email = "[email protected]")
15+
16+
val mutablePerson = MutablePerson("Charlie", 35, "[email protected]")
17+
18+
val address = Address("New York", "Washington Street")
19+
20+
val employee1 = Employee("Developer", person1, address)
21+
val employeeDefault = Employee(person = person1, address = address)
22+
23+
@Test
24+
fun `should create person with correct properties`() {
25+
assertEquals("Alice", person1.firstName)
26+
assertEquals(30, person1.age)
27+
assertEquals("[email protected]", person1.email)
28+
}
29+
30+
@Test
31+
fun `toString() should return formatted string`() {
32+
assertEquals(
33+
"Person(firstName=Alice, age=30, [email protected])",
34+
person1.toString(),
35+
)
36+
}
37+
38+
@Test
39+
fun `equals should work correctly for same content`() {
40+
assertEquals(person1, person3)
41+
assertNotEquals(person1, person2)
42+
}
43+
44+
@Test
45+
fun `hashCode should be same for equal objects`() {
46+
assertEquals(person1.hashCode(), person3.hashCode())
47+
assertNotEquals(person1.hashCode(), person2.hashCode())
48+
}
49+
50+
@Test
51+
fun `should work correctly in hashset`() {
52+
val peopleSet = hashSetOf(person1, person2)
53+
assertTrue(peopleSet.contains(person1))
54+
assertTrue(peopleSet.contains(person2))
55+
assertTrue(peopleSet.contains(person3))
56+
assertEquals(2, peopleSet.size)
57+
}
58+
59+
@Test
60+
fun `should work correctly in hashmap`() {
61+
val salary =
62+
hashMapOf(
63+
person1 to 30000,
64+
person2 to 27000,
65+
)
66+
assertEquals(30000, salary[person1])
67+
assertEquals(27000, salary[person2])
68+
assertEquals(30000, salary[person3])
69+
assertEquals(2, salary.size)
70+
}
71+
72+
@Test
73+
fun `mutation var properties should break hashmap key`() {
74+
val testMap = hashMapOf(mutablePerson to "Developer")
75+
assertEquals("Developer", testMap[mutablePerson])
76+
mutablePerson.age = 36
77+
assertNull(testMap[mutablePerson])
78+
}
79+
80+
@Test
81+
fun `mutation var properties should change hashCode()`() {
82+
val originalHashCode = mutablePerson.hashCode()
83+
mutablePerson.age = 36
84+
val newHashCode = mutablePerson.hashCode()
85+
assertNotEquals(originalHashCode, newHashCode)
86+
}
87+
88+
@Test
89+
fun `copy() should create new instance with identical properties`() {
90+
val copy = person1.copy()
91+
assertEquals(person1, copy)
92+
assertNotSame(person1, copy)
93+
}
94+
95+
@Test
96+
fun `copy() should create new instance with updated properties`() {
97+
val updated = person1.copy(email = "[email protected]")
98+
assertEquals(person1.firstName, updated.firstName)
99+
assertEquals(person1.age, updated.age)
100+
assertEquals("[email protected]", updated.email)
101+
assertEquals("[email protected]", person1.email)
102+
}
103+
104+
@Test
105+
fun `copy() should perform shallow copy of reference types`() {
106+
val employee2 = employee1.copy()
107+
108+
assertNotSame(employee1, employee2)
109+
assertSame(employee1.person, employee2.person)
110+
assertSame(employee1.address, employee2.address)
111+
}
112+
113+
@Test
114+
fun `mutation of referenced objects should affect the original and its copy`() {
115+
val employee2 = employee1.copy()
116+
employee2.address.street = "Park Avenue"
117+
assertEquals("Park Avenue", employee1.address.street)
118+
assertEquals("Park Avenue", employee2.address.street)
119+
}
120+
121+
@Test
122+
fun `should use default value when not specified`() {
123+
assertEquals("Intern", employeeDefault.position)
124+
}
125+
126+
@Test
127+
fun `copy() use default value`() {
128+
val copiedEmployee = employeeDefault.copy()
129+
assertEquals("Intern", copiedEmployee.position)
130+
}
131+
132+
@Test
133+
fun `destructuring should work correctly`() {
134+
val (name, age, email) = person1
135+
assertEquals("Alice", name)
136+
assertEquals(30, age)
137+
assertEquals("[email protected]", email)
138+
}
139+
140+
@Test
141+
fun `componentN() should work correctly`() {
142+
assertEquals("Alice", person1.component1())
143+
assertEquals(30, person1.component2())
144+
assertEquals("[email protected]", person1.component3())
145+
}
146+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package codecollection.snippets.numbers
2+
3+
import kotlin.test.Test
4+
import kotlin.test.assertFalse
5+
import kotlin.test.assertTrue
6+
7+
class IsEvenTest {
8+
9+
@Test
10+
fun `should return true for even numbers`() {
11+
assertTrue(isEven(0))
12+
assertTrue(isEven(2))
13+
assertTrue(isEven(-4))
14+
assertTrue(isEven(100))
15+
}
16+
17+
@Test
18+
fun `should return false for odd numbers`() {
19+
assertFalse(isEven(1))
20+
assertFalse(isEven(-3))
21+
assertFalse(isEven(99))
22+
}
23+
}

0 commit comments

Comments
 (0)