Commit 0a0ee97a authored by François Sarradin's avatar François Sarradin
Browse files

2017-01-12 session @ Ippon - IppDej

parents
# Created by .ignore support plugin (hsz.mobi)
### Java template
*.class
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
target
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea
*.iws
*.iml
## Plugin-specific files:
# IntelliJ
/out/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Découverte de la programmation fonctionnelle
François Sarradin
Manager Technique Capitalisation
Ippon Technologies
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.ippon</groupId>
<artifactId>java8fp</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.javaslang</groupId>
<artifactId>javaslang</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>io.javaslang</groupId>
<artifactId>javaslang-test</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package fr.ippon.java8fp;
import javaslang.collection.List;
import java.util.ArrayList;
public class IncreaseMain {
static java.util.List<Double> increase(List<Double> salaries) {
java.util.List<Double> newSalaries = new ArrayList<>();
for (Double salary : salaries) {
newSalaries.add(salary * 1.02);
}
return newSalaries;
}
public static void main(String[] args) {
List<Double> salaries = List.of(1000.0, 2000.0, 3000.0, 5000.0);
java.util.List<Double> result = increase(salaries);
System.out.println(result);
salaries
.map(salary -> salary * 1.02)
.forEach(System.out::println);
}
}
package fr.ippon.java8fp;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public class LambdaMain {
static List<User> users = Arrays.asList(
new User("John Doe", new Address("1 avenue de la Porte, Ankh-Morpork")),
new User("Marc Steans", new Address("23 rue du Merle, Ankh-Morpork")),
new User("Carol Leigh", new Address("5 boulevard de Marroniers, Ankh-Morpork"))
);
static class Address {
final String data;
Address(String data) {
this.data = data;
}
public String getData() {
return data;
}
@Override
public String toString() {
return "Address: " + data;
}
}
static class User {
final String name;
final Address address;
User(String name, Address address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public Address getAddress() {
return address;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", address=" + address +
'}';
}
}
public static void main(String[] args) throws Exception {
User user = new User("John Doe", new Address("1 avenue de la Porte, Ankh-Morpork"));
System.out.println(user.getAddress());
Function<User, Address> getAddress = User::getAddress;
System.out.println(getAddress.apply(user));
Thread t = new Thread(() -> System.out.println("hello"));
t.start();
t.join();
}
}
package fr.ippon.java8fp;
import javaslang.collection.Iterator;
import javaslang.collection.List;
import javaslang.collection.Stream;
import javaslang.control.Option;
import javaslang.control.Try;
public class RetryMain {
static void process(String s) {
System.out.println("s = " + s);
Integer value = Integer.valueOf(s);
System.out.println("value = " + value);
}
public static void main(String[] args) {
List<String> values = List.of("a", "b", "c", "s42", "e", "f");
Iterator<String> iterator = values.iterator();
Stream<String> s = values.toStream();
s.forEach(System.out::println);
s.forEach(System.out::println);
// Stream<Try<Void>> tries = Stream.continually(() -> Try.<Void>of(() -> {
// process(iterator.next());
// return null;
// }))
// .take(5);
//
// Option<Try<Void>> result =
// tries
// .find(Try::isSuccess)
// .orElse(tries::lastOption);
//
// System.out.println(result);
// Stream<Try<Void>> result =
// Stream.continually(() ->
// Try.<Void>of(() -> {
// process(iterator.next());
// return null;
// }))
// .takeUntil(Try::isSuccess)
// .take(5)
// ;
//
// result.toList().forEach(System.out::println);
}
}
package fr.ippon.java8fp;
import javaslang.collection.Map;
import javaslang.collection.Stream;
import javaslang.collection.Traversable;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.regex.Pattern;
public class TextAnalysisMain {
static final String URL = "http://www.gutenberg.org/cache/epub/5781/pg5781.txt";
static final String FILENAME = "src/main/resources/legrandmeaulnes.txt";
public static void main(String[] args) throws Exception {
Pattern separators = Pattern.compile("[\\s.,;:!?()\\[\\]{}\"'-/]+");
// InputStream netStream = new URL(URL).openStream();
// Stream<String> lines = new BufferedReader(new InputStreamReader(netStream)).lines();
Stream<String> lines = Files.lines(Paths.get(FILENAME))
.collect(Stream.collector())
.drop(91)
.take(7770);
Map<String, Integer> occurences = lines
.flatMap(line -> separators.splitAsStream(line).collect(Stream.collector()))
.map(String::toLowerCase)
.filter(word -> word.length() >= 15)
.groupBy(word -> word)
.mapValues(Stream::size);
occurences
.toList()
.sortBy(t -> t._2)
.forEach(System.out::println);
}
}
package fr.ippon.java8fp.bank;
import java.util.Objects;
public class Account {
public final String id;
public final String owner;
public final Double balance;
public Account(String id, String owner, Double balance) {
this.id = id;
this.owner = owner;
this.balance = balance;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Account account = (Account) o;
return Objects.equals(id, account.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "Account{" +
"id='" + id + '\'' +
", owner='" + owner + '\'' +
", balance=" + balance +
'}';
}
}
package fr.ippon.java8fp.bank;
import javaslang.collection.List;
import javaslang.control.Option;
import javaslang.control.Try;
public class BankMain {
public static void main(String[] args) {
List<String> accountIds = List.of(
"WFRHH",
"YJSE4",
"7FZXD",
"F6HWS",
"G2HDS",
"R5NSZ"
);
BankServiceAdapter bankService = new BankServiceAdapter(new BankServiceImpl());
accountIds
.map(bankService::getAccount)
.forEach(System.out::println);
}
static class BankServiceAdapter {
private final BankService bankService;
public BankServiceAdapter(BankService bankService) {
this.bankService = bankService;
}
public Try<Account> getAccount(String id) {
Account account = bankService.getAccount(id);
return Option.of(account).toTry(() -> new IllegalArgumentException(id));
}
}
}
package fr.ippon.java8fp.bank;
public interface BankService {
Account getAccount(String id);
}
package fr.ippon.java8fp.bank;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
public class BankServiceImpl implements BankService {
private final Map<String, Account> accounts = new HashMap<>();
private final Iterator<Double> randomBalance =
new Random()
.doubles(100.0, 5000.0)
.map(b -> Math.round(b * 100.0) / 100.0)
.iterator();
private final Iterator<Boolean> acceptIds =
new Random()
.ints(0, 100)
.mapToObj(i -> i >= 20)
.iterator();
private Double generateBalance() {
return randomBalance.next();
}
private Boolean acceptId() {
return acceptIds.next();
}
@Override
public Account getAccount(String id) {
if (!accounts.containsKey(id)) {
if (acceptId()) {
Account account = new Account(id, "John Doe", generateBalance());
accounts.put(id, account);
}
else {
return null;
}
}
return accounts.get(id);
}
}
package fr.ippon.java8fp.hlist;
class HCons<H, T extends HList> extends HList {
public final H head;
public final T tail;
public HCons(H head, T tail) {
this.head = head;
this.tail = tail;
}
@Override
public <U> HCons<U, HCons<H, T>> add(U head) {
return new HCons<>(head, this);
}
@Override
public HList reverse() {
return null;
}
@Override
public String toString() {
return head.toString() + " :: " + tail.toString();
}
}
package fr.ippon.java8fp.hlist;
abstract class HList {
public abstract <T> HCons<T, ? extends HList> add(T head);
public abstract HList reverse();
}
package fr.ippon.java8fp.hlist;
public class HLists {
public static final HNil hnil = new HNil();
public static <H, T extends HList> HCons<H, T> hcons(H head, T tail) {
return new HCons<>(head, tail);
}
public static void main(String[] args) {
HCons<Integer, HCons<String, HCons<Double, HNil>>> list1 =
hcons(1, hcons("hello", hcons(2.0, hnil)));
HCons<Integer, HCons<String, HCons<Double, HNil>>> list2 = hnil.add(2.0).add("hello").add(1);
System.out.println(list1);
System.out.println(list2);
}
}
package fr.ippon.java8fp.hlist;
class HNil extends HList {
@Override
public <T> HCons<T, HNil> add(T head) {
return new HCons<>(head, this);
}
@Override
public HList reverse() {
return this;
}
@Override
public String toString() {
return "HNil";
}
}
package fr.ippon.java8fp.parser;
public class Input {
public final static char EOS = '\u001a';
public final String source;
public final int offset;
public Input(String source, int offset) {
this.source = source;
this.offset = offset;
}
public boolean atEnd() {
return offset >= source.length();
}
public char first() {
if (atEnd()) return EOS;
return source.charAt(offset);
}
public Input rest() {
if (atEnd()) return this;
return new Input(source, offset + 1);
}
public Input drop(int n) {
return new Input(source, offset + n);
}
}
package fr.ippon.java8fp.parser;
import javaslang.Function1;
import javaslang.Function2;
abstract class ParseResult<T> {
public final Input input;
private ParseResult(Input input) {
this.input = input;
}
public abstract T get();
public <U> ParseResult<U> map(Function1<T, U> f) {
return flatMap((v, input) -> new Success<U>(f.apply(v), input));
}
public abstract <U> ParseResult<U> flatMap(Function2<T, Input, ParseResult<U>> f);
public abstract ParseResult<T> or(ParseResult<T> result);
public static class Success<T> extends ParseResult<T> {
public final T value;
public Success(T value, Input input) {
super(input);
this.value = value;
}
@Override
public T get() {
return value;
}
@Override
public <U> ParseResult<U> flatMap(Function2<T, Input, ParseResult<U>> f) {
return f.apply(value, input);
}
@Override
public ParseResult<T> or(ParseResult<T> result) {
return this;
}
}
public static class Failure<T> extends ParseResult<T>