Skip to content

Commit

Permalink
add more prints
Browse files Browse the repository at this point in the history
  • Loading branch information
forax committed Jan 11, 2020
1 parent c95674a commit 83ef837
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 45 deletions.
29 changes: 18 additions & 11 deletions chapter08-lambda.jsh
Expand Up @@ -7,9 +7,10 @@
// # Lambda and Method reference
// Java unlike JavaScript or Python, don't let you pass a method as argument of a method
// without ceremony

// Let say i want to write a method that do either the sum of an array of values or the sum of their square,
// it can write if that way
int sumOf(int[] array, boolean squareSum) {
int sumOf(boolean squareSum, int... array) {
var sum = 0;
for(var value: array) {
if (squareSum) {
Expand All @@ -20,9 +21,10 @@ int sumOf(int[] array, boolean squareSum) {
}
return sum;
}
System.out.println(sumOf(true, 1, 2, 3));

// but you every values of the array, squareSum will have the same value so it's equivalent to write
int sumOf(int[] array, boolean squareSum) {
int sumOf(boolean squareSum, int... array) {
var sum = 0;
if (squareSum) {
for(var value: array) {
Expand All @@ -35,13 +37,14 @@ int sumOf(int[] array, boolean squareSum) {
}
return sum;
}
System.out.println(sumOf(true, 1, 2, 3));

// and at that point, you have code duplication.
// Usually testing a condition in the middle of a computation is a code smell.
// There is a way to solve that, it's to take the part of the computation that change as parameter
// so sumOf instead of a boolean that take a function as parameter more or less like this
/*
int sumOf(int[] array, ??? function) {
int sumOf(??? function, int... array) {
var sum = 0;
for(var value: array) {
sum = sum + function(value);
Expand All @@ -58,8 +61,7 @@ int sumOf(int[] array, ??? function) {
interface Fun {
int apply(int value);
}

int sumOf(int[] array, Fun function) {
int sumOf(Fun function, int[] array) {
var sum = 0;
for(var value: array) {
sum = sum + function.apply(value);
Expand All @@ -69,19 +71,21 @@ int sumOf(int[] array, Fun function) {

// then using the lambda syntax we have seeing in the previous chapter sumOf can be called
var array = new int[] { 1, 2, 3 };
System.out.println(sumOf(array, x -> x));
System.out.println(sumOf(array, x -> x * x));
System.out.println(sumOf(x -> x, array));
System.out.println(sumOf(x -> x * x, array));


// ## Package java.util.function

// because it's not convenient to have to declare an interface every times you want to send
// Because it's not convenient to have to declare an interface every times you want to send
// a function as parameter, Java already provides a bunch of interfaces in the package
// java.lang.function, so you often don't have to write your own
// Moreover most interface also have variant for primitive types

import java.util.function.*;

// java.lang.Runnable is equivalent to () -> void
Runnable runnable = () -> { System.out.println("hello"); }
Runnable runnable = () -> { System.out.println("hello"); };
runnable.run();

// Supplier<T> is equivalent to () -> T
Expand Down Expand Up @@ -114,7 +118,7 @@ System.out.println(fun.apply("function"));

// IntFunction<T>, LongFunction<T> and DoubleFunction<T>
IntFunction<String[]> arrayCreator = size -> new String[size];
System.out.println(arrayCreator.apply(0));
System.out.println(arrayCreator.apply(5).length);

// ToIntFunction<T>, ToLongFunction<T> and ToDoubleFunction<T>
ToIntFunction<String> stringLength = s -> s.length();
Expand Down Expand Up @@ -152,16 +156,19 @@ System.out.println(binaryOp.applyAsInt(40, 2));
// - with 1 parameter: x -> expression
// - with 2 or more parameters: (a, b) -> expression
DoubleUnaryOperator op = x -> 2.0 * x;
System.out.println(op.applyAsDouble(2));

// instead of an expression, you can have statements between curly braces
DoubleUnaryOperator op = x -> {
return 2.0 * x;
};
System.out.println(op.applyAsDouble(2));

// The types of the parameters are optional so you can declare them or not
// if you don't declare them the parameter types of the abstract method
// of the interface are used
DoubleUnaryOperator op = (double x) -> 2.0 * x;
System.out.println(op.applyAsDouble(2));


// ## Method references
Expand Down Expand Up @@ -202,7 +209,7 @@ System.out.println(factory.apply("John"));

// Same as above, the return type is the array.
IntFunction<String[]> arrayCreator = String[]::new;
System.out.println(arrayCreator.apply(2));
System.out.println(arrayCreator.apply(2).length);

// A frequent error is to think that String::length is a reference
// to a static method because the syntax is close to String.length()
Expand Down
33 changes: 20 additions & 13 deletions guide/chapter08-lambda.md
Expand Up @@ -4,10 +4,11 @@ if you have not read the previous chapter on interfaces, starts by it first
# Lambda and Method reference
Java unlike JavaScript or Python, don't let you pass a method as argument of a method
without ceremony

Let say i want to write a method that do either the sum of an array of values or the sum of their square,
it can write if that way
```java
int sumOf(int[] array, boolean squareSum) {
int sumOf(boolean squareSum, int... array) {
var sum = 0;
for(var value: array) {
if (squareSum) {
Expand All @@ -18,11 +19,12 @@ int sumOf(int[] array, boolean squareSum) {
}
return sum;
}
System.out.println(sumOf(true, 1, 2, 3));
```

but you every values of the array, squareSum will have the same value so it's equivalent to write
```java
int sumOf(int[] array, boolean squareSum) {
int sumOf(boolean squareSum, int... array) {
var sum = 0;
if (squareSum) {
for(var value: array) {
Expand All @@ -35,6 +37,7 @@ int sumOf(int[] array, boolean squareSum) {
}
return sum;
}
System.out.println(sumOf(true, 1, 2, 3));
```

and at that point, you have code duplication.
Expand All @@ -43,7 +46,7 @@ There is a way to solve that, it's to take the part of the computation that chan
so sumOf instead of a boolean that take a function as parameter more or less like this
```java
/*
int sumOf(int[] array, ??? function) {
int sumOf(??? function, int... array) {
var sum = 0;
for(var value: array) {
sum = sum + function(value);
Expand All @@ -62,10 +65,7 @@ Here my interface is a function that takes an int and return an int so
interface Fun {
int apply(int value);
}
```

```java
int sumOf(int[] array, Fun function) {
int sumOf(Fun function, int[] array) {
var sum = 0;
for(var value: array) {
sum = sum + function.apply(value);
Expand All @@ -77,21 +77,25 @@ int sumOf(int[] array, Fun function) {
then using the lambda syntax we have seeing in the previous chapter sumOf can be called
```java
var array = new int[] { 1, 2, 3 };
System.out.println(sumOf(array, x -> x));
System.out.println(sumOf(array, x -> x * x));
System.out.println(sumOf(x -> x, array));
System.out.println(sumOf(x -> x * x, array));
```


## Package java.util.function

because it's not convenient to have to declare an interface every times you want to send
Because it's not convenient to have to declare an interface every times you want to send
a function as parameter, Java already provides a bunch of interfaces in the package
java.lang.function, so you often don't have to write your own
Moreover most interface also have variant for primitive types

```java
import java.util.function.*;
```

java.lang.Runnable is equivalent to () -> void
```java
Runnable runnable = () -> { System.out.println("hello"); }
Runnable runnable = () -> { System.out.println("hello"); };
runnable.run();
```

Expand Down Expand Up @@ -140,7 +144,7 @@ System.out.println(fun.apply("function"));
IntFunction<T>, LongFunction<T> and DoubleFunction<T>
```java
IntFunction<String[]> arrayCreator = size -> new String[size];
System.out.println(arrayCreator.apply(0));
System.out.println(arrayCreator.apply(5).length);
```

ToIntFunction<T>, ToLongFunction<T> and ToDoubleFunction<T>
Expand Down Expand Up @@ -194,20 +198,23 @@ Lambda syntax is similar to arrow part the switch syntax
- with 2 or more parameters: (a, b) -> expression
```java
DoubleUnaryOperator op = x -> 2.0 * x;
System.out.println(op.applyAsDouble(2));
```

instead of an expression, you can have statements between curly braces
```java
DoubleUnaryOperator op = x -> {
return 2.0 * x;
};
System.out.println(op.applyAsDouble(2));
```

The types of the parameters are optional so you can declare them or not
if you don't declare them the parameter types of the abstract method
of the interface are used
```java
DoubleUnaryOperator op = (double x) -> 2.0 * x;
System.out.println(op.applyAsDouble(2));
```


Expand Down Expand Up @@ -258,7 +265,7 @@ System.out.println(factory.apply("John"));
Same as above, the return type is the array.
```java
IntFunction<String[]> arrayCreator = String[]::new;
System.out.println(arrayCreator.apply(2));
System.out.println(arrayCreator.apply(2).length);
```

A frequent error is to think that String::length is a reference
Expand Down
48 changes: 27 additions & 21 deletions jupyter/chapter08-lambda.ipynb
Expand Up @@ -14,15 +14,21 @@
{
"cell_type": "markdown",
"metadata": {},
"source": ["# Lambda and Method reference \n", "Java unlike JavaScript or Python, don't let you pass a method as argument of a method\n", "without ceremony\n", "Let say i want to write a method that do either the sum of an array of values or the sum of their square,\n", "it can write if that way\n"]
"source": ["# Lambda and Method reference \n", "Java unlike JavaScript or Python, don't let you pass a method as argument of a method\n", "without ceremony\n"]
}
,
{
"cell_type": "markdown",
"metadata": {},
"source": ["Let say i want to write a method that do either the sum of an array of values or the sum of their square,\n", "it can write if that way\n"]
}
,
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["int sumOf(int[] array, boolean squareSum) {\n", " var sum = 0;\n", " for(var value: array) {\n", " if (squareSum) {\n", " sum = sum + value * value;\n", " } else {\n", " sum = sum + value;\n", " }\n", " }\n", " return sum;\n", "}\n"]
"source": ["int sumOf(boolean squareSum, int... array) {\n", " var sum = 0;\n", " for(var value: array) {\n", " if (squareSum) {\n", " sum = sum + value * value;\n", " } else {\n", " sum = sum + value;\n", " }\n", " }\n", " return sum;\n", "}\n", "System.out.println(sumOf(true, 1, 2, 3));\n"]
}
,
{
Expand All @@ -36,7 +42,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["int sumOf(int[] array, boolean squareSum) {\n", " var sum = 0;\n", " if (squareSum) {\n", " for(var value: array) {\n", " sum = sum + value * value;\n", " }\n", " } else {\n", " for(var value: array) {\n", " sum = sum + value;\n", " }\n", " }\n", " return sum;\n", "}\n"]
"source": ["int sumOf(boolean squareSum, int... array) {\n", " var sum = 0;\n", " if (squareSum) {\n", " for(var value: array) {\n", " sum = sum + value * value;\n", " }\n", " } else {\n", " for(var value: array) {\n", " sum = sum + value;\n", " }\n", " }\n", " return sum;\n", "}\n", "System.out.println(sumOf(true, 1, 2, 3));\n"]
}
,
{
Expand All @@ -50,7 +56,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["/*\n", "int sumOf(int[] array, ??? function) {\n", " var sum = 0;\n", " for(var value: array) {\n", " sum = sum + function(value);\n", " }\n", " return sum;\n", "}\n", "*/\n"]
"source": ["/*\n", "int sumOf(??? function, int... array) {\n", " var sum = 0;\n", " for(var value: array) {\n", " sum = sum + function(value);\n", " }\n", " return sum;\n", "}\n", "*/\n"]
}
,
{
Expand All @@ -64,15 +70,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["interface Fun {\n", " int apply(int value);\n", "}\n"]
}
,
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["int sumOf(int[] array, Fun function) {\n", " var sum = 0;\n", " for(var value: array) {\n", " sum = sum + function.apply(value);\n", " }\n", " return sum;\n", "}\n"]
"source": ["interface Fun {\n", " int apply(int value);\n", "}\n", "int sumOf(Fun function, int[] array) {\n", " var sum = 0;\n", " for(var value: array) {\n", " sum = sum + function.apply(value);\n", " }\n", " return sum;\n", "}\n"]
}
,
{
Expand All @@ -86,7 +84,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["var array = new int[] { 1, 2, 3 };\n", "System.out.println(sumOf(array, x -> x));\n", "System.out.println(sumOf(array, x -> x * x));\n"]
"source": ["var array = new int[] { 1, 2, 3 };\n", "System.out.println(sumOf(x -> x, array));\n", "System.out.println(sumOf(x -> x * x, array));\n"]
}
,
{
Expand All @@ -98,7 +96,15 @@
{
"cell_type": "markdown",
"metadata": {},
"source": ["because it's not convenient to have to declare an interface every times you want to send\n", "a function as parameter, Java already provides a bunch of interfaces in the package\n", "java.lang.function, so you often don't have to write your own\n", "Moreover most interface also have variant for primitive types \n"]
"source": ["Because it's not convenient to have to declare an interface every times you want to send\n", "a function as parameter, Java already provides a bunch of interfaces in the package\n", "java.lang.function, so you often don't have to write your own\n", "Moreover most interface also have variant for primitive types \n"]
}
,
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["import java.util.function.*;\n"]
}
,
{
Expand All @@ -112,7 +118,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["Runnable runnable = () -> { System.out.println(\"hello\"); }\n", "runnable.run();\n"]
"source": ["Runnable runnable = () -> { System.out.println(\"hello\"); };\n", "runnable.run();\n"]
}
,
{
Expand Down Expand Up @@ -224,7 +230,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["IntFunction<String[]> arrayCreator = size -> new String[size];\n", "System.out.println(arrayCreator.apply(0));\n"]
"source": ["IntFunction<String[]> arrayCreator = size -> new String[size];\n", "System.out.println(arrayCreator.apply(5).length);\n"]
}
,
{
Expand Down Expand Up @@ -336,7 +342,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["DoubleUnaryOperator op = x -> 2.0 * x;\n"]
"source": ["DoubleUnaryOperator op = x -> 2.0 * x;\n", "System.out.println(op.applyAsDouble(2));\n"]
}
,
{
Expand All @@ -350,7 +356,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["DoubleUnaryOperator op = x -> {\n", " return 2.0 * x;\n", " };\n"]
"source": ["DoubleUnaryOperator op = x -> {\n", " return 2.0 * x;\n", " };\n", "System.out.println(op.applyAsDouble(2));\n"]
}
,
{
Expand All @@ -364,7 +370,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["DoubleUnaryOperator op = (double x) -> 2.0 * x;\n"]
"source": ["DoubleUnaryOperator op = (double x) -> 2.0 * x;\n", "System.out.println(op.applyAsDouble(2));\n"]
}
,
{
Expand Down Expand Up @@ -470,7 +476,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["IntFunction<String[]> arrayCreator = String[]::new;\n", "System.out.println(arrayCreator.apply(2));\n"]
"source": ["IntFunction<String[]> arrayCreator = String[]::new;\n", "System.out.println(arrayCreator.apply(2).length);\n"]
}
,
{
Expand Down

0 comments on commit 83ef837

Please sign in to comment.