package com.github.java8.lambdasinaction.chap14; import java.util.function.Consumer; public class PersistentTrainJourney { public static void main(String[] args) { TrainJourney tj1 = new TrainJourney(40, new TrainJourney(30, null)); TrainJourney tj2 = new TrainJourney(20, new TrainJourney(50, null)); TrainJourney appended = append(tj1, tj2); visit(appended, tj -> { System.out.print(tj.price + " - "); }); System.out.println(); // A new TrainJourney is created without altering tj1 and tj2. TrainJourney appended2 = append(tj1, tj2); visit(appended2, tj -> { System.out.print(tj.price + " - "); }); System.out.println(); // tj1 is altered but it's still not visible in the results. TrainJourney linked = link(tj1, tj2); visit(linked, tj -> { System.out.print(tj.price + " - "); }); System.out.println(); // ... but here, if this code is uncommented, tj2 will be appended // at the end of the already altered tj1. This will cause a // StackOverflowError from the endless visit() recursive calls on // the tj2 part of the twice altered tj1. /*TrainJourney linked2 = link(tj1, tj2); visit(linked2, tj -> { System.out.print(tj.price + " - "); }); System.out.println();*/ } static class TrainJourney { public int price; public TrainJourney onward; public TrainJourney(int p, TrainJourney t) { price = p; onward = t; } } static TrainJourney link(TrainJourney a, TrainJourney b) { if (a == null) { return b; } TrainJourney t = a; while (t.onward != null) { t = t.onward; } t.onward = b; return a; } static TrainJourney append(TrainJourney a, TrainJourney b) { return a == null ? b : new TrainJourney(a.price, append(a.onward, b)); } static void visit(TrainJourney journey, Consumer<TrainJourney> c) { if (journey != null) { c.accept(journey); visit(journey.onward, c); } } }