20

JDD2014: Real life lambdas - Peter Lawrey

  • Upload
    proidea

  • View
    138

  • Download
    4

Embed Size (px)

DESCRIPTION

After working with lambdas for the last 5 months, from a code base originally written in C#, a number of real life patterns and anti-patterns have become apparent. What are some of the common patterns we used, and what are some patterns which needed to be avoided?

Citation preview

Page 1: JDD2014: Real life lambdas - Peter Lawrey
Page 2: JDD2014: Real life lambdas - Peter Lawrey

Introduction

For the last 6 months, Higher Frequency Trading has been porting a legacy C# application with over 25K lines of code to Java.

We have translated many LINQ statements into Java 8 Stream + Lambda.

What are some common patterns and anti-patterns we have seen?

Page 3: JDD2014: Real life lambdas - Peter Lawrey

Contains 2.0

if (list.stream().anyMatch(p -> p.getType() == Type.Cash)) {

Page 4: JDD2014: Real life lambdas - Peter Lawrey

Deep Copy

List<Position> newPositions = classPos.stream()

.map(Position::clone)

.collect(toList())

Page 5: JDD2014: Real life lambdas - Peter Lawrey

Validate all entries

positions.forEach(Position::validate);

Validate throws an InvalidStateException if invalid

Page 6: JDD2014: Real life lambdas - Peter Lawrey

Summing BigDecimal

BigDecimal sum = getResults().stream()

.reduce(BigDecimal.ZERO,

(bd, t) -> bd.add(t.getRequirement()),

BigDecimal::add);

Page 7: JDD2014: Real life lambdas - Peter Lawrey

Sorting by multiple fields

setTrades(getTrades().stream()

.sorted(comparing(t -> t.getInfo().getDate())

.thenComparing(Position::getCUSIP)

.thenComparing(Position::getQuantity).reversed())

.collect(Collectors.toList()));

Page 8: JDD2014: Real life lambdas - Peter Lawrey

Group By

Map<String, List<Position>> positionBySymbol =

positions.values().stream()

.filter(p -> p.getQuantity() != 0)

.collect(groupingBy(Position::getSymbol));

Page 9: JDD2014: Real life lambdas - Peter Lawrey

Streaming Maps

pos.entrySet().stream()

.filter(p -> p.getValue().getQuantity() != 0.0)

.forEach(p -> pos2.put(p.getKey(), p.getValue()));

Page 10: JDD2014: Real life lambdas - Peter Lawrey

To collect or not (anti-pattern)

getTrades().stream()

.filter(t -> getDate().equals(t.getInfo().getDate()))

.collect(toList())

.forEach(t -> trades.add(t.getInfo()));

Page 11: JDD2014: Real life lambdas - Peter Lawrey

To collect or not (solution)

List<Trade> trades = getTrades().stream()

.filter(t -> getDate().equals(t.getInfo().getDate()))

.map(t → t.getInfo())

.collect(Collectors.toList());

Page 12: JDD2014: Real life lambdas - Peter Lawrey

Sort of sorted (anti pattern)

Map<Date, List<Trade>> groupTrades =

trades.stream()

.sorted(comparing(Trade::getDate))

.collect(groupingBy(Trade::getDate));

Page 13: JDD2014: Real life lambdas - Peter Lawrey

Sort of sorted (solution)

Map<Date, List<Trade>> groupTrades =

trades.stream()

.collect(groupingBy(

TradeDetail::getTradeDate,

TreeMap::new,

toList()));

Page 14: JDD2014: Real life lambdas - Peter Lawrey

Multi-sorted (anti-pattern)

return trade.stream()

.filter(t -> !isExcluded(t))

.sorted(comparing(Trade::getDate))

.sorted(comparing(Trade::getCUSIP))

.sorted(comparing(Trade::getNetAmount))

.collect(toList());

Page 15: JDD2014: Real life lambdas - Peter Lawrey

Multi-sorted (solution)

return trade.stream()

.filter(t -> !isExcluded(t))

.sorted(comparing(Trade::getNetAmount)

.thenComparing(Trade::getCUSIP)

.thenComparing(Trade::getDate))

.collect(toList());

Page 16: JDD2014: Real life lambdas - Peter Lawrey

Top twenty words (Ugly)

List<String> words =

Files.lines(path).parallel()

.flatMap(line -> Arrays.asList(line.split("\\b")).stream())

.collect(groupingBy(w -> w, counting()))

.entrySet().stream()

.sorted(comparing(Map.Entry<String, Long>::getValue).reversed())

.limit(20)

.map(Map.Entry::getKey)

.collect(Collectors.toList());

Page 17: JDD2014: Real life lambdas - Peter Lawrey

I must use streams (Ugly)

combinedList.addAll(

balances.stream().collect(Collectors.toList()));

List<Trade> allTrades = new ArrayList<>();

trades1.forEach(t -> allTrades.add(t));

trades2.forEach(t -> allTrades.add(t));

Page 18: JDD2014: Real life lambdas - Peter Lawrey

Optional denial

Position todayPos = newPos.stream()

.filter(pos -> pos.getCUSIP().equals(p.getCUSIP()))

.findFirst().orElse(null);

if (todayPos != null) {

Page 19: JDD2014: Real life lambdas - Peter Lawrey

Optional denial

Optional<MTrade> otodayTrade = trades.stream()

.filter(t -> t.getCUSIP().equals(p.getCUSIP())).findFirst();

MTrade todayTrade = null;

if (otodayTrade.isPresent()) todayTrade = otodayTrade.get();

if (todayTrade != null && todayTrade.getClosingPrice() != null) {

Page 20: JDD2014: Real life lambdas - Peter Lawrey

Q & A

Peter Lawrey

http://vanillajava.blogspot.com/

@PeterLawrey

[email protected]