[{"data":1,"prerenderedAt":4121},["ShallowReactive",2],{"item-lessons-light-ch22-the-builder-pattern":3,"item-examples-light-ch22-the-builder-pattern":444,"item-exercises-light-ch22-the-builder-pattern":753,"item-lesson-full-ch22-the-builder-pattern-22":1070,"item-example-full-ch22-the-builder-pattern-22":1772,"item-exercise-full-ch22-the-builder-pattern-22":2593},[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,284,288,292,296,300,304,308,312,316,320,324,328,332,336,340,344,348,352,356,360,364,368,372,376,380,384,388,392,396,400,404,408,412,416,420,424,428,432,436,440],{"path":5,"title":6,"stem":7},"\u002Fshockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1-why-java-for-frc","Why Java for FRC?","shockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1.1-why-java-for-frc",{"path":9,"title":10,"stem":11},"\u002Fshockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers","shockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":13,"title":14,"stem":15},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":17,"title":18,"stem":19},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":21,"title":22,"stem":23},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":25,"title":26,"stem":27},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":29,"title":30,"stem":31},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":33,"title":34,"stem":35},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":37,"title":38,"stem":39},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":41,"title":42,"stem":43},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":45,"title":46,"stem":47},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":49,"title":50,"stem":51},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":53,"title":54,"stem":55},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":57,"title":58,"stem":59},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":61,"title":62,"stem":63},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":65,"title":66,"stem":67},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":69,"title":70,"stem":71},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","Control Structures: if Statements & For Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":73,"title":74,"stem":75},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":77,"title":78,"stem":79},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":81,"title":82,"stem":83},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":85,"title":86,"stem":87},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":89,"title":90,"stem":91},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":93,"title":94,"stem":95},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":97,"title":98,"stem":99},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":101,"title":102,"stem":103},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws)","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":105,"title":106,"stem":107},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F8-while-loops","While Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.8-while-loops",{"path":109,"title":110,"stem":111},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":113,"title":114,"stem":115},"\u002Fshockwave-curriculum\u002Flessons\u002Fch06-strings\u002F1-strings","Strings","shockwave-curriculum\u002Flessons\u002Fch06-strings\u002F6.1-strings",{"path":117,"title":118,"stem":119},"\u002Fshockwave-curriculum\u002Flessons\u002Fch06-strings\u002F2-string-algorithms","String Algorithms","shockwave-curriculum\u002Flessons\u002Fch06-strings\u002F6.2-string-algorithms",{"path":121,"title":122,"stem":123},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","The Class Blueprint","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":125,"title":126,"stem":127},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":129,"title":130,"stem":131},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":133,"title":134,"stem":135},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":137,"title":138,"stem":139},"\u002Fshockwave-curriculum\u002Flessons\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\"","shockwave-curriculum\u002Flessons\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":141,"title":142,"stem":143},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":145,"title":146,"stem":147},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":149,"title":150,"stem":151},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":153,"title":154,"stem":155},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":157,"title":158,"stem":159},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":161,"title":162,"stem":163},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":165,"title":166,"stem":167},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":169,"title":170,"stem":171},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":173,"title":174,"stem":175},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":177,"title":178,"stem":179},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":181,"title":182,"stem":183},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":185,"title":186,"stem":187},"\u002Fshockwave-curriculum\u002Flessons\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices","shockwave-curriculum\u002Flessons\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":189,"title":190,"stem":191},"\u002Fshockwave-curriculum\u002Flessons\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch","shockwave-curriculum\u002Flessons\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":193,"title":194,"stem":195},"\u002Fshockwave-curriculum\u002Flessons\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas","shockwave-curriculum\u002Flessons\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":197,"title":198,"stem":199},"\u002Fshockwave-curriculum\u002Flessons\u002Fch14-why-design-patterns\u002F14-why-design-patterns","Why Design Patterns?","shockwave-curriculum\u002Flessons\u002Fch14-why-design-patterns\u002F14-why-design-patterns",{"path":201,"title":202,"stem":203},"\u002Fshockwave-curriculum\u002Flessons\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap)","shockwave-curriculum\u002Flessons\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":205,"title":206,"stem":207},"\u002Fshockwave-curriculum\u002Flessons\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics","shockwave-curriculum\u002Flessons\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":209,"title":210,"stem":211},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":213,"title":214,"stem":215},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":217,"title":218,"stem":219},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":221,"title":222,"stem":223},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":225,"title":226,"stem":227},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":229,"title":230,"stem":231},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":233,"title":234,"stem":235},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":237,"title":238,"stem":239},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":241,"title":242,"stem":243},"\u002Fshockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts","shockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":245,"title":246,"stem":247},"\u002Fshockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References","shockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":249,"title":250,"stem":251},"\u002Fshockwave-curriculum\u002Flessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern","shockwave-curriculum\u002Flessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":253,"title":254,"stem":255},"\u002Fshockwave-curriculum\u002Flessons\u002Fch21-static-factories\u002F21-static-factories","Static Factories","shockwave-curriculum\u002Flessons\u002Fch21-static-factories\u002F21-static-factories",{"path":257,"title":258,"stem":259},"\u002Fshockwave-curriculum\u002Flessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern","shockwave-curriculum\u002Flessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":261,"title":262,"stem":263},"\u002Fshockwave-curriculum\u002Flessons\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability","shockwave-curriculum\u002Flessons\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":265,"title":266,"stem":267},"\u002Fshockwave-curriculum\u002Flessons\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions","shockwave-curriculum\u002Flessons\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":269,"title":270,"stem":271},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming?","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":273,"title":274,"stem":275},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":277,"title":278,"stem":279},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":281,"title":282,"stem":283},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":285,"title":286,"stem":287},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":289,"title":290,"stem":291},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":293,"title":294,"stem":295},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":297,"title":298,"stem":299},"\u002Fshockwave-curriculum\u002Flessons\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways","shockwave-curriculum\u002Flessons\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":301,"title":302,"stem":303},"\u002Fshockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design","shockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":305,"title":306,"stem":307},"\u002Fshockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F2-impact-of-program-design","Impact of Program Design","shockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F27.2-impact-of-program-design",{"path":309,"title":310,"stem":311},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":313,"title":314,"stem":315},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":317,"title":318,"stem":319},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":321,"title":322,"stem":323},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",{"path":325,"title":326,"stem":327},"\u002Fshockwave-curriculum\u002Flessons\u002Fch29-git-and-github-basics\u002F1-coming-soon","Git & GitHub Basics — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch29-git-and-github-basics\u002F29.1-coming-soon",{"path":329,"title":330,"stem":331},"\u002Fshockwave-curriculum\u002Flessons\u002Fch30-git-history-and-merging\u002F1-coming-soon","Git — History & Merging — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch30-git-history-and-merging\u002F30.1-coming-soon",{"path":333,"title":334,"stem":335},"\u002Fshockwave-curriculum\u002Flessons\u002Fch31-dev-environment-and-tooling\u002F1-coming-soon","Dev Environment & Tooling — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch31-dev-environment-and-tooling\u002F31.1-coming-soon",{"path":337,"title":338,"stem":339},"\u002Fshockwave-curriculum\u002Flessons\u002Fch32-unit-testing\u002F1-coming-soon","Unit Testing — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch32-unit-testing\u002F32.1-coming-soon",{"path":341,"title":342,"stem":343},"\u002Fshockwave-curriculum\u002Flessons\u002Fch33-advantagekit-autologging\u002F1-coming-soon","AdvantageKit — AutoLogging — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch33-advantagekit-autologging\u002F33.1-coming-soon",{"path":345,"title":346,"stem":347},"\u002Fshockwave-curriculum\u002Flessons\u002Fch34-log-replay\u002F1-coming-soon","Log Replay — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch34-log-replay\u002F34.1-coming-soon",{"path":349,"title":350,"stem":351},"\u002Fshockwave-curriculum\u002Flessons\u002Fch35-advantagescope-i-visualization\u002F1-coming-soon","AdvantageScope I: Visualization — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch35-advantagescope-i-visualization\u002F35.1-coming-soon",{"path":353,"title":354,"stem":355},"\u002Fshockwave-curriculum\u002Flessons\u002Fch36-advantagescope-ii-custom-3d-assets\u002F1-coming-soon","AdvantageScope II: Custom 3D Assets — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch36-advantagescope-ii-custom-3d-assets\u002F36.1-coming-soon",{"path":357,"title":358,"stem":359},"\u002Fshockwave-curriculum\u002Flessons\u002Fch37-autonomous-i\u002F1-coming-soon","Autonomous I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch37-autonomous-i\u002F37.1-coming-soon",{"path":361,"title":362,"stem":363},"\u002Fshockwave-curriculum\u002Flessons\u002Fch38-autonomous-ii-pathplanner-and-trajectories\u002F1-coming-soon","Autonomous II: PathPlanner & Trajectories — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch38-autonomous-ii-pathplanner-and-trajectories\u002F38.1-coming-soon",{"path":365,"title":366,"stem":367},"\u002Fshockwave-curriculum\u002Flessons\u002Fch39-control-fundamentals\u002F1-coming-soon","Control Fundamentals — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch39-control-fundamentals\u002F39.1-coming-soon",{"path":369,"title":370,"stem":371},"\u002Fshockwave-curriculum\u002Flessons\u002Fch40-motion-profiles\u002F1-coming-soon","Motion Profiles — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch40-motion-profiles\u002F40.1-coming-soon",{"path":373,"title":374,"stem":375},"\u002Fshockwave-curriculum\u002Flessons\u002Fch41-hardware-fundamentals\u002F1-coming-soon","Hardware Fundamentals — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch41-hardware-fundamentals\u002F41.1-coming-soon",{"path":377,"title":378,"stem":379},"\u002Fshockwave-curriculum\u002Flessons\u002Fch42-photonvision\u002F1-coming-soon","PhotonVision — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch42-photonvision\u002F42.1-coming-soon",{"path":381,"title":382,"stem":383},"\u002Fshockwave-curriculum\u002Flessons\u002Fch43-apriltags-and-pose\u002F1-coming-soon","AprilTags & Pose — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch43-apriltags-and-pose\u002F43.1-coming-soon",{"path":385,"title":386,"stem":387},"\u002Fshockwave-curriculum\u002Flessons\u002Fch44-subsystems-i\u002F1-coming-soon","Subsystems I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch44-subsystems-i\u002F44.1-coming-soon",{"path":389,"title":390,"stem":391},"\u002Fshockwave-curriculum\u002Flessons\u002Fch45-subsystems-ii-advanced\u002F1-coming-soon","Subsystems II — Advanced — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch45-subsystems-ii-advanced\u002F45.1-coming-soon",{"path":393,"title":394,"stem":395},"\u002Fshockwave-curriculum\u002Flessons\u002Fch46-team-utilities-i\u002F1-coming-soon","Team Utilities I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch46-team-utilities-i\u002F46.1-coming-soon",{"path":397,"title":398,"stem":399},"\u002Fshockwave-curriculum\u002Flessons\u002Fch47-field-constants\u002F1-coming-soon","Field Constants — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch47-field-constants\u002F47.1-coming-soon",{"path":401,"title":402,"stem":403},"\u002Fshockwave-curriculum\u002Flessons\u002Fch48-troubleshooting-i-runtime-debug\u002F1-coming-soon","Troubleshooting I — Runtime Debug — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch48-troubleshooting-i-runtime-debug\u002F48.1-coming-soon",{"path":405,"title":406,"stem":407},"\u002Fshockwave-curriculum\u002Flessons\u002Fch49-troubleshooting-ii-can-and-sim\u002F1-coming-soon","Troubleshooting II: CAN & Sim — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch49-troubleshooting-ii-can-and-sim\u002F49.1-coming-soon",{"path":409,"title":410,"stem":411},"\u002Fshockwave-curriculum\u002Flessons\u002Fch50-vendor-libraries-talonfx\u002F1-coming-soon","Vendor Libraries: TalonFX — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch50-vendor-libraries-talonfx\u002F50.1-coming-soon",{"path":413,"title":414,"stem":415},"\u002Fshockwave-curriculum\u002Flessons\u002Fch51-robot-alerts\u002F1-coming-soon","Robot Alerts — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch51-robot-alerts\u002F51.1-coming-soon",{"path":417,"title":418,"stem":419},"\u002Fshockwave-curriculum\u002Flessons\u002Fch52-wpilib-commands\u002F1-coming-soon","WPILib Commands — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch52-wpilib-commands\u002F52.1-coming-soon",{"path":421,"title":422,"stem":423},"\u002Fshockwave-curriculum\u002Flessons\u002Fch53-wpilib-geometry\u002F1-coming-soon","WPILib Geometry — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch53-wpilib-geometry\u002F53.1-coming-soon",{"path":425,"title":426,"stem":427},"\u002Fshockwave-curriculum\u002Flessons\u002Fch54-networktables\u002F1-coming-soon","NetworkTables — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch54-networktables\u002F54.1-coming-soon",{"path":429,"title":430,"stem":431},"\u002Fshockwave-curriculum\u002Flessons\u002Fch55-command-scheduler\u002F1-coming-soon","Command Scheduler — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch55-command-scheduler\u002F55.1-coming-soon",{"path":433,"title":434,"stem":435},"\u002Fshockwave-curriculum\u002Flessons\u002Fch56-wpilib-timers\u002F1-coming-soon","WPILib Timers — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch56-wpilib-timers\u002F56.1-coming-soon",{"path":437,"title":438,"stem":439},"\u002Fshockwave-curriculum\u002Flessons\u002Fch57-wpilib-triggers\u002F1-coming-soon","WPILib Triggers — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch57-wpilib-triggers\u002F57.1-coming-soon",{"path":441,"title":442,"stem":443},"\u002Fshockwave-curriculum\u002Flessons\u002Fch58-vendor-units-and-conversions\u002F1-coming-soon","Vendor Units & Conversions — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch58-vendor-units-and-conversions\u002F58.1-coming-soon",[445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505,509,513,517,521,525,529,533,537,541,545,549,553,557,561,565,569,573,577,581,585,589,593,597,601,605,609,613,617,621,625,629,633,637,641,645,649,653,657,661,665,669,673,677,681,685,689,693,697,701,705,709,713,717,721,725,729,733,737,741,745,749],{"path":446,"title":447,"stem":448},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":450,"title":451,"stem":452},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":454,"title":455,"stem":456},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":458,"title":459,"stem":460},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":462,"title":463,"stem":464},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":466,"title":467,"stem":468},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":470,"title":471,"stem":472},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":474,"title":475,"stem":476},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":478,"title":479,"stem":480},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":482,"title":483,"stem":484},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":486,"title":487,"stem":488},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":490,"title":491,"stem":492},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":494,"title":495,"stem":496},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":498,"title":499,"stem":500},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":502,"title":503,"stem":504},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":506,"title":507,"stem":508},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","if Statements & For Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":510,"title":511,"stem":512},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":514,"title":515,"stem":516},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":518,"title":519,"stem":520},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":522,"title":523,"stem":524},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":526,"title":527,"stem":528},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":530,"title":531,"stem":532},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":534,"title":535,"stem":536},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":538,"title":539,"stem":540},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws) — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":542,"title":543,"stem":544},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F8-while-loops","While Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.8-while-loops",{"path":546,"title":547,"stem":548},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":550,"title":551,"stem":552},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F1-strings","Strings — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F6.1-strings",{"path":554,"title":555,"stem":556},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F2-string-algorithms","String Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F6.2-string-algorithms",{"path":558,"title":559,"stem":560},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","Anatomy of a Java Class — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":562,"title":563,"stem":564},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":566,"title":567,"stem":568},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":570,"title":571,"stem":572},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":574,"title":575,"stem":576},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\" — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":578,"title":579,"stem":580},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":582,"title":583,"stem":584},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":586,"title":587,"stem":588},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":590,"title":591,"stem":592},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":594,"title":595,"stem":596},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":598,"title":599,"stem":600},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":602,"title":603,"stem":604},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":606,"title":607,"stem":608},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":610,"title":611,"stem":612},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":614,"title":615,"stem":616},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":618,"title":619,"stem":620},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":622,"title":623,"stem":624},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":626,"title":627,"stem":628},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":630,"title":631,"stem":632},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":634,"title":635,"stem":636},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap) — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":638,"title":639,"stem":640},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":642,"title":643,"stem":644},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":646,"title":647,"stem":648},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":650,"title":651,"stem":652},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":654,"title":655,"stem":656},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":658,"title":659,"stem":660},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":662,"title":663,"stem":664},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":666,"title":667,"stem":668},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":670,"title":671,"stem":672},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":674,"title":675,"stem":676},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":678,"title":679,"stem":680},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":682,"title":683,"stem":684},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":686,"title":687,"stem":688},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch21-static-factories\u002F21-static-factories","Static Factories — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch21-static-factories\u002F21-static-factories",{"path":690,"title":691,"stem":692},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":694,"title":695,"stem":696},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":698,"title":699,"stem":700},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":702,"title":703,"stem":704},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming? — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":706,"title":707,"stem":708},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":710,"title":711,"stem":712},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":714,"title":715,"stem":716},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":718,"title":719,"stem":720},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":722,"title":723,"stem":724},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":726,"title":727,"stem":728},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":730,"title":731,"stem":732},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":734,"title":735,"stem":736},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":738,"title":739,"stem":740},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":742,"title":743,"stem":744},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":746,"title":747,"stem":748},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":750,"title":751,"stem":752},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",[754,758,762,766,770,774,778,782,786,790,794,798,802,806,810,814,818,822,826,830,834,838,842,846,850,854,858,862,866,870,874,878,882,886,890,894,898,902,906,910,914,918,922,926,930,934,938,942,946,950,954,958,962,966,970,974,978,982,986,990,994,998,1002,1006,1010,1014,1018,1022,1026,1030,1034,1038,1042,1046,1050,1054,1058,1062,1066],{"path":755,"title":756,"stem":757},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers — Exercises","shockwave-curriculum\u002Fexercises\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":759,"title":760,"stem":761},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":763,"title":764,"stem":765},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":767,"title":768,"stem":769},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":771,"title":772,"stem":773},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":775,"title":776,"stem":777},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":779,"title":780,"stem":781},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":783,"title":784,"stem":785},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":787,"title":788,"stem":789},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":791,"title":792,"stem":793},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":795,"title":796,"stem":797},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":799,"title":800,"stem":801},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":803,"title":804,"stem":805},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":807,"title":808,"stem":809},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":811,"title":812,"stem":813},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":815,"title":816,"stem":817},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","if Statements & For Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":819,"title":820,"stem":821},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":823,"title":824,"stem":825},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":827,"title":828,"stem":829},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":831,"title":832,"stem":833},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":835,"title":836,"stem":837},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":839,"title":840,"stem":841},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":843,"title":844,"stem":845},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":847,"title":848,"stem":849},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws) — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":851,"title":852,"stem":853},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F8-while-loops","While Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.8-while-loops",{"path":855,"title":856,"stem":857},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":859,"title":860,"stem":861},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F1-strings","Strings — Exercises","shockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F6.1-strings",{"path":863,"title":864,"stem":865},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F2-string-algorithms","String Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F6.2-string-algorithms",{"path":867,"title":868,"stem":869},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","Anatomy of a Java Class — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":871,"title":872,"stem":873},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":875,"title":876,"stem":877},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":879,"title":880,"stem":881},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":883,"title":884,"stem":885},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\" — Exercises","shockwave-curriculum\u002Fexercises\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":887,"title":888,"stem":889},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":891,"title":892,"stem":893},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":895,"title":896,"stem":897},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":899,"title":900,"stem":901},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":903,"title":904,"stem":905},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":907,"title":908,"stem":909},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":911,"title":912,"stem":913},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":915,"title":916,"stem":917},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":919,"title":920,"stem":921},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":923,"title":924,"stem":925},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":927,"title":928,"stem":929},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":931,"title":932,"stem":933},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices — Exercises","shockwave-curriculum\u002Fexercises\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":935,"title":936,"stem":937},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch — Exercises","shockwave-curriculum\u002Fexercises\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":939,"title":940,"stem":941},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas — Exercises","shockwave-curriculum\u002Fexercises\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":943,"title":944,"stem":945},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch14-why-design-patterns\u002F14-why-design-patterns","Why Design Patterns? — Exercises","shockwave-curriculum\u002Fexercises\u002Fch14-why-design-patterns\u002F14-why-design-patterns",{"path":947,"title":948,"stem":949},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap) — Exercises","shockwave-curriculum\u002Fexercises\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":951,"title":952,"stem":953},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics — Exercises","shockwave-curriculum\u002Fexercises\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":955,"title":956,"stem":957},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":959,"title":960,"stem":961},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":963,"title":964,"stem":965},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":967,"title":968,"stem":969},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":971,"title":972,"stem":973},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":975,"title":976,"stem":977},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":979,"title":980,"stem":981},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":983,"title":984,"stem":985},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":987,"title":988,"stem":989},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts — Exercises","shockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":991,"title":992,"stem":993},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References — Exercises","shockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":995,"title":996,"stem":997},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern — Exercises","shockwave-curriculum\u002Fexercises\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":999,"title":1000,"stem":1001},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch21-static-factories\u002F21-static-factories","Static Factories — Exercises","shockwave-curriculum\u002Fexercises\u002Fch21-static-factories\u002F21-static-factories",{"path":1003,"title":1004,"stem":1005},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern — Exercises","shockwave-curriculum\u002Fexercises\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":1007,"title":1008,"stem":1009},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability — Exercises","shockwave-curriculum\u002Fexercises\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":1011,"title":1012,"stem":1013},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":1015,"title":1016,"stem":1017},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming? — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":1019,"title":1020,"stem":1021},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":1023,"title":1024,"stem":1025},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":1027,"title":1028,"stem":1029},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":1031,"title":1032,"stem":1033},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":1035,"title":1036,"stem":1037},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":1039,"title":1040,"stem":1041},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":1043,"title":1044,"stem":1045},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways — Exercises","shockwave-curriculum\u002Fexercises\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":1047,"title":1048,"stem":1049},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design — Exercises","shockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":1051,"title":1052,"stem":1053},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F2-impact-of-program-design","Impact of Program Design — Exercises","shockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F27.2-impact-of-program-design",{"path":1055,"title":1056,"stem":1057},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":1059,"title":1060,"stem":1061},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":1063,"title":1064,"stem":1065},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":1067,"title":1068,"stem":1069},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",{"id":1071,"title":258,"body":1072,"description":1094,"extension":1766,"meta":1767,"navigation":1256,"path":257,"seo":1770,"stem":259,"__hash__":1771},"lessons\u002Fshockwave-curriculum\u002Flessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern.md",{"type":1073,"value":1074,"toc":1753},"minimark",[1075,1079,1084,1088,1105,1108,1112,1137,1189,1200,1204,1222,1407,1420,1424,1461,1503,1517,1525,1548,1552,1588,1592,1598,1618,1636,1640,1643,1647,1694,1698,1734,1749],[1076,1077,258],"h1",{"id":1078},"the-builder-pattern",[1080,1081,1083],"h2",{"id":1082},"the-problem-constructor-hell","The Problem: \"Constructor Hell\"",[1085,1086,1087],"p",{},"A constructor with many parameters — especially several of the same type, or several optional ones — becomes genuinely hard to read and easy to get wrong:",[1089,1090,1095],"pre",{"className":1091,"code":1092,"language":1093,"meta":1094,"style":1094},"language-java shiki shiki-themes github-light github-dark","Shooter shooter = new Shooter(0.01, 0.0, 0.02, true, 5000.0, 1000.0);\n","java","",[1096,1097,1098],"code",{"__ignoreMap":1094},[1099,1100,1103],"span",{"class":1101,"line":1102},"line",1,[1099,1104,1092],{},[1085,1106,1107],{},"What does each number actually mean? Swap two arguments of the same type by mistake, and the compiler won't catch it — it'll just silently misconfigure the shooter. This is sometimes called \"constructor hell,\" and it gets worse the more optional settings a class has, since a constructor either forces every caller to specify every parameter, or multiplies into a pile of overloads trying to cover every combination.",[1080,1109,1111],{"id":1110},"the-builder-pattern-construct-step-by-step","The Builder Pattern: Construct Step by Step",[1085,1113,1114,1115,1119,1120,1124,1125,1128,1129,1132,1133,1136],{},"The ",[1116,1117,1118],"strong",{},"Builder Pattern"," separates ",[1121,1122,1123],"em",{},"building"," an object from ",[1121,1126,1127],{},"using"," it — a separate ",[1096,1130,1131],{},"Builder"," object collects settings one at a time, through named, chainable methods, then produces the final object only once, via a ",[1096,1134,1135],{},"build()"," call:",[1089,1138,1140],{"className":1091,"code":1139,"language":1093,"meta":1094,"style":1094},"Shooter shooter = new Shooter.Builder()\n    .setKP(0.01)\n    .setKI(0.0)\n    .setKD(0.02)\n    .enableFeedforward(true)\n    .setMaxRPM(5000.0)\n    .setMinRPM(1000.0)\n    .build();\n",[1096,1141,1142,1147,1153,1159,1165,1171,1177,1183],{"__ignoreMap":1094},[1099,1143,1144],{"class":1101,"line":1102},[1099,1145,1146],{},"Shooter shooter = new Shooter.Builder()\n",[1099,1148,1150],{"class":1101,"line":1149},2,[1099,1151,1152],{},"    .setKP(0.01)\n",[1099,1154,1156],{"class":1101,"line":1155},3,[1099,1157,1158],{},"    .setKI(0.0)\n",[1099,1160,1162],{"class":1101,"line":1161},4,[1099,1163,1164],{},"    .setKD(0.02)\n",[1099,1166,1168],{"class":1101,"line":1167},5,[1099,1169,1170],{},"    .enableFeedforward(true)\n",[1099,1172,1174],{"class":1101,"line":1173},6,[1099,1175,1176],{},"    .setMaxRPM(5000.0)\n",[1099,1178,1180],{"class":1101,"line":1179},7,[1099,1181,1182],{},"    .setMinRPM(1000.0)\n",[1099,1184,1186],{"class":1101,"line":1185},8,[1099,1187,1188],{},"    .build();\n",[1085,1190,1191,1192,1195,1196,1199],{},"Every call is now self-documenting — ",[1096,1193,1194],{},".setKP(0.01)"," says exactly what ",[1096,1197,1198],{},"0.01"," means, in a way a bare constructor argument never could.",[1080,1201,1203],{"id":1202},"implementing-a-builder","Implementing a Builder",[1085,1205,1206,1207,1210,1211,1214,1215,1218,1219,1221],{},"The target class (",[1096,1208,1209],{},"Shooter",") gets a ",[1096,1212,1213],{},"private"," constructor — callers can no longer construct it directly, only through the builder — plus a ",[1096,1216,1217],{},"public static"," nested ",[1096,1220,1131],{}," class that collects the settings:",[1089,1223,1225],{"className":1091,"code":1224,"language":1093,"meta":1094,"style":1094},"public class Shooter\n{\n    private final double kP, kI, kD;\n    private final boolean feedforward;\n    private final double maxRPM, minRPM;\n\n    private Shooter(Builder builder)\n    {\n        this.kP = builder.kP;\n        this.kI = builder.kI;\n        this.kD = builder.kD;\n        this.feedforward = builder.feedforward;\n        this.maxRPM = builder.maxRPM;\n        this.minRPM = builder.minRPM;\n    }\n\n    public static class Builder\n    {\n        private double kP = 0, kI = 0, kD = 0;\n        private boolean feedforward = false;\n        private double maxRPM = 0, minRPM = 0;\n\n        public Builder setKP(double kP) { this.kP = kP; return this; }\n        public Builder setKI(double kI) { this.kI = kI; return this; }\n        public Builder setKD(double kD) { this.kD = kD; return this; }\n        public Builder enableFeedforward(boolean ff) { feedforward = ff; return this; }\n        public Builder setMaxRPM(double max) { this.maxRPM = max; return this; }\n        public Builder setMinRPM(double min) { this.minRPM = min; return this; }\n\n        public Shooter build() { return new Shooter(this); }\n    }\n}\n",[1096,1226,1227,1232,1237,1242,1247,1252,1258,1263,1268,1274,1280,1286,1292,1298,1304,1310,1315,1321,1326,1332,1338,1344,1349,1355,1361,1367,1373,1379,1385,1390,1396,1401],{"__ignoreMap":1094},[1099,1228,1229],{"class":1101,"line":1102},[1099,1230,1231],{},"public class Shooter\n",[1099,1233,1234],{"class":1101,"line":1149},[1099,1235,1236],{},"{\n",[1099,1238,1239],{"class":1101,"line":1155},[1099,1240,1241],{},"    private final double kP, kI, kD;\n",[1099,1243,1244],{"class":1101,"line":1161},[1099,1245,1246],{},"    private final boolean feedforward;\n",[1099,1248,1249],{"class":1101,"line":1167},[1099,1250,1251],{},"    private final double maxRPM, minRPM;\n",[1099,1253,1254],{"class":1101,"line":1173},[1099,1255,1257],{"emptyLinePlaceholder":1256},true,"\n",[1099,1259,1260],{"class":1101,"line":1179},[1099,1261,1262],{},"    private Shooter(Builder builder)\n",[1099,1264,1265],{"class":1101,"line":1185},[1099,1266,1267],{},"    {\n",[1099,1269,1271],{"class":1101,"line":1270},9,[1099,1272,1273],{},"        this.kP = builder.kP;\n",[1099,1275,1277],{"class":1101,"line":1276},10,[1099,1278,1279],{},"        this.kI = builder.kI;\n",[1099,1281,1283],{"class":1101,"line":1282},11,[1099,1284,1285],{},"        this.kD = builder.kD;\n",[1099,1287,1289],{"class":1101,"line":1288},12,[1099,1290,1291],{},"        this.feedforward = builder.feedforward;\n",[1099,1293,1295],{"class":1101,"line":1294},13,[1099,1296,1297],{},"        this.maxRPM = builder.maxRPM;\n",[1099,1299,1301],{"class":1101,"line":1300},14,[1099,1302,1303],{},"        this.minRPM = builder.minRPM;\n",[1099,1305,1307],{"class":1101,"line":1306},15,[1099,1308,1309],{},"    }\n",[1099,1311,1313],{"class":1101,"line":1312},16,[1099,1314,1257],{"emptyLinePlaceholder":1256},[1099,1316,1318],{"class":1101,"line":1317},17,[1099,1319,1320],{},"    public static class Builder\n",[1099,1322,1324],{"class":1101,"line":1323},18,[1099,1325,1267],{},[1099,1327,1329],{"class":1101,"line":1328},19,[1099,1330,1331],{},"        private double kP = 0, kI = 0, kD = 0;\n",[1099,1333,1335],{"class":1101,"line":1334},20,[1099,1336,1337],{},"        private boolean feedforward = false;\n",[1099,1339,1341],{"class":1101,"line":1340},21,[1099,1342,1343],{},"        private double maxRPM = 0, minRPM = 0;\n",[1099,1345,1347],{"class":1101,"line":1346},22,[1099,1348,1257],{"emptyLinePlaceholder":1256},[1099,1350,1352],{"class":1101,"line":1351},23,[1099,1353,1354],{},"        public Builder setKP(double kP) { this.kP = kP; return this; }\n",[1099,1356,1358],{"class":1101,"line":1357},24,[1099,1359,1360],{},"        public Builder setKI(double kI) { this.kI = kI; return this; }\n",[1099,1362,1364],{"class":1101,"line":1363},25,[1099,1365,1366],{},"        public Builder setKD(double kD) { this.kD = kD; return this; }\n",[1099,1368,1370],{"class":1101,"line":1369},26,[1099,1371,1372],{},"        public Builder enableFeedforward(boolean ff) { feedforward = ff; return this; }\n",[1099,1374,1376],{"class":1101,"line":1375},27,[1099,1377,1378],{},"        public Builder setMaxRPM(double max) { this.maxRPM = max; return this; }\n",[1099,1380,1382],{"class":1101,"line":1381},28,[1099,1383,1384],{},"        public Builder setMinRPM(double min) { this.minRPM = min; return this; }\n",[1099,1386,1388],{"class":1101,"line":1387},29,[1099,1389,1257],{"emptyLinePlaceholder":1256},[1099,1391,1393],{"class":1101,"line":1392},30,[1099,1394,1395],{},"        public Shooter build() { return new Shooter(this); }\n",[1099,1397,1399],{"class":1101,"line":1398},31,[1099,1400,1309],{},[1099,1402,1404],{"class":1101,"line":1403},32,[1099,1405,1406],{},"}\n",[1085,1408,1409,1412,1413,1416,1417,1419],{},[1096,1410,1411],{},"private final double kP, kI, kD;"," declares three fields of the same type in one statement, separated by commas (Lesson 2.1). Every field here is also ",[1096,1414,1415],{},"final"," — Lesson 23.1 covers ",[1096,1418,1415],{}," fields, methods, and classes in full.",[1080,1421,1423],{"id":1422},"classes-inside-classes-static-nested-classes","Classes Inside Classes: Static Nested Classes",[1085,1425,1426,1428,1429,1432,1433,1435,1436,1439,1440,1443,1444,1447,1448,1451,1452,1454,1455,1457,1458,1460],{},[1096,1427,1131],{}," is written as ",[1096,1430,1431],{},"public static class Builder",", declared entirely inside ",[1096,1434,1209],{},"'s own braces — that's a ",[1116,1437,1438],{},"static nested class",". Its full name is ",[1096,1441,1442],{},"Shooter.Builder",", which is exactly why building one starts with ",[1096,1445,1446],{},"new Shooter.Builder()",". The ",[1096,1449,1450],{},"static"," here means what it always means: a ",[1096,1453,1442],{}," can be created without an existing ",[1096,1456,1209],{}," object around, the same way a ",[1096,1459,1450],{}," method can be called without an existing object.",[1085,1462,1463,1464,1466,1467,1469,1470,1472,1473,1475,1476,1479,1480,1483,1484,1486,1487,1489,1490,1493,1494,1496,1497,1499,1500,1502],{},"Nesting one class inside another also grants both classes a special privilege: ",[1096,1465,1209],{}," and ",[1096,1468,1442],{}," can reach each other's ",[1096,1471,1213],{}," members directly, something no other class could do. That's how the ",[1096,1474,1209],{}," constructor above can read ",[1096,1477,1478],{},"builder.kP"," even though ",[1096,1481,1482],{},"kP"," is ",[1096,1485,1213],{}," inside ",[1096,1488,1131],{}," — and how ",[1096,1491,1492],{},"Builder.build()"," can call ",[1096,1495,1209],{},"'s ",[1096,1498,1213],{}," constructor. Code outside both classes still can't touch either one's ",[1096,1501,1213],{}," fields.",[1085,1504,1505,1506,1509,1510,1513,1514,1516],{},"(Java also has ",[1121,1507,1508],{},"non-static"," nested classes, called ",[1116,1511,1512],{},"inner classes",", where every instance is tied to one specific instance of the outer class — the Builder Pattern only ever needs the ",[1096,1515,1450],{}," kind shown here, so that's the only kind this course covers.)",[1080,1518,1520,1521,1524],{"id":1519},"the-fluent-chain-why-return-this-matters","The Fluent Chain: Why ",[1096,1522,1523],{},"return this;"," Matters",[1085,1526,1527,1528,1530,1531,1533,1534,1536,1537,1540,1541,1543,1544,1547],{},"Every ",[1096,1529,1131],{}," method ends with ",[1096,1532,1523],{}," — returning the same builder object it was just called on. That's exactly what makes chaining possible: each call's result is another ",[1096,1535,1131],{},", ready for the next call in the chain, all the way until ",[1096,1538,1539],{},".build()"," finally produces the real ",[1096,1542,1209],{},". This style (a method call chain, each step returning the object it was called on) is called a ",[1116,1545,1546],{},"fluent interface",".",[1080,1549,1551],{"id":1550},"why-the-result-is-safer-not-just-prettier","Why the Result Is Safer, Not Just Prettier",[1553,1554,1555,1559,1562,1571],"ul",{},[1556,1557,1558],"li",{},"Every setting has a readable name at the call site, instead of an anonymous position in an argument list.",[1556,1560,1561],{},"Optional settings simply aren't called, rather than needing a separate constructor overload for every combination.",[1556,1563,1564,1565,1567,1568,1570],{},"The final object (",[1096,1566,1209],{},") is typically built as immutable — every field is ",[1096,1569,1415],{}," and set exactly once, inside the private constructor, from the builder's already-finished values.",[1556,1572,1573,1575,1576,1579,1580,1583,1584,1587],{},[1096,1574,1135],{}," can also validate before constructing the final object — for example, throwing an ",[1096,1577,1578],{},"IllegalArgumentException"," (Ch.12) if ",[1096,1581,1582],{},"minRPM"," ended up greater than ",[1096,1585,1586],{},"maxRPM"," — instead of quietly handing back a nonsensical configuration.",[1080,1589,1591],{"id":1590},"real-patterns-this-mirrors-in-wpilib","Real Patterns This Mirrors in WPILib",[1085,1593,1594,1595,1597],{},"Several real WPILib classes already use builder-like chaining, even without a nested ",[1096,1596,1131],{}," class:",[1089,1599,1601],{"className":1091,"code":1600,"language":1093,"meta":1094,"style":1094},"TrajectoryConfig config = new TrajectoryConfig(maxVelocity, maxAccel)\n    .setKinematics(driveKinematics)\n    .addConstraint(voltageConstraint);\n",[1096,1602,1603,1608,1613],{"__ignoreMap":1094},[1099,1604,1605],{"class":1101,"line":1102},[1099,1606,1607],{},"TrajectoryConfig config = new TrajectoryConfig(maxVelocity, maxAccel)\n",[1099,1609,1610],{"class":1101,"line":1149},[1099,1611,1612],{},"    .setKinematics(driveKinematics)\n",[1099,1614,1615],{"class":1101,"line":1155},[1099,1616,1617],{},"    .addConstraint(voltageConstraint);\n",[1085,1619,1620,1621,1624,1625,1628,1629,1632,1633,1547],{},"Commands v3 (Ch.25) leans on the same idea even harder — building a ",[1096,1622,1623],{},"Command"," is itself a staged builder chain, where each stage only offers the methods legal to call next: ",[1096,1626,1627],{},"Command.sequence(intake, shoot).named(\"Auto\")"," builds a bigger command out of smaller ones, and ",[1096,1630,1631],{},"Command.requiring(drive, arm).executing(coroutine -> ...).named(\"Reach and Drive\")"," is a builder whose required mechanisms are locked in before you can even call ",[1096,1634,1635],{},".executing(...)",[1080,1637,1639],{"id":1638},"when-not-to-reach-for-a-builder","When Not to Reach for a Builder",[1085,1641,1642],{},"A builder is genuine overhead — a whole extra nested class — that only pays for itself once a constructor's parameter list gets long or has several optional pieces. For a class with 2-3 simple, always-required parameters, a plain constructor (or, per Ch.21, a static factory method) is simpler and should be preferred.",[1080,1644,1646],{"id":1645},"common-pitfalls","Common Pitfalls",[1553,1648,1649,1676,1688],{},[1556,1650,1651,1657,1658,1660,1661,1663,1664,1667,1668,1671,1672,1675],{},[1116,1652,1653,1654,1656],{},"Forgetting ",[1096,1655,1523],{}," in a builder method."," If the method still returns ",[1096,1659,1131],{},", dropping ",[1096,1662,1523],{}," gives a ",[1096,1665,1666],{},"missing return statement"," compile error right there. If its return type was also changed to ",[1096,1669,1670],{},"void",", the error shows up one call later instead: the next call in the chain fails with ",[1096,1673,1674],{},"void cannot be dereferenced",", since there's nothing to call it on.",[1556,1677,1678,1685,1686,1547],{},[1116,1679,1680,1681,1684],{},"Making the target class's constructor ",[1096,1682,1683],{},"public"," alongside the builder."," That defeats the pattern's purpose — callers should only ever construct the object through the builder, which is why the real constructor stays ",[1096,1687,1213],{},[1556,1689,1690,1693],{},[1116,1691,1692],{},"Reaching for a builder on a simple, 2-3-parameter class."," That's exactly the case the pattern isn't meant for — the extra ceremony isn't worth it there.",[1080,1695,1697],{"id":1696},"key-takeaways","Key Takeaways",[1553,1699,1700,1703,1715,1724,1731],{},[1556,1701,1702],{},"The Builder Pattern separates step-by-step construction from a class's actual usage, avoiding \"constructor hell\" (many same-typed or optional parameters).",[1556,1704,1705,1706,1708,1709,1712,1713,1547],{},"A builder is a nested ",[1096,1707,1450],{}," class collecting settings via named, chainable methods (each returning ",[1096,1710,1711],{},"this"," — a fluent interface), finishing with ",[1096,1714,1135],{},[1556,1716,1717,1718,1720,1721,1723],{},"The target class's real constructor is ",[1096,1719,1213],{},", taking the finished builder and copying its values into ",[1096,1722,1415],{}," fields — producing an immutable, safely-configured result.",[1556,1725,1726,1727,1730],{},"Real WPILib classes (",[1096,1728,1729],{},"TrajectoryConfig",") and Commands v3's staged builders (Ch.25) already use this same chaining idea.",[1556,1732,1733],{},"Skip the builder for simple classes with few, always-required parameters — a constructor or static factory (Ch.21) is simpler there.",[1085,1735,1736,1737,1740,1741,1744,1745,1748],{},"Derived from ",[1096,1738,1739],{},"other-reference-repo",": ",[1096,1742,1743],{},"team-5817-training\u002Fdesign-patterns\u002Fbuilder.md"," (T5817 30.1)\n",[1116,1746,1747],{},"Deck context:"," mechacoder-test\u002Fsrc\u002Flessons\u002Fjava-2.js, slide 8 (\"The Builder Pattern\") — MotorConfig fluent-builder example",[1750,1751,1752],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":1094,"searchDepth":1149,"depth":1149,"links":1754},[1755,1756,1757,1758,1759,1761,1762,1763,1764,1765],{"id":1082,"depth":1149,"text":1083},{"id":1110,"depth":1149,"text":1111},{"id":1202,"depth":1149,"text":1203},{"id":1422,"depth":1149,"text":1423},{"id":1519,"depth":1149,"text":1760},"The Fluent Chain: Why return this; Matters",{"id":1550,"depth":1149,"text":1551},{"id":1590,"depth":1149,"text":1591},{"id":1638,"depth":1149,"text":1639},{"id":1645,"depth":1149,"text":1646},{"id":1696,"depth":1149,"text":1697},"md",{"outlineRef":1768,"status":1769},"22 — The Builder Pattern (T5817 30.1)","new — authored lesson (fuller depth than the teaser slide)",{"title":258,"description":1094},"GBcAqVJVGw5OxlN9L281xzfeMbMDwDy-lJxo31HiJac",{"id":1773,"title":691,"body":1774,"description":1094,"extension":1766,"meta":2588,"navigation":1256,"path":690,"seo":2591,"stem":692,"__hash__":2592},"examples\u002Fshockwave-curriculum\u002Fexamples\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern.md",{"type":1073,"value":1775,"toc":2574},[1776,1779,1783,1786,1801,1805,1843,1847,1922,1965,1969,2040,2067,2083,2089,2113,2139,2143,2173,2410,2414,2422,2445,2449,2459,2468,2483,2490,2499,2508,2529,2533,2572],[1076,1777,691],{"id":1778},"the-builder-pattern-worked-example",[1080,1780,1782],{"id":1781},"problem","Problem",[1085,1784,1785],{},"An elevator's configuration has four settings: a maximum height in meters, a gear ratio, whether the motor uses brake mode, and whether the motor direction is inverted. Most elevators use the usual values (1.0 m max, 10:1 gear ratio, brake mode on, not inverted), so callers should only have to mention the settings they're changing. The finished configuration should never change once it's built.",[1085,1787,1788,1789,1792,1793,1796,1797,1800],{},"With a plain constructor this would be ",[1096,1790,1791],{},"new ElevatorConfig(1.4, 10.0, true, true)",": two ",[1096,1794,1795],{},"double","s and two ",[1096,1798,1799],{},"boolean","s in a row, where swapping either pair compiles fine and silently misconfigures the elevator. Build it with the Builder Pattern instead.",[1080,1802,1804],{"id":1803},"step-1-plan-it-first","Step 1: Plan It First",[1806,1807,1808,1821,1827,1836],"ol",{},[1556,1809,1810,1811,1814,1815,1817,1818,1820],{},"Write the target class, ",[1096,1812,1813],{},"ElevatorConfig",", with four ",[1096,1816,1415],{}," fields and a ",[1096,1819,1213],{}," constructor that copies them from a builder.",[1556,1822,1823,1824,1826],{},"Write a nested ",[1096,1825,1431],{}," that holds the same four settings, starting at their usual values.",[1556,1828,1829,1830,1832,1833,1835],{},"Give the builder one chainable method per setting (each ending in ",[1096,1831,1523],{},"), plus a ",[1096,1834,1135],{}," method.",[1556,1837,1838,1839,1842],{},"In ",[1096,1840,1841],{},"main",", build a configuration that changes only two of the four settings.",[1080,1844,1846],{"id":1845},"step-2-the-target-classs-fields-and-private-constructor","Step 2: The Target Class's Fields and Private Constructor",[1089,1848,1850],{"className":1091,"code":1849,"language":1093,"meta":1094,"style":1094},"class ElevatorConfig\n{\n    private final double maxHeightMeters;\n    private final double gearRatio;\n    private final boolean brakeMode;\n    private final boolean inverted;\n\n    private ElevatorConfig(Builder builder)\n    {\n        this.maxHeightMeters = builder.maxHeightMeters;\n        this.gearRatio = builder.gearRatio;\n        this.brakeMode = builder.brakeMode;\n        this.inverted = builder.inverted;\n    }\n}\n",[1096,1851,1852,1857,1861,1866,1871,1876,1881,1885,1890,1894,1899,1904,1909,1914,1918],{"__ignoreMap":1094},[1099,1853,1854],{"class":1101,"line":1102},[1099,1855,1856],{},"class ElevatorConfig\n",[1099,1858,1859],{"class":1101,"line":1149},[1099,1860,1236],{},[1099,1862,1863],{"class":1101,"line":1155},[1099,1864,1865],{},"    private final double maxHeightMeters;\n",[1099,1867,1868],{"class":1101,"line":1161},[1099,1869,1870],{},"    private final double gearRatio;\n",[1099,1872,1873],{"class":1101,"line":1167},[1099,1874,1875],{},"    private final boolean brakeMode;\n",[1099,1877,1878],{"class":1101,"line":1173},[1099,1879,1880],{},"    private final boolean inverted;\n",[1099,1882,1883],{"class":1101,"line":1179},[1099,1884,1257],{"emptyLinePlaceholder":1256},[1099,1886,1887],{"class":1101,"line":1185},[1099,1888,1889],{},"    private ElevatorConfig(Builder builder)\n",[1099,1891,1892],{"class":1101,"line":1270},[1099,1893,1267],{},[1099,1895,1896],{"class":1101,"line":1276},[1099,1897,1898],{},"        this.maxHeightMeters = builder.maxHeightMeters;\n",[1099,1900,1901],{"class":1101,"line":1282},[1099,1902,1903],{},"        this.gearRatio = builder.gearRatio;\n",[1099,1905,1906],{"class":1101,"line":1288},[1099,1907,1908],{},"        this.brakeMode = builder.brakeMode;\n",[1099,1910,1911],{"class":1101,"line":1294},[1099,1912,1913],{},"        this.inverted = builder.inverted;\n",[1099,1915,1916],{"class":1101,"line":1300},[1099,1917,1309],{},[1099,1919,1920],{"class":1101,"line":1306},[1099,1921,1406],{},[1553,1923,1924,1933,1946],{},[1556,1925,1926,1927,1929,1930,1932],{},"Every field is ",[1096,1928,1415],{},", so each is assigned exactly once, in the constructor, and can never change afterward. The finished ",[1096,1931,1813],{}," is immutable.",[1556,1934,1935,1936,1938,1939,1941,1942,1945],{},"The constructor is ",[1096,1937,1213],{},", so code outside ",[1096,1940,1813],{}," can't call ",[1096,1943,1944],{},"new ElevatorConfig(...)",". The only way to get one is through the builder.",[1556,1947,1948,1949,1951,1952,1955,1956,1958,1959,1961,1962,1964],{},"The constructor takes the finished ",[1096,1950,1131],{}," and copies its four values across. It can read ",[1096,1953,1954],{},"builder.maxHeightMeters"," even though that field is ",[1096,1957,1213],{},", because ",[1096,1960,1131],{}," is nested inside ",[1096,1963,1813],{},". Java lets the outer class and its nested class reach each other's private members.",[1080,1966,1968],{"id":1967},"step-3-the-nested-builder","Step 3: The Nested Builder",[1089,1970,1972],{"className":1091,"code":1971,"language":1093,"meta":1094,"style":1094},"public static class Builder\n{\n    private double maxHeightMeters = 1.0;\n    private double gearRatio = 10.0;\n    private boolean brakeMode = true;\n    private boolean inverted = false;\n\n    public Builder setMaxHeightMeters(double max) { this.maxHeightMeters = max; return this; }\n    public Builder setGearRatio(double ratio) { this.gearRatio = ratio; return this; }\n    public Builder setBrakeMode(boolean brake) { this.brakeMode = brake; return this; }\n    public Builder setInverted(boolean inverted) { this.inverted = inverted; return this; }\n\n    public ElevatorConfig build() { return new ElevatorConfig(this); }\n}\n",[1096,1973,1974,1979,1983,1988,1993,1998,2003,2007,2012,2017,2022,2027,2031,2036],{"__ignoreMap":1094},[1099,1975,1976],{"class":1101,"line":1102},[1099,1977,1978],{},"public static class Builder\n",[1099,1980,1981],{"class":1101,"line":1149},[1099,1982,1236],{},[1099,1984,1985],{"class":1101,"line":1155},[1099,1986,1987],{},"    private double maxHeightMeters = 1.0;\n",[1099,1989,1990],{"class":1101,"line":1161},[1099,1991,1992],{},"    private double gearRatio = 10.0;\n",[1099,1994,1995],{"class":1101,"line":1167},[1099,1996,1997],{},"    private boolean brakeMode = true;\n",[1099,1999,2000],{"class":1101,"line":1173},[1099,2001,2002],{},"    private boolean inverted = false;\n",[1099,2004,2005],{"class":1101,"line":1179},[1099,2006,1257],{"emptyLinePlaceholder":1256},[1099,2008,2009],{"class":1101,"line":1185},[1099,2010,2011],{},"    public Builder setMaxHeightMeters(double max) { this.maxHeightMeters = max; return this; }\n",[1099,2013,2014],{"class":1101,"line":1270},[1099,2015,2016],{},"    public Builder setGearRatio(double ratio) { this.gearRatio = ratio; return this; }\n",[1099,2018,2019],{"class":1101,"line":1276},[1099,2020,2021],{},"    public Builder setBrakeMode(boolean brake) { this.brakeMode = brake; return this; }\n",[1099,2023,2024],{"class":1101,"line":1282},[1099,2025,2026],{},"    public Builder setInverted(boolean inverted) { this.inverted = inverted; return this; }\n",[1099,2028,2029],{"class":1101,"line":1288},[1099,2030,1257],{"emptyLinePlaceholder":1256},[1099,2032,2033],{"class":1101,"line":1294},[1099,2034,2035],{},"    public ElevatorConfig build() { return new ElevatorConfig(this); }\n",[1099,2037,2038],{"class":1101,"line":1300},[1099,2039,1406],{},[1553,2041,2042,2045,2054],{},[1556,2043,2044],{},"The builder's fields start at the usual values. A setting nobody changes just keeps its starting value, with no extra constructor overload needed.",[1556,2046,2047,2048,2050,2051,2053],{},"Each setter's return type is ",[1096,2049,1131],{},", and it ends in ",[1096,2052,1523],{},", handing back the same builder it was called on. That's what lets the next call chain straight on.",[1556,2055,2056,2058,2059,2061,2062,2064,2065,1547],{},[1096,2057,1135],{}," passes ",[1096,2060,1711],{}," (the finished builder) to the private constructor from Step 2. It can call that constructor because ",[1096,2063,1131],{}," lives inside ",[1096,2066,1813],{},[1085,2068,2069,2070,2072,2073,2075,2076,2079,2080,2082],{},"This whole ",[1096,2071,1131],{}," class goes inside ",[1096,2074,1813],{},"'s braces, after the constructor. A ",[1096,2077,2078],{},"describe()"," method is also added to ",[1096,2081,1813],{}," so the program can print the result.",[1080,2084,2086,2087],{"id":2085},"step-4-build-one-in-main","Step 4: Build One in ",[1096,2088,1841],{},[1089,2090,2092],{"className":1091,"code":2091,"language":1093,"meta":1094,"style":1094},"ElevatorConfig compBot = new ElevatorConfig.Builder()\n    .setMaxHeightMeters(1.4)\n    .setInverted(true)\n    .build();\n",[1096,2093,2094,2099,2104,2109],{"__ignoreMap":1094},[1099,2095,2096],{"class":1101,"line":1102},[1099,2097,2098],{},"ElevatorConfig compBot = new ElevatorConfig.Builder()\n",[1099,2100,2101],{"class":1101,"line":1149},[1099,2102,2103],{},"    .setMaxHeightMeters(1.4)\n",[1099,2105,2106],{"class":1101,"line":1155},[1099,2107,2108],{},"    .setInverted(true)\n",[1099,2110,2111],{"class":1101,"line":1161},[1099,2112,1188],{},[1085,2114,2115,2116,2119,2120,1466,2123,2126,2127,2129,2130,2132,2133,2135,2136,2138],{},"Read it top to bottom. ",[1096,2117,2118],{},"new ElevatorConfig.Builder()"," creates a builder with the usual values. ",[1096,2121,2122],{},".setMaxHeightMeters(1.4)",[1096,2124,2125],{},".setInverted(true)"," each change one setting and return the same builder. ",[1096,2128,1539],{}," ends the chain and produces the real ",[1096,2131,1813],{},". Gear ratio and brake mode are never mentioned, so they keep their starting values. Every argument sits right next to its name, so there's no way to mix up which ",[1096,2134,1795],{}," or which ",[1096,2137,1799],{}," is which.",[1080,2140,2142],{"id":2141},"step-5-the-whole-program","Step 5: The Whole Program",[1085,2144,2145,2146,2149,2150,2152,2153,2155,2156,2158,2159,2161,2162,2165,2166,2169,2170,2172],{},"To run this as one file, both classes go in ",[1096,2147,2148],{},"ElevatorSetup.java",". Java allows only one ",[1096,2151,1683],{}," class per file — the one whose name matches the file — so ",[1096,2154,1813],{}," is written without ",[1096,2157,1683],{},". The class holding ",[1096,2160,1841],{}," goes first: on Java 17, running a file with ",[1096,2163,2164],{},"java ElevatorSetup.java"," starts the ",[1121,2167,2168],{},"first"," class in the file, so ",[1096,2171,1841],{}," must live there. Java 25 is more forgiving (it also finds the class named after the file), but main-class-first works on both, so every multi-class program in this course uses it.",[1089,2174,2176],{"className":1091,"code":2175,"language":1093,"meta":1094,"style":1094},"public class ElevatorSetup\n{\n    public static void main(String[] args)\n    {\n        ElevatorConfig compBot = new ElevatorConfig.Builder()\n            .setMaxHeightMeters(1.4)\n            .setInverted(true)\n            .build();\n\n        System.out.println(\"Comp bot elevator: \" + compBot.describe());\n    }\n}\n\nclass ElevatorConfig\n{\n    private final double maxHeightMeters;\n    private final double gearRatio;\n    private final boolean brakeMode;\n    private final boolean inverted;\n\n    private ElevatorConfig(Builder builder)\n    {\n        this.maxHeightMeters = builder.maxHeightMeters;\n        this.gearRatio = builder.gearRatio;\n        this.brakeMode = builder.brakeMode;\n        this.inverted = builder.inverted;\n    }\n\n    public String describe()\n    {\n        return \"max height \" + maxHeightMeters + \" m, gear ratio \" + gearRatio\n            + \":1, brake mode \" + brakeMode + \", inverted \" + inverted;\n    }\n\n    public static class Builder\n    {\n        private double maxHeightMeters = 1.0;\n        private double gearRatio = 10.0;\n        private boolean brakeMode = true;\n        private boolean inverted = false;\n\n        public Builder setMaxHeightMeters(double max) { this.maxHeightMeters = max; return this; }\n        public Builder setGearRatio(double ratio) { this.gearRatio = ratio; return this; }\n        public Builder setBrakeMode(boolean brake) { this.brakeMode = brake; return this; }\n        public Builder setInverted(boolean inverted) { this.inverted = inverted; return this; }\n\n        public ElevatorConfig build() { return new ElevatorConfig(this); }\n    }\n}\n",[1096,2177,2178,2183,2187,2192,2196,2201,2206,2211,2216,2220,2225,2229,2233,2237,2241,2245,2249,2253,2257,2261,2265,2269,2273,2277,2281,2285,2289,2293,2297,2302,2306,2311,2316,2321,2326,2331,2336,2342,2348,2354,2360,2365,2371,2377,2383,2389,2394,2400,2405],{"__ignoreMap":1094},[1099,2179,2180],{"class":1101,"line":1102},[1099,2181,2182],{},"public class ElevatorSetup\n",[1099,2184,2185],{"class":1101,"line":1149},[1099,2186,1236],{},[1099,2188,2189],{"class":1101,"line":1155},[1099,2190,2191],{},"    public static void main(String[] args)\n",[1099,2193,2194],{"class":1101,"line":1161},[1099,2195,1267],{},[1099,2197,2198],{"class":1101,"line":1167},[1099,2199,2200],{},"        ElevatorConfig compBot = new ElevatorConfig.Builder()\n",[1099,2202,2203],{"class":1101,"line":1173},[1099,2204,2205],{},"            .setMaxHeightMeters(1.4)\n",[1099,2207,2208],{"class":1101,"line":1179},[1099,2209,2210],{},"            .setInverted(true)\n",[1099,2212,2213],{"class":1101,"line":1185},[1099,2214,2215],{},"            .build();\n",[1099,2217,2218],{"class":1101,"line":1270},[1099,2219,1257],{"emptyLinePlaceholder":1256},[1099,2221,2222],{"class":1101,"line":1276},[1099,2223,2224],{},"        System.out.println(\"Comp bot elevator: \" + compBot.describe());\n",[1099,2226,2227],{"class":1101,"line":1282},[1099,2228,1309],{},[1099,2230,2231],{"class":1101,"line":1288},[1099,2232,1406],{},[1099,2234,2235],{"class":1101,"line":1294},[1099,2236,1257],{"emptyLinePlaceholder":1256},[1099,2238,2239],{"class":1101,"line":1300},[1099,2240,1856],{},[1099,2242,2243],{"class":1101,"line":1306},[1099,2244,1236],{},[1099,2246,2247],{"class":1101,"line":1312},[1099,2248,1865],{},[1099,2250,2251],{"class":1101,"line":1317},[1099,2252,1870],{},[1099,2254,2255],{"class":1101,"line":1323},[1099,2256,1875],{},[1099,2258,2259],{"class":1101,"line":1328},[1099,2260,1880],{},[1099,2262,2263],{"class":1101,"line":1334},[1099,2264,1257],{"emptyLinePlaceholder":1256},[1099,2266,2267],{"class":1101,"line":1340},[1099,2268,1889],{},[1099,2270,2271],{"class":1101,"line":1346},[1099,2272,1267],{},[1099,2274,2275],{"class":1101,"line":1351},[1099,2276,1898],{},[1099,2278,2279],{"class":1101,"line":1357},[1099,2280,1903],{},[1099,2282,2283],{"class":1101,"line":1363},[1099,2284,1908],{},[1099,2286,2287],{"class":1101,"line":1369},[1099,2288,1913],{},[1099,2290,2291],{"class":1101,"line":1375},[1099,2292,1309],{},[1099,2294,2295],{"class":1101,"line":1381},[1099,2296,1257],{"emptyLinePlaceholder":1256},[1099,2298,2299],{"class":1101,"line":1387},[1099,2300,2301],{},"    public String describe()\n",[1099,2303,2304],{"class":1101,"line":1392},[1099,2305,1267],{},[1099,2307,2308],{"class":1101,"line":1398},[1099,2309,2310],{},"        return \"max height \" + maxHeightMeters + \" m, gear ratio \" + gearRatio\n",[1099,2312,2313],{"class":1101,"line":1403},[1099,2314,2315],{},"            + \":1, brake mode \" + brakeMode + \", inverted \" + inverted;\n",[1099,2317,2319],{"class":1101,"line":2318},33,[1099,2320,1309],{},[1099,2322,2324],{"class":1101,"line":2323},34,[1099,2325,1257],{"emptyLinePlaceholder":1256},[1099,2327,2329],{"class":1101,"line":2328},35,[1099,2330,1320],{},[1099,2332,2334],{"class":1101,"line":2333},36,[1099,2335,1267],{},[1099,2337,2339],{"class":1101,"line":2338},37,[1099,2340,2341],{},"        private double maxHeightMeters = 1.0;\n",[1099,2343,2345],{"class":1101,"line":2344},38,[1099,2346,2347],{},"        private double gearRatio = 10.0;\n",[1099,2349,2351],{"class":1101,"line":2350},39,[1099,2352,2353],{},"        private boolean brakeMode = true;\n",[1099,2355,2357],{"class":1101,"line":2356},40,[1099,2358,2359],{},"        private boolean inverted = false;\n",[1099,2361,2363],{"class":1101,"line":2362},41,[1099,2364,1257],{"emptyLinePlaceholder":1256},[1099,2366,2368],{"class":1101,"line":2367},42,[1099,2369,2370],{},"        public Builder setMaxHeightMeters(double max) { this.maxHeightMeters = max; return this; }\n",[1099,2372,2374],{"class":1101,"line":2373},43,[1099,2375,2376],{},"        public Builder setGearRatio(double ratio) { this.gearRatio = ratio; return this; }\n",[1099,2378,2380],{"class":1101,"line":2379},44,[1099,2381,2382],{},"        public Builder setBrakeMode(boolean brake) { this.brakeMode = brake; return this; }\n",[1099,2384,2386],{"class":1101,"line":2385},45,[1099,2387,2388],{},"        public Builder setInverted(boolean inverted) { this.inverted = inverted; return this; }\n",[1099,2390,2392],{"class":1101,"line":2391},46,[1099,2393,1257],{"emptyLinePlaceholder":1256},[1099,2395,2397],{"class":1101,"line":2396},47,[1099,2398,2399],{},"        public ElevatorConfig build() { return new ElevatorConfig(this); }\n",[1099,2401,2403],{"class":1101,"line":2402},48,[1099,2404,1309],{},[1099,2406,2408],{"class":1101,"line":2407},49,[1099,2409,1406],{},[1080,2411,2413],{"id":2412},"what-it-prints","What It Prints",[1089,2415,2420],{"className":2416,"code":2418,"language":2419},[2417],"language-text","Comp bot elevator: max height 1.4 m, gear ratio 10.0:1, brake mode true, inverted true\n","text",[1096,2421,2418],{"__ignoreMap":1094},[1085,2423,2424,1466,2427,2430,2431,1466,2434,2437,2438,1466,2441,2444],{},[1096,2425,2426],{},"max height",[1096,2428,2429],{},"inverted"," show the two values that were set in the chain. ",[1096,2432,2433],{},"gear ratio",[1096,2435,2436],{},"brake mode"," show the builder's starting values (",[1096,2439,2440],{},"10.0",[1096,2442,2443],{},"true","), because the chain never touched them.",[1080,2446,2448],{"id":2447},"what-the-private-constructor-blocks","What the Private Constructor Blocks",[1085,2450,2451,2452,2454,2455,2458],{},"Because ",[1096,2453,1841],{}," lives in a different class (",[1096,2456,2457],{},"ElevatorSetup","), trying to skip the builder fails to compile:",[1089,2460,2462],{"className":1091,"code":2461,"language":1093,"meta":1094,"style":1094},"ElevatorConfig compBot = new ElevatorConfig(new ElevatorConfig.Builder()); \u002F\u002F compile error\n",[1096,2463,2464],{"__ignoreMap":1094},[1099,2465,2466],{"class":1101,"line":1102},[1099,2467,2461],{},[1085,2469,2470,2471,2474,2475,2477,2478,2480,2481,1547],{},"The compiler reports ",[1096,2472,2473],{},"ElevatorConfig(Builder) has private access in ElevatorConfig",". That's the point of the ",[1096,2476,1213],{}," constructor: callers can only get an ",[1096,2479,1813],{}," by finishing a builder chain with ",[1096,2482,1539],{},[1080,2484,2486,2487,2489],{"id":2485},"what-forgetting-return-this-would-look-like","What Forgetting ",[1096,2488,1523],{}," Would Look Like",[1085,2491,2492,2493,2495,2496,2498],{},"If one setter were written as ",[1096,2494,1670],{}," without ",[1096,2497,1523],{},":",[1089,2500,2502],{"className":1091,"code":2501,"language":1093,"meta":1094,"style":1094},"public void setMaxHeightMeters(double max) { this.maxHeightMeters = max; }\n",[1096,2503,2504],{"__ignoreMap":1094},[1099,2505,2506],{"class":1101,"line":1102},[1099,2507,2501],{},[1085,2509,2510,2511,2513,2514,2516,2517,2519,2520,2522,2523,2525,2526,2528],{},"then the chain in ",[1096,2512,1841],{}," breaks at the very next call. ",[1096,2515,2122],{}," now returns nothing, so there's no object for ",[1096,2518,2125],{}," to be called on. The compiler reports ",[1096,2521,1674],{}," on the ",[1096,2524,2125],{}," line. Each ",[1096,2527,1523],{}," is what gives the next call in the chain something to call.",[1080,2530,2532],{"id":2531},"recap","Recap",[1553,2534,2535,2546,2552,2561,2566],{},[1556,2536,2537,2538,1817,2540,2542,2543,2545],{},"The target class has ",[1096,2539,1415],{},[1096,2541,1213],{}," constructor that takes a finished ",[1096,2544,1131],{},", so the object can only be made through the builder and never changes once built.",[1556,2547,2548,2549,2551],{},"The nested ",[1096,2550,1431],{}," holds each setting with a sensible starting value, so callers only mention the settings they change.",[1556,2553,2554,2555,2557,2558,2560],{},"Every builder method returns ",[1096,2556,1131],{}," and ends in ",[1096,2559,1523],{},", which makes the fluent chain possible.",[1556,2562,2563,2565],{},[1096,2564,1135],{}," ends the chain by passing the finished builder to the private constructor.",[1556,2567,2568,2569,2571],{},"Named calls like ",[1096,2570,2125],{}," replace anonymous positional arguments, so two same-typed settings can't be silently swapped.",[1750,2573,1752],{},{"title":1094,"searchDepth":1149,"depth":1149,"links":2575},[2576,2577,2578,2579,2580,2582,2583,2584,2585,2587],{"id":1781,"depth":1149,"text":1782},{"id":1803,"depth":1149,"text":1804},{"id":1845,"depth":1149,"text":1846},{"id":1967,"depth":1149,"text":1968},{"id":2085,"depth":1149,"text":2581},"Step 4: Build One in main",{"id":2141,"depth":1149,"text":2142},{"id":2412,"depth":1149,"text":2413},{"id":2447,"depth":1149,"text":2448},{"id":2485,"depth":1149,"text":2586},"What Forgetting return this; Would Look Like",{"id":2531,"depth":1149,"text":2532},{"outlineRef":1768,"pairsWith":2589,"status":2590},"[`lessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern.md`](..\u002F..\u002Flessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern.md)","new — authored worked example (fully solved, walked step by step — not a problem to attempt)",{"title":691,"description":1094},"c21OlDQhE2eSiJBTBodo0PuWzzriWlaPtIXZ5aO9Auw",{"id":2594,"title":1004,"body":2595,"description":1094,"extension":1766,"meta":4117,"navigation":1256,"path":1003,"seo":4119,"stem":1005,"__hash__":4120},"exercises\u002Fshockwave-curriculum\u002Fexercises\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern.md",{"type":1073,"value":2596,"toc":4112},[2597,2600,2604,2614,2623,2631,2655,2660,2693,2699,2715,2740,2744,2787,2790,2828,2833,2839,3038,3084,3088,3094,3103,3197,3210,3215,3382,3387,3392,3398,3403,3409,3414,3418,3424,3428,3434,3439,3443,3449,3453,3459,3464,3468,3474,3478,3484,3489,3493,3499,3503,3509,3514,3518,3524,3528,3533,3538,4068,4110],[1076,2598,1004],{"id":2599},"the-builder-pattern-exercises",[1080,2601,2603],{"id":2602},"multiple-choice","Multiple Choice",[1085,2605,2606,2609,2610,2613],{},[1116,2607,2608],{},"Question:"," An ",[1096,2611,2612],{},"IntakeConfig.Builder"," has this method:",[1089,2615,2617],{"className":1091,"code":2616,"language":1093,"meta":1094,"style":1094},"public void setRollerSpeed(double speed) { this.rollerSpeed = speed; }\n",[1096,2618,2619],{"__ignoreMap":1094},[1099,2620,2621],{"class":1101,"line":1102},[1099,2622,2616],{},[1085,2624,2625,2626,2557,2628,2630],{},"Every other builder method correctly returns ",[1096,2627,1131],{},[1096,2629,1523],{},". What happens with this code?",[1089,2632,2634],{"className":1091,"code":2633,"language":1093,"meta":1094,"style":1094},"IntakeConfig config = new IntakeConfig.Builder()\n    .setRollerSpeed(0.8)\n    .setReversed(true)\n    .build();\n",[1096,2635,2636,2641,2646,2651],{"__ignoreMap":1094},[1099,2637,2638],{"class":1101,"line":1102},[1099,2639,2640],{},"IntakeConfig config = new IntakeConfig.Builder()\n",[1099,2642,2643],{"class":1101,"line":1149},[1099,2644,2645],{},"    .setRollerSpeed(0.8)\n",[1099,2647,2648],{"class":1101,"line":1155},[1099,2649,2650],{},"    .setReversed(true)\n",[1099,2652,2653],{"class":1101,"line":1161},[1099,2654,1188],{},[1085,2656,2657],{},[1116,2658,2659],{},"Options:",[1553,2661,2662,2672,2679,2686],{},[1556,2663,2664,2665,2668,2669,2671],{},"A. It doesn't compile, because ",[1096,2666,2667],{},".setReversed(true)"," is being called on the result of a ",[1096,2670,1670],{}," method",[1556,2673,2674,2675,2678],{},"B. It compiles and runs, but ",[1096,2676,2677],{},"rollerSpeed"," keeps its default value",[1556,2680,2681,2682,2685],{},"C. It compiles and runs, but ",[1096,2683,2684],{},"setReversed(true)"," is silently skipped",[1556,2687,2688,2689,2692],{},"D. It compiles, but throws a ",[1096,2690,2691],{},"NullPointerException"," when it runs",[1085,2694,2695,2698],{},[1116,2696,2697],{},"Answer:"," A",[1085,2700,2701,2704,2705,2708,2709,2711,2712,2714],{},[1116,2702,2703],{},"Why:"," A fluent chain only works because each call returns an object for the next call to be made on. ",[1096,2706,2707],{},"setRollerSpeed"," returns ",[1096,2710,1670],{},", so there's nothing for ",[1096,2713,2667],{}," to be called on, and the compiler rejects the chain.",[1553,2716,2717,2724,2730],{},[1556,2718,2719,2720,2723],{},"B is wrong. The problem isn't the value being assigned (",[1096,2721,2722],{},"this.rollerSpeed = speed;"," is fine). The program never compiles, so nothing runs at all.",[1556,2725,2726,2727,2729],{},"C is wrong. Java never silently skips a call in a chain. A call on ",[1096,2728,1670],{}," is a compile error, not a no-op.",[1556,2731,2732,2733,2735,2736,2739],{},"D is wrong. This is caught at compile time, before the program can run. A ",[1096,2734,1670],{}," return isn't a ",[1096,2737,2738],{},"null"," reference that fails later.",[1080,2741,2743],{"id":2742},"micro-parsons","Micro-Parsons",[1085,2745,2746,2749,2750,2752,2753,2756,2757,2759,2760,2762,2763,2766,2767,2769,2770,2772,2773,2775,2776,2779,2780,2783,2784,1547],{},[1116,2747,2748],{},"Problem:"," You're given everything in the program below except the body of ",[1096,2751,1841],{},": the ",[1096,2754,2755],{},"ArmSetup"," class (with ",[1096,2758,1841],{},"'s signature and braces, placed first so the file also runs correctly on Java 17 — the class holding ",[1096,2761,1841],{}," has to come first in a multi-class file), and the ",[1096,2764,2765],{},"ArmConfig"," class, with its ",[1096,2768,1213],{}," constructor and nested ",[1096,2771,1131],{},". Reorder the fragments below into the body of ",[1096,2774,1841],{},". It should use the builder to set the arm's maximum angle to ",[1096,2777,2778],{},"110.0",", turn brake mode on, and set the gear ratio to ",[1096,2781,2782],{},"50.0",", then print the finished configuration: ",[1096,2785,2786],{},"max 110.0 deg, brake true, ratio 50.0:1",[1085,2788,2789],{},"Reorder the fragments below to complete it:",[1553,2791,2792,2798,2804,2810,2816,2822],{},[1556,2793,2794,2795],{},"a. ",[1096,2796,2797],{},"            .setGearRatio(50.0)",[1556,2799,2800,2801],{},"b. ",[1096,2802,2803],{},"        System.out.println(config.describe());",[1556,2805,2806,2807],{},"c. ",[1096,2808,2809],{},"        ArmConfig config = new ArmConfig.Builder()",[1556,2811,2812,2813],{},"d. ",[1096,2814,2815],{},"            .build();",[1556,2817,2818,2819],{},"e. ",[1096,2820,2821],{},"            .setMaxAngle(110.0)",[1556,2823,2824,2825],{},"f. ",[1096,2826,2827],{},"            .setBrakeMode(true)",[1085,2829,2830,2832],{},[1116,2831,2697],{}," c, e, f, a, d, b",[1085,2834,2835,2838],{},[1116,2836,2837],{},"Interchangeable:"," (e, f, a)",[1089,2840,2842],{"className":1091,"code":2841,"language":1093,"meta":1094,"style":1094},"public class ArmSetup\n{\n    public static void main(String[] args)\n    {\n        ArmConfig config = new ArmConfig.Builder()\n            .setMaxAngle(110.0)\n            .setBrakeMode(true)\n            .setGearRatio(50.0)\n            .build();\n        System.out.println(config.describe());\n    }\n}\n\nclass ArmConfig\n{\n    private final double maxAngle;\n    private final boolean brakeMode;\n    private final double gearRatio;\n\n    private ArmConfig(Builder builder)\n    {\n        this.maxAngle = builder.maxAngle;\n        this.brakeMode = builder.brakeMode;\n        this.gearRatio = builder.gearRatio;\n    }\n\n    public String describe()\n    {\n        return \"max \" + maxAngle + \" deg, brake \" + brakeMode + \", ratio \" + gearRatio + \":1\";\n    }\n\n    public static class Builder\n    {\n        private double maxAngle = 90.0;\n        private boolean brakeMode = false;\n        private double gearRatio = 1.0;\n\n        public Builder setMaxAngle(double maxAngle) { this.maxAngle = maxAngle; return this; }\n        public Builder setBrakeMode(boolean brakeMode) { this.brakeMode = brakeMode; return this; }\n        public Builder setGearRatio(double gearRatio) { this.gearRatio = gearRatio; return this; }\n\n        public ArmConfig build() { return new ArmConfig(this); }\n    }\n}\n",[1096,2843,2844,2849,2853,2857,2861,2866,2871,2876,2881,2885,2890,2894,2898,2902,2907,2911,2916,2920,2924,2928,2933,2937,2942,2946,2950,2954,2958,2962,2966,2971,2975,2979,2983,2987,2992,2997,3002,3006,3011,3016,3021,3025,3030,3034],{"__ignoreMap":1094},[1099,2845,2846],{"class":1101,"line":1102},[1099,2847,2848],{},"public class ArmSetup\n",[1099,2850,2851],{"class":1101,"line":1149},[1099,2852,1236],{},[1099,2854,2855],{"class":1101,"line":1155},[1099,2856,2191],{},[1099,2858,2859],{"class":1101,"line":1161},[1099,2860,1267],{},[1099,2862,2863],{"class":1101,"line":1167},[1099,2864,2865],{},"        ArmConfig config = new ArmConfig.Builder()\n",[1099,2867,2868],{"class":1101,"line":1173},[1099,2869,2870],{},"            .setMaxAngle(110.0)\n",[1099,2872,2873],{"class":1101,"line":1179},[1099,2874,2875],{},"            .setBrakeMode(true)\n",[1099,2877,2878],{"class":1101,"line":1185},[1099,2879,2880],{},"            .setGearRatio(50.0)\n",[1099,2882,2883],{"class":1101,"line":1270},[1099,2884,2215],{},[1099,2886,2887],{"class":1101,"line":1276},[1099,2888,2889],{},"        System.out.println(config.describe());\n",[1099,2891,2892],{"class":1101,"line":1282},[1099,2893,1309],{},[1099,2895,2896],{"class":1101,"line":1288},[1099,2897,1406],{},[1099,2899,2900],{"class":1101,"line":1294},[1099,2901,1257],{"emptyLinePlaceholder":1256},[1099,2903,2904],{"class":1101,"line":1300},[1099,2905,2906],{},"class ArmConfig\n",[1099,2908,2909],{"class":1101,"line":1306},[1099,2910,1236],{},[1099,2912,2913],{"class":1101,"line":1312},[1099,2914,2915],{},"    private final double maxAngle;\n",[1099,2917,2918],{"class":1101,"line":1317},[1099,2919,1875],{},[1099,2921,2922],{"class":1101,"line":1323},[1099,2923,1870],{},[1099,2925,2926],{"class":1101,"line":1328},[1099,2927,1257],{"emptyLinePlaceholder":1256},[1099,2929,2930],{"class":1101,"line":1334},[1099,2931,2932],{},"    private ArmConfig(Builder builder)\n",[1099,2934,2935],{"class":1101,"line":1340},[1099,2936,1267],{},[1099,2938,2939],{"class":1101,"line":1346},[1099,2940,2941],{},"        this.maxAngle = builder.maxAngle;\n",[1099,2943,2944],{"class":1101,"line":1351},[1099,2945,1908],{},[1099,2947,2948],{"class":1101,"line":1357},[1099,2949,1903],{},[1099,2951,2952],{"class":1101,"line":1363},[1099,2953,1309],{},[1099,2955,2956],{"class":1101,"line":1369},[1099,2957,1257],{"emptyLinePlaceholder":1256},[1099,2959,2960],{"class":1101,"line":1375},[1099,2961,2301],{},[1099,2963,2964],{"class":1101,"line":1381},[1099,2965,1267],{},[1099,2967,2968],{"class":1101,"line":1387},[1099,2969,2970],{},"        return \"max \" + maxAngle + \" deg, brake \" + brakeMode + \", ratio \" + gearRatio + \":1\";\n",[1099,2972,2973],{"class":1101,"line":1392},[1099,2974,1309],{},[1099,2976,2977],{"class":1101,"line":1398},[1099,2978,1257],{"emptyLinePlaceholder":1256},[1099,2980,2981],{"class":1101,"line":1403},[1099,2982,1320],{},[1099,2984,2985],{"class":1101,"line":2318},[1099,2986,1267],{},[1099,2988,2989],{"class":1101,"line":2323},[1099,2990,2991],{},"        private double maxAngle = 90.0;\n",[1099,2993,2994],{"class":1101,"line":2328},[1099,2995,2996],{},"        private boolean brakeMode = false;\n",[1099,2998,2999],{"class":1101,"line":2333},[1099,3000,3001],{},"        private double gearRatio = 1.0;\n",[1099,3003,3004],{"class":1101,"line":2338},[1099,3005,1257],{"emptyLinePlaceholder":1256},[1099,3007,3008],{"class":1101,"line":2344},[1099,3009,3010],{},"        public Builder setMaxAngle(double maxAngle) { this.maxAngle = maxAngle; return this; }\n",[1099,3012,3013],{"class":1101,"line":2350},[1099,3014,3015],{},"        public Builder setBrakeMode(boolean brakeMode) { this.brakeMode = brakeMode; return this; }\n",[1099,3017,3018],{"class":1101,"line":2356},[1099,3019,3020],{},"        public Builder setGearRatio(double gearRatio) { this.gearRatio = gearRatio; return this; }\n",[1099,3022,3023],{"class":1101,"line":2362},[1099,3024,1257],{"emptyLinePlaceholder":1256},[1099,3026,3027],{"class":1101,"line":2367},[1099,3028,3029],{},"        public ArmConfig build() { return new ArmConfig(this); }\n",[1099,3031,3032],{"class":1101,"line":2373},[1099,3033,1309],{},[1099,3035,3036],{"class":1101,"line":2379},[1099,3037,1406],{},[1085,3039,3040,3043,3044,3047,3048,3051,3052,3051,3055,3058,3059,3061,3062,3065,3066,3069,3070,3072,3073,3065,3076,3079,3080,3083],{},[1116,3041,3042],{},"Why this order:"," The chain has to start with the line that creates the builder (",[1096,3045,3046],{},"c","). Every other call in the chain is made on the object it produces. The three setters (",[1096,3049,3050],{},"e",", ",[1096,3053,3054],{},"f",[1096,3056,3057],{},"a",") each set a different, independent field and each return the same builder, so they can go in any order (hence ",[1116,3060,2837],{}," (e, f, a)). ",[1096,3063,3064],{},".build();"," (",[1096,3067,3068],{},"d",") has to come last in the chain. It's the call that turns the builder into the real ",[1096,3071,2765],{},", and it's the only fragment with the semicolon that ends the statement. After it, nothing else can chain on as a builder call. ",[1096,3074,3075],{},"println",[1096,3077,3078],{},"b",") comes last, since ",[1096,3081,3082],{},"config"," only exists once the whole chain has finished.",[1080,3085,3087],{"id":3086},"coding","Coding",[1085,3089,3090,3093],{},[1116,3091,3092],{},"Mode:"," full-program",[1085,3095,3096,3098,3099,3102],{},[1116,3097,2748],{}," Write the class ",[1096,3100,3101],{},"MotorConfig"," using the Builder Pattern.",[1553,3104,3105,3146,3173],{},[1556,3106,3107,3109,3110,3115,3116,3118,3119,3122,3123,3051,3125,3051,3127,3129,3130,3133,3134,3051,3137,3051,3140,1466,3143,1547],{},[1096,3108,3101],{}," has a ",[1116,3111,3112,3114],{},[1096,3113,1213],{}," constructor"," that takes a ",[1096,3117,1131],{},", and ",[1096,3120,3121],{},"private final"," fields for ",[1096,3124,1482],{},[1096,3126,1586],{},[1096,3128,1582],{}," and\n",[1096,3131,3132],{},"feedforward",". It has getters ",[1096,3135,3136],{},"double getKP()",[1096,3138,3139],{},"double getMaxRPM()",[1096,3141,3142],{},"double getMinRPM()",[1096,3144,3145],{},"boolean isFeedforward()",[1556,3147,3148,3149,3151,3152,3051,3155,3051,3158,3129,3161,3164,3165,3168,3169,3172],{},"It contains a ",[1096,3150,1431],{}," with chainable setters ",[1096,3153,3154],{},"setKP(double)",[1096,3156,3157],{},"setMaxRPM(double)",[1096,3159,3160],{},"setMinRPM(double)",[1096,3162,3163],{},"enableFeedforward(boolean)",". Each returns the same builder. Every setting starts at ",[1096,3166,3167],{},"0"," (feedforward starts as ",[1096,3170,3171],{},"false",").",[1556,3174,3175,3177,3178,3051,3180,3183,3184,3186,3187,3189,3190,3192,3193,3196],{},[1096,3176,1492],{}," returns the new ",[1096,3179,3101],{},[1116,3181,3182],{},"but"," if ",[1096,3185,1582],{}," is greater than ",[1096,3188,1586],{}," it throws an\n",[1096,3191,1578],{}," with the message ",[1096,3194,3195],{},"min RPM is above max RPM"," instead. Equal values are allowed.",[1085,3198,3199,3201,3202,3205,3206,3209],{},[1096,3200,1841],{}," reads the settings (the word ",[1096,3203,3204],{},"yes"," turns feedforward on; any other word leaves the default) and prints the result, or ",[1096,3207,3208],{},"Invalid: "," plus the exception message.",[1085,3211,3212],{},[1116,3213,3214],{},"Starter:",[1089,3216,3218],{"className":1091,"code":3217,"language":1093,"meta":1094,"style":1094},"import java.util.Scanner;\n\npublic class Main\n{\n    public static void main(String[] args) \u002F\u002F Don't change main\n    {\n        Scanner in = new Scanner(System.in);\n        double kP = in.nextDouble();\n        double maxRpm = in.nextDouble();\n        double minRpm = in.nextDouble();\n        String feedforward = in.next();\n        try\n        {\n            MotorConfig.Builder builder = new MotorConfig.Builder()\n                .setKP(kP)\n                .setMaxRPM(maxRpm)\n                .setMinRPM(minRpm);\n            if (feedforward.equals(\"yes\"))\n            {\n                builder.enableFeedforward(true);\n            }\n            MotorConfig config = builder.build();\n            System.out.println(\"kP: \" + config.getKP());\n            System.out.println(\"RPM range: \" + config.getMinRPM() + \" to \" + config.getMaxRPM());\n            System.out.println(\"Feedforward: \" + config.isFeedforward());\n        }\n        catch (IllegalArgumentException e)\n        {\n            System.out.println(\"Invalid: \" + e.getMessage());\n        }\n    }\n}\n\n\u002F\u002F TODO: write the class MotorConfig, with its nested Builder\n",[1096,3219,3220,3225,3229,3234,3238,3243,3247,3252,3257,3262,3267,3272,3277,3282,3287,3292,3297,3302,3307,3312,3317,3322,3327,3332,3337,3342,3347,3352,3356,3361,3365,3369,3373,3377],{"__ignoreMap":1094},[1099,3221,3222],{"class":1101,"line":1102},[1099,3223,3224],{},"import java.util.Scanner;\n",[1099,3226,3227],{"class":1101,"line":1149},[1099,3228,1257],{"emptyLinePlaceholder":1256},[1099,3230,3231],{"class":1101,"line":1155},[1099,3232,3233],{},"public class Main\n",[1099,3235,3236],{"class":1101,"line":1161},[1099,3237,1236],{},[1099,3239,3240],{"class":1101,"line":1167},[1099,3241,3242],{},"    public static void main(String[] args) \u002F\u002F Don't change main\n",[1099,3244,3245],{"class":1101,"line":1173},[1099,3246,1267],{},[1099,3248,3249],{"class":1101,"line":1179},[1099,3250,3251],{},"        Scanner in = new Scanner(System.in);\n",[1099,3253,3254],{"class":1101,"line":1185},[1099,3255,3256],{},"        double kP = in.nextDouble();\n",[1099,3258,3259],{"class":1101,"line":1270},[1099,3260,3261],{},"        double maxRpm = in.nextDouble();\n",[1099,3263,3264],{"class":1101,"line":1276},[1099,3265,3266],{},"        double minRpm = in.nextDouble();\n",[1099,3268,3269],{"class":1101,"line":1282},[1099,3270,3271],{},"        String feedforward = in.next();\n",[1099,3273,3274],{"class":1101,"line":1288},[1099,3275,3276],{},"        try\n",[1099,3278,3279],{"class":1101,"line":1294},[1099,3280,3281],{},"        {\n",[1099,3283,3284],{"class":1101,"line":1300},[1099,3285,3286],{},"            MotorConfig.Builder builder = new MotorConfig.Builder()\n",[1099,3288,3289],{"class":1101,"line":1306},[1099,3290,3291],{},"                .setKP(kP)\n",[1099,3293,3294],{"class":1101,"line":1312},[1099,3295,3296],{},"                .setMaxRPM(maxRpm)\n",[1099,3298,3299],{"class":1101,"line":1317},[1099,3300,3301],{},"                .setMinRPM(minRpm);\n",[1099,3303,3304],{"class":1101,"line":1323},[1099,3305,3306],{},"            if (feedforward.equals(\"yes\"))\n",[1099,3308,3309],{"class":1101,"line":1328},[1099,3310,3311],{},"            {\n",[1099,3313,3314],{"class":1101,"line":1334},[1099,3315,3316],{},"                builder.enableFeedforward(true);\n",[1099,3318,3319],{"class":1101,"line":1340},[1099,3320,3321],{},"            }\n",[1099,3323,3324],{"class":1101,"line":1346},[1099,3325,3326],{},"            MotorConfig config = builder.build();\n",[1099,3328,3329],{"class":1101,"line":1351},[1099,3330,3331],{},"            System.out.println(\"kP: \" + config.getKP());\n",[1099,3333,3334],{"class":1101,"line":1357},[1099,3335,3336],{},"            System.out.println(\"RPM range: \" + config.getMinRPM() + \" to \" + config.getMaxRPM());\n",[1099,3338,3339],{"class":1101,"line":1363},[1099,3340,3341],{},"            System.out.println(\"Feedforward: \" + config.isFeedforward());\n",[1099,3343,3344],{"class":1101,"line":1369},[1099,3345,3346],{},"        }\n",[1099,3348,3349],{"class":1101,"line":1375},[1099,3350,3351],{},"        catch (IllegalArgumentException e)\n",[1099,3353,3354],{"class":1101,"line":1381},[1099,3355,3281],{},[1099,3357,3358],{"class":1101,"line":1387},[1099,3359,3360],{},"            System.out.println(\"Invalid: \" + e.getMessage());\n",[1099,3362,3363],{"class":1101,"line":1392},[1099,3364,3346],{},[1099,3366,3367],{"class":1101,"line":1398},[1099,3368,1309],{},[1099,3370,3371],{"class":1101,"line":1403},[1099,3372,1406],{},[1099,3374,3375],{"class":1101,"line":2318},[1099,3376,1257],{"emptyLinePlaceholder":1256},[1099,3378,3379],{"class":1101,"line":2323},[1099,3380,3381],{},"\u002F\u002F TODO: write the class MotorConfig, with its nested Builder\n",[1085,3383,3384],{},[1116,3385,3386],{},"Scenario 1 (visible):",[1085,3388,3389],{},[1116,3390,3391],{},"Input:",[1089,3393,3396],{"className":3394,"code":3395,"language":2419,"meta":1094},[2417],"0.01 5000.0 1000.0 yes\n",[1096,3397,3395],{"__ignoreMap":1094},[1085,3399,3400],{},[1116,3401,3402],{},"Expected output:",[1089,3404,3407],{"className":3405,"code":3406,"language":2419,"meta":1094},[2417],"kP: 0.01\nRPM range: 1000.0 to 5000.0\nFeedforward: true\n",[1096,3408,3406],{"__ignoreMap":1094},[1085,3410,3411],{},[1116,3412,3413],{},"Scenario 2 (visible):",[1085,3415,3416],{},[1116,3417,3391],{},[1089,3419,3422],{"className":3420,"code":3421,"language":2419,"meta":1094},[2417],"0.5 300.0 -300.0 no\n",[1096,3423,3421],{"__ignoreMap":1094},[1085,3425,3426],{},[1116,3427,3402],{},[1089,3429,3432],{"className":3430,"code":3431,"language":2419,"meta":1094},[2417],"kP: 0.5\nRPM range: -300.0 to 300.0\nFeedforward: false\n",[1096,3433,3431],{"__ignoreMap":1094},[1085,3435,3436],{},[1116,3437,3438],{},"Scenario 3 (visible):",[1085,3440,3441],{},[1116,3442,3391],{},[1089,3444,3447],{"className":3445,"code":3446,"language":2419,"meta":1094},[2417],"0.02 100.0 200.0 no\n",[1096,3448,3446],{"__ignoreMap":1094},[1085,3450,3451],{},[1116,3452,3402],{},[1089,3454,3457],{"className":3455,"code":3456,"language":2419,"meta":1094},[2417],"Invalid: min RPM is above max RPM\n",[1096,3458,3456],{"__ignoreMap":1094},[1085,3460,3461],{},[1116,3462,3463],{},"Scenario 4 (hidden):",[1085,3465,3466],{},[1116,3467,3391],{},[1089,3469,3472],{"className":3470,"code":3471,"language":2419,"meta":1094},[2417],"0.25 1500.0 1500.0 no\n",[1096,3473,3471],{"__ignoreMap":1094},[1085,3475,3476],{},[1116,3477,3402],{},[1089,3479,3482],{"className":3480,"code":3481,"language":2419,"meta":1094},[2417],"kP: 0.25\nRPM range: 1500.0 to 1500.0\nFeedforward: false\n",[1096,3483,3481],{"__ignoreMap":1094},[1085,3485,3486],{},[1116,3487,3488],{},"Scenario 5 (hidden):",[1085,3490,3491],{},[1116,3492,3391],{},[1089,3494,3497],{"className":3495,"code":3496,"language":2419,"meta":1094},[2417],"1.5 6000.0 0.0 yes\n",[1096,3498,3496],{"__ignoreMap":1094},[1085,3500,3501],{},[1116,3502,3402],{},[1089,3504,3507],{"className":3505,"code":3506,"language":2419,"meta":1094},[2417],"kP: 1.5\nRPM range: 0.0 to 6000.0\nFeedforward: true\n",[1096,3508,3506],{"__ignoreMap":1094},[1085,3510,3511],{},[1116,3512,3513],{},"Scenario 6 (hidden):",[1085,3515,3516],{},[1116,3517,3391],{},[1089,3519,3522],{"className":3520,"code":3521,"language":2419,"meta":1094},[2417],"0.1 -50.0 -10.0 yes\n",[1096,3523,3521],{"__ignoreMap":1094},[1085,3525,3526],{},[1116,3527,3402],{},[1089,3529,3531],{"className":3530,"code":3456,"language":2419,"meta":1094},[2417],[1096,3532,3456],{"__ignoreMap":1094},[1085,3534,3535],{},[1116,3536,3537],{},"Solution:",[1089,3539,3541],{"className":1091,"code":3540,"language":1093,"meta":1094,"style":1094},"import java.util.Scanner;\n\npublic class Main\n{\n    public static void main(String[] args) \u002F\u002F Don't change main\n    {\n        Scanner in = new Scanner(System.in);\n        double kP = in.nextDouble();\n        double maxRpm = in.nextDouble();\n        double minRpm = in.nextDouble();\n        String feedforward = in.next();\n        try\n        {\n            MotorConfig.Builder builder = new MotorConfig.Builder()\n                .setKP(kP)\n                .setMaxRPM(maxRpm)\n                .setMinRPM(minRpm);\n            if (feedforward.equals(\"yes\"))\n            {\n                builder.enableFeedforward(true);\n            }\n            MotorConfig config = builder.build();\n            System.out.println(\"kP: \" + config.getKP());\n            System.out.println(\"RPM range: \" + config.getMinRPM() + \" to \" + config.getMaxRPM());\n            System.out.println(\"Feedforward: \" + config.isFeedforward());\n        }\n        catch (IllegalArgumentException e)\n        {\n            System.out.println(\"Invalid: \" + e.getMessage());\n        }\n    }\n}\n\nclass MotorConfig\n{\n    private final double kP;\n    private final double maxRPM;\n    private final double minRPM;\n    private final boolean feedforward;\n\n    private MotorConfig(Builder builder)\n    {\n        this.kP = builder.kP;\n        this.maxRPM = builder.maxRPM;\n        this.minRPM = builder.minRPM;\n        this.feedforward = builder.feedforward;\n    }\n\n    public double getKP()\n    {\n        return kP;\n    }\n\n    public double getMaxRPM()\n    {\n        return maxRPM;\n    }\n\n    public double getMinRPM()\n    {\n        return minRPM;\n    }\n\n    public boolean isFeedforward()\n    {\n        return feedforward;\n    }\n\n    public static class Builder\n    {\n        private double kP = 0;\n        private double maxRPM = 0;\n        private double minRPM = 0;\n        private boolean feedforward = false;\n\n        public Builder setKP(double kP)\n        {\n            this.kP = kP;\n            return this;\n        }\n\n        public Builder setMaxRPM(double max)\n        {\n            this.maxRPM = max;\n            return this;\n        }\n\n        public Builder setMinRPM(double min)\n        {\n            this.minRPM = min;\n            return this;\n        }\n\n        public Builder enableFeedforward(boolean ff)\n        {\n            this.feedforward = ff;\n            return this;\n        }\n\n        public MotorConfig build()\n        {\n            if (minRPM > maxRPM)\n            {\n                throw new IllegalArgumentException(\"min RPM is above max RPM\");\n            }\n            return new MotorConfig(this);\n        }\n    }\n}\n",[1096,3542,3543,3547,3551,3555,3559,3563,3567,3571,3575,3579,3583,3587,3591,3595,3599,3603,3607,3611,3615,3619,3623,3627,3631,3635,3639,3643,3647,3651,3655,3659,3663,3667,3671,3675,3680,3684,3689,3694,3699,3703,3707,3712,3716,3720,3724,3728,3732,3736,3740,3745,3750,3756,3761,3766,3772,3777,3783,3788,3793,3799,3804,3810,3815,3820,3826,3831,3837,3842,3847,3852,3857,3863,3869,3875,3880,3885,3891,3896,3902,3908,3913,3918,3924,3929,3935,3940,3945,3950,3956,3961,3967,3972,3977,3982,3988,3993,3999,4004,4009,4014,4020,4025,4031,4036,4042,4047,4053,4058,4063],{"__ignoreMap":1094},[1099,3544,3545],{"class":1101,"line":1102},[1099,3546,3224],{},[1099,3548,3549],{"class":1101,"line":1149},[1099,3550,1257],{"emptyLinePlaceholder":1256},[1099,3552,3553],{"class":1101,"line":1155},[1099,3554,3233],{},[1099,3556,3557],{"class":1101,"line":1161},[1099,3558,1236],{},[1099,3560,3561],{"class":1101,"line":1167},[1099,3562,3242],{},[1099,3564,3565],{"class":1101,"line":1173},[1099,3566,1267],{},[1099,3568,3569],{"class":1101,"line":1179},[1099,3570,3251],{},[1099,3572,3573],{"class":1101,"line":1185},[1099,3574,3256],{},[1099,3576,3577],{"class":1101,"line":1270},[1099,3578,3261],{},[1099,3580,3581],{"class":1101,"line":1276},[1099,3582,3266],{},[1099,3584,3585],{"class":1101,"line":1282},[1099,3586,3271],{},[1099,3588,3589],{"class":1101,"line":1288},[1099,3590,3276],{},[1099,3592,3593],{"class":1101,"line":1294},[1099,3594,3281],{},[1099,3596,3597],{"class":1101,"line":1300},[1099,3598,3286],{},[1099,3600,3601],{"class":1101,"line":1306},[1099,3602,3291],{},[1099,3604,3605],{"class":1101,"line":1312},[1099,3606,3296],{},[1099,3608,3609],{"class":1101,"line":1317},[1099,3610,3301],{},[1099,3612,3613],{"class":1101,"line":1323},[1099,3614,3306],{},[1099,3616,3617],{"class":1101,"line":1328},[1099,3618,3311],{},[1099,3620,3621],{"class":1101,"line":1334},[1099,3622,3316],{},[1099,3624,3625],{"class":1101,"line":1340},[1099,3626,3321],{},[1099,3628,3629],{"class":1101,"line":1346},[1099,3630,3326],{},[1099,3632,3633],{"class":1101,"line":1351},[1099,3634,3331],{},[1099,3636,3637],{"class":1101,"line":1357},[1099,3638,3336],{},[1099,3640,3641],{"class":1101,"line":1363},[1099,3642,3341],{},[1099,3644,3645],{"class":1101,"line":1369},[1099,3646,3346],{},[1099,3648,3649],{"class":1101,"line":1375},[1099,3650,3351],{},[1099,3652,3653],{"class":1101,"line":1381},[1099,3654,3281],{},[1099,3656,3657],{"class":1101,"line":1387},[1099,3658,3360],{},[1099,3660,3661],{"class":1101,"line":1392},[1099,3662,3346],{},[1099,3664,3665],{"class":1101,"line":1398},[1099,3666,1309],{},[1099,3668,3669],{"class":1101,"line":1403},[1099,3670,1406],{},[1099,3672,3673],{"class":1101,"line":2318},[1099,3674,1257],{"emptyLinePlaceholder":1256},[1099,3676,3677],{"class":1101,"line":2323},[1099,3678,3679],{},"class MotorConfig\n",[1099,3681,3682],{"class":1101,"line":2328},[1099,3683,1236],{},[1099,3685,3686],{"class":1101,"line":2333},[1099,3687,3688],{},"    private final double kP;\n",[1099,3690,3691],{"class":1101,"line":2338},[1099,3692,3693],{},"    private final double maxRPM;\n",[1099,3695,3696],{"class":1101,"line":2344},[1099,3697,3698],{},"    private final double minRPM;\n",[1099,3700,3701],{"class":1101,"line":2350},[1099,3702,1246],{},[1099,3704,3705],{"class":1101,"line":2356},[1099,3706,1257],{"emptyLinePlaceholder":1256},[1099,3708,3709],{"class":1101,"line":2362},[1099,3710,3711],{},"    private MotorConfig(Builder builder)\n",[1099,3713,3714],{"class":1101,"line":2367},[1099,3715,1267],{},[1099,3717,3718],{"class":1101,"line":2373},[1099,3719,1273],{},[1099,3721,3722],{"class":1101,"line":2379},[1099,3723,1297],{},[1099,3725,3726],{"class":1101,"line":2385},[1099,3727,1303],{},[1099,3729,3730],{"class":1101,"line":2391},[1099,3731,1291],{},[1099,3733,3734],{"class":1101,"line":2396},[1099,3735,1309],{},[1099,3737,3738],{"class":1101,"line":2402},[1099,3739,1257],{"emptyLinePlaceholder":1256},[1099,3741,3742],{"class":1101,"line":2407},[1099,3743,3744],{},"    public double getKP()\n",[1099,3746,3748],{"class":1101,"line":3747},50,[1099,3749,1267],{},[1099,3751,3753],{"class":1101,"line":3752},51,[1099,3754,3755],{},"        return kP;\n",[1099,3757,3759],{"class":1101,"line":3758},52,[1099,3760,1309],{},[1099,3762,3764],{"class":1101,"line":3763},53,[1099,3765,1257],{"emptyLinePlaceholder":1256},[1099,3767,3769],{"class":1101,"line":3768},54,[1099,3770,3771],{},"    public double getMaxRPM()\n",[1099,3773,3775],{"class":1101,"line":3774},55,[1099,3776,1267],{},[1099,3778,3780],{"class":1101,"line":3779},56,[1099,3781,3782],{},"        return maxRPM;\n",[1099,3784,3786],{"class":1101,"line":3785},57,[1099,3787,1309],{},[1099,3789,3791],{"class":1101,"line":3790},58,[1099,3792,1257],{"emptyLinePlaceholder":1256},[1099,3794,3796],{"class":1101,"line":3795},59,[1099,3797,3798],{},"    public double getMinRPM()\n",[1099,3800,3802],{"class":1101,"line":3801},60,[1099,3803,1267],{},[1099,3805,3807],{"class":1101,"line":3806},61,[1099,3808,3809],{},"        return minRPM;\n",[1099,3811,3813],{"class":1101,"line":3812},62,[1099,3814,1309],{},[1099,3816,3818],{"class":1101,"line":3817},63,[1099,3819,1257],{"emptyLinePlaceholder":1256},[1099,3821,3823],{"class":1101,"line":3822},64,[1099,3824,3825],{},"    public boolean isFeedforward()\n",[1099,3827,3829],{"class":1101,"line":3828},65,[1099,3830,1267],{},[1099,3832,3834],{"class":1101,"line":3833},66,[1099,3835,3836],{},"        return feedforward;\n",[1099,3838,3840],{"class":1101,"line":3839},67,[1099,3841,1309],{},[1099,3843,3845],{"class":1101,"line":3844},68,[1099,3846,1257],{"emptyLinePlaceholder":1256},[1099,3848,3850],{"class":1101,"line":3849},69,[1099,3851,1320],{},[1099,3853,3855],{"class":1101,"line":3854},70,[1099,3856,1267],{},[1099,3858,3860],{"class":1101,"line":3859},71,[1099,3861,3862],{},"        private double kP = 0;\n",[1099,3864,3866],{"class":1101,"line":3865},72,[1099,3867,3868],{},"        private double maxRPM = 0;\n",[1099,3870,3872],{"class":1101,"line":3871},73,[1099,3873,3874],{},"        private double minRPM = 0;\n",[1099,3876,3878],{"class":1101,"line":3877},74,[1099,3879,1337],{},[1099,3881,3883],{"class":1101,"line":3882},75,[1099,3884,1257],{"emptyLinePlaceholder":1256},[1099,3886,3888],{"class":1101,"line":3887},76,[1099,3889,3890],{},"        public Builder setKP(double kP)\n",[1099,3892,3894],{"class":1101,"line":3893},77,[1099,3895,3281],{},[1099,3897,3899],{"class":1101,"line":3898},78,[1099,3900,3901],{},"            this.kP = kP;\n",[1099,3903,3905],{"class":1101,"line":3904},79,[1099,3906,3907],{},"            return this;\n",[1099,3909,3911],{"class":1101,"line":3910},80,[1099,3912,3346],{},[1099,3914,3916],{"class":1101,"line":3915},81,[1099,3917,1257],{"emptyLinePlaceholder":1256},[1099,3919,3921],{"class":1101,"line":3920},82,[1099,3922,3923],{},"        public Builder setMaxRPM(double max)\n",[1099,3925,3927],{"class":1101,"line":3926},83,[1099,3928,3281],{},[1099,3930,3932],{"class":1101,"line":3931},84,[1099,3933,3934],{},"            this.maxRPM = max;\n",[1099,3936,3938],{"class":1101,"line":3937},85,[1099,3939,3907],{},[1099,3941,3943],{"class":1101,"line":3942},86,[1099,3944,3346],{},[1099,3946,3948],{"class":1101,"line":3947},87,[1099,3949,1257],{"emptyLinePlaceholder":1256},[1099,3951,3953],{"class":1101,"line":3952},88,[1099,3954,3955],{},"        public Builder setMinRPM(double min)\n",[1099,3957,3959],{"class":1101,"line":3958},89,[1099,3960,3281],{},[1099,3962,3964],{"class":1101,"line":3963},90,[1099,3965,3966],{},"            this.minRPM = min;\n",[1099,3968,3970],{"class":1101,"line":3969},91,[1099,3971,3907],{},[1099,3973,3975],{"class":1101,"line":3974},92,[1099,3976,3346],{},[1099,3978,3980],{"class":1101,"line":3979},93,[1099,3981,1257],{"emptyLinePlaceholder":1256},[1099,3983,3985],{"class":1101,"line":3984},94,[1099,3986,3987],{},"        public Builder enableFeedforward(boolean ff)\n",[1099,3989,3991],{"class":1101,"line":3990},95,[1099,3992,3281],{},[1099,3994,3996],{"class":1101,"line":3995},96,[1099,3997,3998],{},"            this.feedforward = ff;\n",[1099,4000,4002],{"class":1101,"line":4001},97,[1099,4003,3907],{},[1099,4005,4007],{"class":1101,"line":4006},98,[1099,4008,3346],{},[1099,4010,4012],{"class":1101,"line":4011},99,[1099,4013,1257],{"emptyLinePlaceholder":1256},[1099,4015,4017],{"class":1101,"line":4016},100,[1099,4018,4019],{},"        public MotorConfig build()\n",[1099,4021,4023],{"class":1101,"line":4022},101,[1099,4024,3281],{},[1099,4026,4028],{"class":1101,"line":4027},102,[1099,4029,4030],{},"            if (minRPM > maxRPM)\n",[1099,4032,4034],{"class":1101,"line":4033},103,[1099,4035,3311],{},[1099,4037,4039],{"class":1101,"line":4038},104,[1099,4040,4041],{},"                throw new IllegalArgumentException(\"min RPM is above max RPM\");\n",[1099,4043,4045],{"class":1101,"line":4044},105,[1099,4046,3321],{},[1099,4048,4050],{"class":1101,"line":4049},106,[1099,4051,4052],{},"            return new MotorConfig(this);\n",[1099,4054,4056],{"class":1101,"line":4055},107,[1099,4057,3346],{},[1099,4059,4061],{"class":1101,"line":4060},108,[1099,4062,1309],{},[1099,4064,4066],{"class":1101,"line":4065},109,[1099,4067,1406],{},[1085,4069,4070,4072,4073,4075,4076,4078,4079,4081,4082,4084,4085,4087,4088,4090,4091,4093,4094,4097,4098,4101,4102,4105,4106,4109],{},[1116,4071,2703],{}," Each setter ends with ",[1096,4074,1523],{},", which is what lets ",[1096,4077,1841],{}," chain them, and the target class's constructor is ",[1096,4080,1213],{}," so the only way in is through ",[1096,4083,1135],{},". The\n",[1096,4086,3101],{}," constructor copies the builder's finished values into ",[1096,4089,1415],{}," fields. Because ",[1096,4092,1135],{}," is the one place the object is created, it is also the place to validate. The\nhidden scenarios catch two common mistakes: no validation at all (the ",[1096,4095,4096],{},"min > max"," case builds a nonsense config), and a ",[1096,4099,4100],{},">="," check that wrongly rejects ",[1096,4103,4104],{},"min == max",".\nA builder that forgets to copy a field into the constructor shows up as ",[1096,4107,4108],{},"0.0"," values in the output.",[1750,4111,1752],{},{"title":1094,"searchDepth":1149,"depth":1149,"links":4113},[4114,4115,4116],{"id":2602,"depth":1149,"text":2603},{"id":2742,"depth":1149,"text":2743},{"id":3086,"depth":1149,"text":3087},{"outlineRef":1768,"pairsWith":2589,"status":4118},"new — authored exercises (Multiple Choice + Micro-Parsons + Coding)",{"title":1004,"description":1094},"nyig7u2CFHa-CYef_QVlmEeS9Ihk2y_0bBJMsaAYues",1792718166186]