Skip to content

Commit c01f7df

Browse files
committed
examples added
1 parent dd4e385 commit c01f7df

File tree

21 files changed

+476
-7
lines changed

21 files changed

+476
-7
lines changed

build.gradle

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
buildscript {
22
ext {
3-
kotlinVersion = '1.1.1'
3+
kotlinVersion = '1.1.3-2'
44
}
55
repositories {
66
mavenCentral()
77
}
88
dependencies {
99
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
10-
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
11-
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
1210
}
1311
}
1412

@@ -22,4 +20,4 @@ repositories {
2220

2321
dependencies {
2422
compile("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
25-
}
23+
}

gradle.properties

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
version=0.0.1-SNAPSHOT
2-
group=org.codetome.examples.javatokotlin
3-
kotlin.incremental=true
1+
version=1.0.0
2+
group=org.codetome.kotlin.examples
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.codetome.kotlin.examples.data;
2+
3+
import java.util.Objects;
4+
5+
6+
/**
7+
* A plain old java object with all the boilerplate.
8+
*/
9+
public class HexagonValueObject {
10+
11+
private final int x;
12+
private final int y;
13+
private final int z;
14+
15+
public HexagonValueObject(int x, int y, int z) {
16+
this.x = x;
17+
this.y = y;
18+
this.z = z;
19+
}
20+
21+
public int getX() {
22+
return x;
23+
}
24+
25+
public int getY() {
26+
return y;
27+
}
28+
29+
public int getZ() {
30+
return z;
31+
}
32+
33+
@Override
34+
public boolean equals(Object o) {
35+
if (this == o) return true;
36+
if (o == null || getClass() != o.getClass()) return false;
37+
HexagonValueObject hexagon = (HexagonValueObject) o;
38+
return getX() == hexagon.getX() &&
39+
getY() == hexagon.getY() &&
40+
getZ() == hexagon.getZ();
41+
}
42+
43+
@Override
44+
public int hashCode() {
45+
return Objects.hash(getX(), getY(), getZ());
46+
}
47+
48+
@Override
49+
public String toString() {
50+
return "HexagonValueObject{" +
51+
"x=" + x +
52+
", y=" + y +
53+
", z=" + z +
54+
'}';
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.codetome.kotlin.examples.exceptions;
2+
3+
import java.io.BufferedReader;
4+
import java.io.FileReader;
5+
import java.io.IOException;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
/**
10+
* Old school IO in java. Note the try with resources block!
11+
*/
12+
public class JavaLineLoader {
13+
14+
public List<String> loadLines(String path) {
15+
List<String> lines = new ArrayList<>();
16+
try(BufferedReader br = new BufferedReader(new FileReader(path))) {
17+
String line;
18+
while((line = br.readLine()) != null) {
19+
lines.add(line);
20+
}
21+
} catch (IOException e) {
22+
e.printStackTrace();
23+
}
24+
return lines;
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.codetome.kotlin.examples.extensions;
2+
3+
import java.util.AbstractList;
4+
import java.util.List;
5+
import java.util.stream.Collectors;
6+
7+
/**
8+
* Writing decorators in java is cumbersome and they are not perfect.
9+
* In this case you can't implement `List` because it would need you to
10+
* implement a lot of other methods so you have to extend `AbstractList`.
11+
*
12+
* If you need to decorate something which does not provide useful base
13+
* classes like `AbstractList` or is a `final` class you are out of luck.
14+
*/
15+
public class ListPresenterDecorator<T> extends AbstractList<T> {
16+
17+
private List<T> list;
18+
19+
public ListPresenterDecorator(List<T> list) {
20+
this.list = list;
21+
}
22+
23+
public String present() {
24+
return list.stream()
25+
.map(Object::toString)
26+
.collect(Collectors.joining(", "));
27+
}
28+
29+
@Override
30+
public T get(int index) {
31+
return list.get(index);
32+
}
33+
34+
@Override
35+
public int size() {
36+
return list.size();
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.codetome.kotlin.examples.fp;
2+
3+
import java.util.List;
4+
import java.util.Set;
5+
import java.util.stream.Collectors;
6+
7+
public class JavaUser {
8+
9+
static class Address {
10+
String city;
11+
12+
public String getCity() {
13+
return city;
14+
}
15+
}
16+
17+
private final String firstName;
18+
private final String lastName;
19+
private final List<Address> addresses;
20+
21+
public JavaUser(String firstName, String lastName, List<Address> addresses) {
22+
this.firstName = firstName;
23+
this.lastName = lastName;
24+
this.addresses = addresses;
25+
}
26+
27+
/**
28+
* Using the Stream API data transformation is rather easy.
29+
*/
30+
public static Set<String> fetchCitiesOfUsers(List<JavaUser> users) {
31+
return users.stream()
32+
.flatMap(user -> user.addresses.stream())
33+
.map(JavaUser.Address::getCity)
34+
.collect(Collectors.toSet());
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.codetome.kotlin.examples.inference;
2+
3+
import java.util.List;
4+
5+
public class JavaUser {
6+
7+
static class Address {
8+
String city;
9+
}
10+
11+
private final String firstName;
12+
private final String lastName;
13+
private final List<Address> addresses;
14+
15+
public JavaUser(String firstName, String lastName, List<Address> addresses) {
16+
this.firstName = firstName;
17+
this.lastName = lastName;
18+
this.addresses = addresses;
19+
}
20+
21+
public Address getFirstAddress() {
22+
Address firstAddress = addresses.get(0);
23+
return firstAddress;
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.codetome.kotlin.examples.interop;
2+
3+
public class KotlinInterop {
4+
5+
public void helloJava() {
6+
System.out.println("Hello from Java!");
7+
}
8+
9+
public void helloKotlin() {
10+
JavaInterop.createInstance().helloKotlin();
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.codetome.kotlin.examples.lambdas;
2+
3+
import java.util.List;
4+
import java.util.stream.Collectors;
5+
6+
public class JavaFilterOperation {
7+
8+
private List<String> items;
9+
10+
/**
11+
* Since there is no syntax for method parameter types
12+
* we have to create an interface for it.
13+
*/
14+
@FunctionalInterface
15+
interface FilterOperation {
16+
Boolean filter(String element);
17+
}
18+
19+
/**
20+
* The method which takes a function looks like this.
21+
* Note that we could use `Function<String, Boolean>` here but
22+
* it only works for functions with one parameter!
23+
*/
24+
private List<String> filterBy(FilterOperation fn) {
25+
return items.stream()
26+
.filter(fn::filter) // applying the function
27+
.collect(Collectors.toList());
28+
}
29+
30+
public void doFilter() {
31+
filterBy((element) -> {
32+
return element.length() > 0; // calling the function with an actual lambda
33+
});
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.codetome.kotlin.examples.nullsafety;
2+
3+
import java.util.List;
4+
5+
/**
6+
* Checking for `null` values involves a lot of boolean expressions and
7+
* a lot of boilerplate.
8+
* You can work around this with the `Optional` class but what if the
9+
* reference to an `Optional` is `null`?
10+
*/
11+
public class JavaUser {
12+
13+
static class Address {
14+
String city;
15+
}
16+
17+
private final String firstName;
18+
private final String lastName;
19+
private final List<Address> addresses;
20+
21+
public JavaUser(String firstName, String lastName, List<Address> addresses) {
22+
this.firstName = firstName;
23+
this.lastName = lastName;
24+
this.addresses = addresses;
25+
}
26+
27+
public static String getFirstCity(JavaUser user) {
28+
if(user != null && user.addresses != null && !user.addresses.isEmpty()) {
29+
for(Address address : user.addresses) {
30+
if(address.city != null) {
31+
return address.city;
32+
}
33+
}
34+
}
35+
throw new IllegalArgumentException("This User has no cities!");
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.codetome.kotlin.examples.strings;
2+
3+
/**
4+
* String manipulation in java is painful.
5+
* It can be alleviated by using `String.format` but
6+
* it will still remain painful.
7+
*/
8+
public class JavaUser {
9+
private final String name;
10+
private final int age;
11+
12+
public JavaUser(String name, int age) {
13+
this.name = name;
14+
this.age = age;
15+
}
16+
17+
public String toHumanReadableFormat() {
18+
return "JavaUser{" +
19+
"name='" + name + '\'' +
20+
", age=" + age +
21+
'}';
22+
}
23+
24+
public String toHumanReadableFormatWithStringFormat() {
25+
return String.format("JavaUser{name='%s', age=%s}", name, age);
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.codetome.kotlin.examples.data
2+
3+
/**
4+
* Data classes in Kotlin give you
5+
* - equals + hashCode and
6+
* - toString in addition to
7+
* - getters and setters.
8+
* You can also `copy` them.
9+
*/
10+
data class HexagonDataClass(val x: Int, val y: Int, val z: Int)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.codetome.kotlin.examples.exceptions
2+
3+
import java.io.File
4+
5+
class KotlinLineLoader {
6+
7+
/**
8+
* Kotlin does away with checked exceptions *and*
9+
* it also adds commonly used functionality to existing
10+
* java classes (like `readLines` here).
11+
*/
12+
fun loadLines(path: String) = File(path).readLines()
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.codetome.kotlin.examples.extensions
2+
3+
/**
4+
* This method acts as a decorator for all `List`s.
5+
* Compared to the java alternative this one-liner is much simpler.
6+
*/
7+
fun <T> List<T>.present() = this.joinToString(", ")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.codetome.kotlin.examples.fp
2+
3+
data class KotlinUser(val firstName: String,
4+
val lastName: String,
5+
val addresses: List<Address> = listOf()) {
6+
7+
data class Address(val city: String)
8+
9+
companion object {
10+
11+
/**
12+
* The differences from Java are rather subtle here:
13+
* - There is no explicit conversion to streams since all Kotlin
14+
* collections support it out of the box
15+
* - Not having to pass a lambda to `flatMap` here is a direct
16+
* consequence of this
17+
* - Collecting the result is also automatic (no need for
18+
* `Collectors.to*` method calls. We only had to use `toSet`
19+
* here because we want to return a `Set`
20+
*/
21+
fun fetchCitiesOfUsers(users: List<KotlinUser>) = users
22+
.flatMap(KotlinUser::addresses)
23+
.map(Address::city)
24+
.toSet()
25+
}
26+
27+
}

0 commit comments

Comments
 (0)