Dwa lata z "funkcyjną" Javą 8

Created by Bartek Kuczyński / @koziolek

Java 8

Co się zmieniło?

Język

API

A w praktyce?

Język

API

Sposób pisania kodu

Problemy

Problemy z API

Java Date and Time

JavaFX

Problemy z API - Rozwiązania

Samodzielna implementacja

Dużo samodzielnej zabawy

PoC dla biznesu

Problemy z Językiem(?)

Zmiana składni - lambdy, referencje

Dobre i złe praktyki


Stream<Invoice> invoiceStream = service.updateInvoices(id,
                    new Function<Invoice, Invoice>() {
	@Override
	public Invoice apply(Invoice i) {
		i.setTotal(i.getTotal() + 1);
		return i;
	}
});
                

Stream<Invoice> invoiceStream = service.updateInvoices(id,
                    i-> {
		                i.setTotal(i.getTotal() + 1);
		                return i;
                    }
});
                

Problemy z Językiem - rzeczywiste

Java to nie Scala

Java nie jest Funkcyjna

Brakuje pewnych podstaw

Problemy z ludźmi

Zmiana składni - lambdy, referencje

Słaba znajomość całości API

Zalety

API

Jest lepsze - naprawiono błędy

Nowe wygodniejsze elementy

Język

Mniej baroku

Wymusił zmianę myślenia

Ludzie

Zainteresowanie FP

Nowe narzędzia → nowe możliwości

Kilka przykładów

Wszystkie przykłady pochodzą z kodu który w jakiś sposób popełniłem

Można się śmiać


Stream<Invoice> invoiceStream = service.updateInvoices(id,
                    i-> {
		                i.setTotal(i.getTotal() + 1);
		                return i;
                    }
});
                

Stream<Invoice> invoiceStream = service.updateInvoices(id,
    i -> new Invoice(i.getId(), i.getCustomer(), i.getTotal() + 1)
);
                

@Transactional
public Stream<Invoice> updateInvoices(Long id,
                    Function<Invoice, Invoice> updater) {
	return Optional.ofNullable(dao.findOne(id))
			.map(Customer::getInvoices)
			.orElseGet(Collections::emptyList)
			.stream()
			.map(updater
                    .andThen(invoiceDao::saveAndFlush)
            );
}
                

Optional<Invoice> one = Optional.ofNullable(dao.findOne(id));
if(one.isPresent()){
	// pewna logika
}
return one;
                

Optional<Invoice> one = Optional.ofNullable(dao.findOne(id));
one.ifPresent(i-> /*pewna logika*/);
return one;
                

invoices.stream()
		.filter(notNull)
		.filter(notOlderThan)
		.filter(lessThan)
		.map(asB2bInvoice)
		.map(fvM)
		.reduce(summary);
                

invoices.stream()
		.filter(notNull.and(notOlderThan).and(lessThan))
		.map(asB2bInvoice.andThen(fvM))
		.reduce(summary);
                

for(Invoice i : invoices){
    // 300 linii kodu
}
                

invoices.foreach(i-> {
    // 300 linii kodu
});
                

invoices.stream()
		.map(i -> {
			someOtherService.call(i.getCustomer());
			i.getItems().stream()
					.map(it->{
				}).reduce(partialItemSummary);
		})
		.reduce(itemSummary);
                

invoices.stream(
		.peek(i -> someOtherService.call(i.getCustomer())
		.flatMap(i -> i.getItems().stream())
		.reduce(itemSummary)
                

Podsumowanie

O czym nie powiedziałem?

Javaslang

Reactive

Testowanie

Myślenie FP

Q&A