diff --git a/.github/workflows/deploy-gh-pages.yaml b/.github/workflows/deploy-gh-pages.yaml index 37710be..d097334 100644 --- a/.github/workflows/deploy-gh-pages.yaml +++ b/.github/workflows/deploy-gh-pages.yaml @@ -3,7 +3,7 @@ name: Deploy mdBook to GH Pages on: push: branches: - - 'master' + - "master" jobs: deploy: @@ -16,7 +16,7 @@ jobs: - name: Setup mdBook uses: peaceiris/actions-mdbook@v1.2.0 with: - mdbook-version: 'latest' + mdbook-version: "latest" - run: mdbook build diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 86ed01e..0d1d43e 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,28 +7,27 @@ name: Mark stale issues and pull requests on: schedule: - - cron: '0 7 * * *' + - cron: "0 7 * * *" jobs: stale: - runs-on: ubuntu-latest permissions: issues: write pull-requests: write steps: - - uses: actions/stale@v4 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label, comment or add the valid label or this will be closed in 5 days.' - stale-pr-message: 'This pull request is stale because it has been open 30 days with no activity. Remove stale label, comment or add the valid label or this will be closed in 5 days.' - stale-issue-label: 'stale' - stale-pr-label: 'stale' - close-issue-label: 'inactivity-closed' - close-pr-label: 'inactivity-closed' - labels-to-add-when-unstale: 'valid' - exempt-issue-labels: 'valid,good first issue' - exempt-pr-labels: 'valid,good first issue' - days-before-stale: 30 - days-before-close: 5 + - uses: actions/stale@v4 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label, comment or add the valid label or this will be closed in 5 days." + stale-pr-message: "This pull request is stale because it has been open 30 days with no activity. Remove stale label, comment or add the valid label or this will be closed in 5 days." + stale-issue-label: "stale" + stale-pr-label: "stale" + close-issue-label: "inactivity-closed" + close-pr-label: "inactivity-closed" + labels-to-add-when-unstale: "valid" + exempt-issue-labels: "valid,good first issue" + exempt-pr-labels: "valid,good first issue" + days-before-stale: 30 + days-before-close: 5 diff --git a/.markdownlint.yaml b/.markdownlint.yaml index e07b360..5f5da14 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -5,4 +5,4 @@ MD007: MD013: line_length: 300 MD033: - allowed_elements: ["iframe", "sup"] \ No newline at end of file + allowed_elements: ["iframe", "sup"] diff --git a/README.md b/README.md index ca5cae3..2bf6e44 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Book teaching how to write modern and effective Java. It is maintained by the community, anyone can contribute. -Feel free to join our [discord server](https://discord.com/invite/XXFUXzK) +Feel free to join our [discord server](https://discord.gg/together-java-272761734820003841) if you have any questions, or require assistance with the project. :relaxed: ## Getting started diff --git a/book.toml b/book.toml index 5a16912..0666248 100644 --- a/book.toml +++ b/book.toml @@ -9,16 +9,17 @@ multilingual = false git-repository-url = "https://github.com/Together-Java/ModernJava" edit-url-template = "https://github.com/Together-Java/ModernJava/edit/develop/{path}" mathjax-support = true +additional-css = ["ferris.css"] +additional-js = ["ferris.js"] [output.html.fold] -enable = true # whether or not to enable section folding -level = 0 # the depth to start folding +enable = true # whether or not to enable section folding +level = 0 # the depth to start folding -[preprocessor.features] -command = "python3 features.java" -# Not ready -toplevel_anonymous_class = false -# Not ready -simple_io = false -# Turn on when Java 21 released -java_21 = false \ No newline at end of file +[output.html.playground] +editable = true + +[output.html.code.hidelines] +java = "~" +[output.html.code.hidelines] +java = "~" diff --git a/features.java b/features.java deleted file mode 100755 index f3fb5e4..0000000 --- a/features.java +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 - -# This file is python, not Java. -# but we got enough people complaining that the repo in github showed 100% python -# that I just changed the extension to .java - I think its funny. We can replace -# this file if either a json library is added to java or someone wants to do all -# the setup to pull in a json lib. - -import json -import sys - -def preprocess_content(context, content): - options = context.get("config", {}).get("preprocessor", {}).get("features", {}) - newContent = [] - skipping = False - for line in content.splitlines(): - if skipping: - if line.strip() == "~ENDIF" or line.strip() == "~ ENDIF": - skipping = False - elif line.strip() == "~ELSE" or line.strip() == "~ ELSE": - skipping = False - elif line.strip().startswith("~IF ") or line.strip().startswith("~ IF "): - if not options.get(line.split(" ", 2)[1].strip(), False): - skipping = True - elif line.strip() == "~ENDIF" or line.strip() == "~ ENDIF": - continue - elif line.strip() == "~ELSE" or line.strip() == "~ ELSE": - skipping = True - continue - else: - if options.get("simple_io", False) and options.get("toplevel_anonymous_class", False): - newContent.append(line.replace("System.out.println", "println").replace("System.out.print", "print")) - else: - newContent.append(line) - - return "\n".join(newContent) - -def preprocess_section(context, section): - if "Chapter" in section: - section["Chapter"]["content"] = \ - preprocess_content(context, section["Chapter"]["content"]) - for sub_section in section["Chapter"].get("sub_items", []): - preprocess_section(context, sub_section) - -if __name__ == '__main__': - if len(sys.argv) > 1: - if sys.argv[1] == "supports": - sys.exit(0) - - context, book = json.load(sys.stdin) - - for section in book["sections"]: - preprocess_section(context, section) - - print(json.dumps(book)) \ No newline at end of file diff --git a/ferris.css b/ferris.css new file mode 100644 index 0000000..6cc9f07 --- /dev/null +++ b/ferris.css @@ -0,0 +1,45 @@ +body.light .does_not_compile, +body.light .panics, +body.light .not_desired_behavior, +body.rust .does_not_compile, +body.rust .panics, +body.rust .not_desired_behavior { + background: #fff1f1; +} + +body.coal .does_not_compile, +body.coal .panics, +body.coal .not_desired_behavior, +body.navy .does_not_compile, +body.navy .panics, +body.navy .not_desired_behavior, +body.ayu .does_not_compile, +body.ayu .panics, +body.ayu .not_desired_behavior { + background: #501f21; +} + +.ferris-container { + position: absolute; + z-index: 99; + right: 5px; + top: 30px; +} + +.ferris { + vertical-align: top; + margin-left: 0.2em; + height: auto; +} + +.ferris-large { + width: 4.5em; +} + +.ferris-small { + width: 2.3em; +} + +.ferris-explain { + width: 100px; +} diff --git a/ferris.js b/ferris.js new file mode 100644 index 0000000..f78ce4a --- /dev/null +++ b/ferris.js @@ -0,0 +1,65 @@ +var ferrisTypes = [ + { + attr: 'does_not_compile', + title: 'This code does not compile!' + }, + { + attr: 'panics', + title: 'This code will crash!' + }, + { + attr: 'not_desired_behavior', + title: 'This code does not produce the desired behavior.' + } +] + +document.addEventListener('DOMContentLoaded', () => { + for (var ferrisType of ferrisTypes) { + attachFerrises(ferrisType) + } +}) + +function attachFerrises(type) { + var elements = document.getElementsByClassName(type.attr) + + for (var codeBlock of elements) { + var lines = codeBlock.innerText.replace(/\n$/, '').split(/\n/).length + var size = 'large' + if (lines < 5) { + size = 'small' + } + + var container = prepareFerrisContainer(codeBlock, size == 'small') + container.appendChild(createFerris(type, size)) + } +} + +function prepareFerrisContainer(element, useButtons) { + var foundButtons = element.parentElement.querySelector('.buttons') + if (useButtons && foundButtons) { + return foundButtons + } + + var div = document.createElement('div') + div.classList.add('ferris-container') + + element.parentElement.insertBefore(div, element) + + return div +} + +function createFerris(type, size) { + var a = document.createElement('a') + // a.setAttribute('href', 'ch00-00-introduction.html#ferris') + a.setAttribute('target', '_blank') + + var img = document.createElement('img') + img.setAttribute('src', '../img/' + type.attr + '.svg') + img.setAttribute('title', type.title) + img.classList.add('ferris') + img.classList.add('ferris-' + size) + + a.appendChild(img) + + return a +} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index fa5ac49..725b3cd 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -17,161 +17,304 @@ # Modern Java - [Prelude](./prelude.md) - - [Asking for Help](./prelude/asking_for_help.md) - - [Toy Problems](./prelude/toy_problems.md) - - [Lies](./prelude/lies.md) + - [Asking for Help](./prelude/asking_for_help.md) + - [Toy Problems](./prelude/toy_problems.md) + - [Lies](./prelude/lies.md) - [Getting Started](./getting_started.md) - [First Steps](./first_steps.md) - - [Comments](./first_steps/comments.md) - - [Semicolons](./first_steps/semicolon.md) - - [Formatting](./first_steps/formatting.md) - - [Challenges](./first_steps/challenges.md) + - [Comments](./first_steps/comments.md) + - [Semicolons](./first_steps/semicolon.md) + - [Formatting](./first_steps/formatting.md) + - [Challenges](./first_steps/challenges.md) - [Local Variables](./variables.md) - - [Naming](./variables/naming.md) - - [Reassignment](./variables/reassignment.md) - - [Delayed Assignment](./variables/delayed_assignment.md) - - [Types](./variables/types.md) - - [Final Variables](./variables/final_variables.md) - - [Inferred Types](./variables/inferred_types.md) - - [Challenges](./variables/challenges.md) + - [Naming](./variables/naming.md) + - [Reassignment](./variables/reassignment.md) + - [Delayed Assignment](./variables/delayed_assignment.md) + - [Types](./variables/types.md) + - [Final Variables](./variables/final_variables.md) + - [Inferred Types](./variables/inferred_types.md) + - [Challenges](./variables/challenges.md) # Data Types I - [Booleans](./boolean.md) - - [And](./boolean/and.md) - - [Or](./boolean/or.md) - - [Not](./boolean/not.md) - - [Operator Precedence](./boolean/operator_precedence.md) - - [Challenges](./boolean/challenges.md) + - [And](./boolean/and.md) + - [Or](./boolean/or.md) + - [Not](./boolean/not.md) + - [Operator Precedence](./boolean/operator_precedence.md) + - [Challenges](./boolean/challenges.md) - [Integers](./integers.md) - - [Integer Literals](./integers/integer_literals.md) - - [Addition](./integers/addition.md) - - [Subtraction](./integers/subtraction.md) - - [Multiplication](./integers/multiplication.md) - - [Division](./integers/division.md) - - [Remainder](./integers/remainder.md) - - [Equality](./integers/equality.md) - - [Comparison](./integers/comparison.md) - - [Chained Comparisons](./integers/chained_comparisons.md) - - [Operator Precedence](./integers/operator_precedence.md) - - [Reassignment](./integers/reassignment.md) - - [Shorthands for Reassignment](./integers/shorthands_for_reassignment.md) - - [Limits](./integers/limits.md) - - [Challenges](./integers/challenges.md) + - [Integer Literals](./integers/integer_literals.md) + - [Addition](./integers/addition.md) + - [Subtraction](./integers/subtraction.md) + - [Multiplication](./integers/multiplication.md) + - [Division](./integers/division.md) + - [Remainder](./integers/remainder.md) + - [Equality](./integers/equality.md) + - [Comparison](./integers/comparison.md) + - [Chained Comparisons](./integers/chained_comparisons.md) + - [Operator Precedence](./integers/operator_precedence.md) + - [Reassignment](./integers/reassignment.md) + - [Shorthands for Reassignment](./integers/shorthands_for_reassignment.md) + - [Limits](./integers/limits.md) + - [Challenges](./integers/challenges.md) - [Floating Point Numbers](./floating_point_numbers.md) - - [Floating Point Literals](./floating_point_numbers/floating_point_literals.md) - - [Accuracy](./floating_point_numbers/accuracy.md) - - [Addition](./floating_point_numbers/addition.md) - - [Subtraction](./floating_point_numbers/subtraction.md) - - [Multiplication](./floating_point_numbers/multiplication.md) - - [Division](./floating_point_numbers/division.md) - - [Equality](./floating_point_numbers/equality.md) - - [Comparison](./floating_point_numbers/comparison.md) - - [Shorthands for Reassignment](./floating_point_numbers/shorthands_for_reassignment.md) - - [NaN](./floating_point_numbers/nan.md) - - [Positive and Negative Infinity](./floating_point_numbers/positive_and_negative_infinity.md) - - [Square Root](./floating_point_numbers/square_root.md) - - [Conversion to Integers](./floating_point_numbers/conversion_to_integers.md) - - [Conversion from Integers](./floating_point_numbers/conversion_from_integers.md) - - [Challenges](./floating_point_numbers/challenges.md) + - [Floating Point Literals](./floating_point_numbers/floating_point_literals.md) + - [Accuracy](./floating_point_numbers/accuracy.md) + - [Addition](./floating_point_numbers/addition.md) + - [Subtraction](./floating_point_numbers/subtraction.md) + - [Multiplication](./floating_point_numbers/multiplication.md) + - [Division](./floating_point_numbers/division.md) + - [Equality](./floating_point_numbers/equality.md) + - [Comparison](./floating_point_numbers/comparison.md) + - [Shorthands for Reassignment](./floating_point_numbers/shorthands_for_reassignment.md) + - [NaN](./floating_point_numbers/nan.md) + - [Positive and Negative Infinity](./floating_point_numbers/positive_and_negative_infinity.md) + - [Square Root](./floating_point_numbers/square_root.md) + - [Conversion to Integers](./floating_point_numbers/conversion_to_integers.md) + - [Conversion from Integers](./floating_point_numbers/conversion_from_integers.md) + - [Challenges](./floating_point_numbers/challenges.md) - [Characters](./characters.md) - - [Character Literals](./characters/character_literals.md) - - [Common Escape Sequences](./characters/common_escape_sequences.md) - - [Conversion to Integers](./characters/conversion_to_integers.md) - - [Conversion from Integers](./characters/conversion_from_integers.md) - - [Unicode](./characters/unicode.md) - - [Challenges](./characters/challenges.md) + - [Character Literals](./characters/character_literals.md) + - [Common Escape Sequences](./characters/common_escape_sequences.md) + - [Conversion to Integers](./characters/conversion_to_integers.md) + - [Conversion from Integers](./characters/conversion_from_integers.md) + - [Unicode](./characters/unicode.md) + - [Challenges](./characters/challenges.md) - [Strings](./strings.md) - - [String Literals](./strings/string_literals.md) - - [Common Escape Sequences](./strings/common_escape_sequences.md) - - [The Empty String](./strings/empty_string.md) - - [Multiline String Literals](./strings/multiline.md) - - [Concatenation](./strings/concatenation.md) - - [Equality](./strings/equality.md) - - [Length](./strings/length.md) - - [Access Individual Characters](./strings/access_individual_characters.md) - - [Challenges](./strings/challenges.md) + - [String Literals](./strings/string_literals.md) + - [Common Escape Sequences](./strings/common_escape_sequences.md) + - [The Empty String](./strings/empty_string.md) + - [Multiline String Literals](./strings/multiline.md) + - [Concatenation](./strings/concatenation.md) + - [Equality](./strings/equality.md) + - [Length](./strings/length.md) + - [Access Individual Characters](./strings/access_individual_characters.md) + - [Challenges](./strings/challenges.md) # Control Flow I - [Branching Paths](./branching_paths.md) - - [If](./branching_logic/if.md) - - [Else](./branching_logic/else.md) - - [Nested Ifs](./branching_logic/nested_ifs.md) - - [Else If](./branching_logic/else_if.md) - - [Relation to Delayed Assignment](./branching_logic/relation_to_delayed_assignment.md) - - [Conditional Operator](./branching_logic/conditional_operator.md) - - [Boolean Expressions](./branching_logic/boolean_expressions.md) - - [Challenges](./branching_logic/challenges.md) + + - [If](./branching_logic/if.md) + - [Nested Ifs](./branching_logic/nested_ifs.md) + - [Else](./branching_logic/else.md) + - [Else](./branching_logic/else.md) + - [Else If](./branching_logic/else_if.md) + - [Relation to Delayed Assignment](./branching_logic/relation_to_delayed_assignment.md) + - [Scoped Variables](./branching_logic/scoped_variables.md) + - [Scoped Variables](./branching_logic/scoped_variables.md) + - [Conditional Operator](./branching_logic/conditional_operator.md) + - [Boolean Expressions](./branching_logic/boolean_expressions.md) + - [Challenges](./branching_logic/challenges.md) + + - [Loops](./loops.md) - - [While](./loops/while.md) - - [Endless Loops](./loops/endless_loops.md) - - [Break](./loops/break.md) - - [Continue](./loops/continue.md) - - [Unreachable Code](./loops/unreachable_code.md) - - [Do While](./loops/do_while.md) - - [Nested Loops](./loops/nested_loops.md) - - [Labeled Break](./loops/labeled_break.md) - - [Labeled Continue](./loops/labeled_continue.md) - - [Iteration](./loops/iteration.md) - - [Counting Up](./loops/counting_up.md) - - [Counting Down](./loops/counting_down.md) - - [Iterate over a String](./loops/iterate_over_a_string.md) - - [Challenges](./loops/challenges.md) + - [While](./loops/while.md) + - [Endless Loops](./loops/endless_loops.md) + - [Break](./loops/break.md) + - [Continue](./loops/continue.md) + - [Unreachable Code](./loops/unreachable_code.md) + - [Do While](./loops/do_while.md) + - [Nested Loops](./loops/nested_loops.md) + - [Labeled Break](./loops/labeled_break.md) + - [Labeled Continue](./loops/labeled_continue.md) + - [Iteration](./loops/iteration.md) + - [Counting Up](./loops/counting_up.md) + - [Counting Down](./loops/counting_down.md) + - [Iterate over a String](./loops/iterate_over_a_string.md) + - [Challenges](./loops/challenges.md) # Data Types II - [Arrays](./arrays.md) - - [Array Initializers](./arrays/array_initializers.md) - - [Length](./arrays/length.md) - - [Access Individual Elements](./arrays/access_individual_elements.md) - - [Set Individual Elements](./arrays/set_individual_elements.md) - - [Aliasing](./arrays/aliasing.md) - - [Reassignment](./arrays/reassignment.md) - - [Relation to Final Variables](./arrays/relation_to_final_variables.md) - - [Printing the Contents of an Array](./arrays/printing_the_contents_of_an_array.md) - - [Empty Array](./arrays/empty_array.md) - - [Difference between Initializer and Literal](./arrays/difference_between_initializer_and_literal.md) - - [Challenges](./arrays/challenges) + - [Array Initializers](./arrays/array_initializers.md) + - [Length](./arrays/length.md) + - [Access Individual Elements](./arrays/access_individual_elements.md) + - [Set Individual Elements](./arrays/set_individual_elements.md) + - [Aliasing](./arrays/aliasing.md) + - [Reassignment](./arrays/reassignment.md) + - [Relation to Final Variables](./arrays/relation_to_final_variables.md) + - [Printing the Contents of an Array](./arrays/printing_the_contents_of_an_array.md) + - [Empty Array](./arrays/empty_array.md) + - [Difference between Initializer and Literal](./arrays/difference_between_initializer_and_literal.md) + - [Challenges](./arrays/challenges.md) # Control Flow II - +- [Arguments](./arguments.md) -# User Defined Types + - [Declaration](./arguments/declaration.md) + - [Invocation with Arguments](./arguments/invocation_with_arguments.md) + - [Reassignment](./arguments/reassignment.md) + - [Final Arguments](./arguments/final_arguments.md) + - [Aliasing](./arguments/aliasing.md) + - [Overloading](./arguments/overloading.md) + - [Inferred Types](./arguments/inferred_types.md) + - [Challenges](./arguments/challenges.md) + +- [Return Values](./return_values.md) + - [Declaration](./return_values/declaration.md) + - [Return Statement](./return_values/return_statement.md) + - [Exhaustiveness](./return_values/exhaustiveness.md) + - [void](./return_values/void.md) + - [Return in void methods](./return_values/return_in_void_methods.md) + - [Conversion](./return_values/conversion.md) + - [Unreachable Statements](./return_values/unreachable_statements.md) + +# Data Types III + +- [null](./null.md) + - [Null as Absence](./null/null_as_absence.md) + - [Null as Unknown](./null/null_as_unknown.md) + - [Checking for null](./null/checking_for_null.md) + - [NullPointerException](./null/null_pointer_exception.md) +- [Boxed Primitives](./boxed_primitives.md) + - [Integer](./boxed_primitives/integer.md) + - [Double](./boxed_primitives/double.md) + - [Character](./boxed_primitives/character.md) + - [Boolean](./boxed_primitives/boolean.md) + - [Unboxing Conversion](./boxed_primitives/unboxing_conversion.md) + - [Boxing Conversion](./boxed_primitives/boxing_conversion.md) + - [Arrays of Boxed Primitives](./boxed_primitives/arrays_of_boxed_primitives.md) + - [Challenges](./boxed_primitives/challenges.md) + - [Challenges](./boxed_primitives/challenges.md) +- [Arrays II](./arrays_ii.md) + - [Initializion with Size](./arrays_ii/initialization_with_size.md) + - [Default Values](./arrays_ii/default_values.md) + - [Populate Arrays](./arrays_ii/populate_arrays.md) + +# Code Structure II - [Classes](./classes.md) - - [Primitive Classes](./classes/primitive_classes.md) - - [Reference Classes](./classes/reference_classes.md) - - [null](./classes/null.md) - - [Class Declaration](./classes/class_declaration.md) - - [Naming](./classes/naming.md) -- [Fields](./fields.md) - - [Default Values](./fields/default_values.md) -- [Methods](./methods.md) - - [Arguments](./methods/arguments.md) - - [Return Values](./methods/return_values.md) - - [void](./methods/void.md) + - [The meaning of the word Class](./classes/the_meaning_of_the_word_class.md) + - [Class Declaration](./classes/class_declaration.md) + - [Naming](./classes/naming.md) + - [Instances](./classes/instances.md) + - [Fields](./classes/fields.md) + - [Field Initialization](./classes/field_initialization.md) + - [Field Access](./classes/field_access.md) + - [Field Default Values](./classes/field_default_values.md) + - [Aliasing](./classes/aliasing.md) + - [Return Multiple Values](./classes/return_multiple_values.md) + +- [Instance Methods](./instance_methods.md) + - [Invocation](./instance_methods/invocation.md) + - [Arguments](./instance_methods/arguments.md) + - [Field Access](./instance_methods/field_access.md) + - [Field Updates](./instance_methods/field_updates.md) + - [Derived Values](./instance_methods/derived_values.md) + - [Invoke Other Methods](./instance_methods/invoke_other_methods.md) + - [this](./instance_methods/this.md) + - [Disambiguation](./instance_methods/disambiguation.md) + - [Clarity](./instance_methods/clarity.md) + +# Data Types IV + +- [Enums](./enums.md) + - [Declaration](./enums/declaration.md) + - [Variants](./enums/variants.md) + - [Naming](./enums/naming.md) + - [Usage](./enums/usage.md) + - [Equality](./enums/equality.md) + - [Comparison to boolean](./enums/comparison_to_boolean.md) + +# Control Flow III + +- [Exceptions](./exceptions.md) + - [throw](./exceptions/throw.md) + - [Messages](./exceptions/messages.md) + - [Stack Traces](./exceptions/stack_traces.md) + - [try/catch](./exceptions/try_catch.md) +- [Switch](./switch.md) + - [Case and Default](./switch/case_and_default.md) + - [Strings](./switch/strings.md) + - [ints](./switch/ints.md) + - [Enums](./switch/enums.md) + - [Omitted Default](./switch/omitted_default.md) + - [Exhaustiveness](./switch/exhaustiveness.md) + - [Combining Cases](./switch/combining_cases.md) + - [null](./switch/null.md) + +# Code Structure III + - [Constructors](./constructors.md) + - [Declaration](./constructors/declaration.md) + - [The Default Constructor](./constructors/the_default_constructor.md) + - [Arguments](./constructors/arguments.md) + - [Final Fields](./constructors/final_fields.md) + - [Invariants](./constructors/invariants.md) + - [Overloads](./constructors/overloads.md) + - [Delegation](./constructors/delegation.md) + + \ No newline at end of file +--> diff --git a/src/arguments.md b/src/arguments.md new file mode 100644 index 0000000..026bd52 --- /dev/null +++ b/src/arguments.md @@ -0,0 +1,18 @@ +# Arguments + +If methods always had to do the same thing each time they were run, they wouldn't be that useful. + +The way to customize what happens when a method is called is to have them take "arguments." + +```java +void sayHello(String name) { + System.out.println("Hello " + name + "!"); +} + +void main() { + // Hello Joshua! + sayHello("Joshua"); + // Hello Claire! + sayHello("Claire"); +} +``` diff --git a/src/arguments/aliasing.md b/src/arguments/aliasing.md new file mode 100644 index 0000000..a27b6dc --- /dev/null +++ b/src/arguments/aliasing.md @@ -0,0 +1,28 @@ +# Aliasing + +Because arguments work like variables, if you pass something +like an array as an argument the array referenced by the argument will be the exact same as the array referenced by the variable given to the method. + +```java +void incrementFirst(int[] numbers) { + numbers[0] = numbers[0] + 1; +} + +void main() { + int[] nums = new int[] { 8 }; + + // The first number is 8 + System.out.println( + "The first number is " + nums[0] + ); + + incrementFirst(nums); + + // Now it is 9 + System.out.println( + "Now it is " + nums[0] + ); +} +``` + +The argument aliases the value passed to the method. diff --git a/src/arguments/challenges.md b/src/arguments/challenges.md new file mode 100644 index 0000000..cc83488 --- /dev/null +++ b/src/arguments/challenges.md @@ -0,0 +1,55 @@ +# Challenges + +Remember the rules for this are + +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt + +## Challenge 1. + +Write a method named `printSquare` which takes one `int` argument named `size`. + +The `size` argument should control how big of a square is output. + +```java,editable +// CODE HERE + +void main() { + printSquare(4); + System.out.println(); + + printSquare(3); + System.out.println(); + + printSquare(2); + System.out.println(); + + printSquare(1); + System.out.println(); +} +``` + +## Challenge 2. + +What happens if a negative number is given to your `printSquare`? + +Make it so that if a negative number is given, it works the same as if a positive number +was given. + +```java,editable +// CODE HERE + +void main() { + printSquare(3); + System.out.println(); + printSquare(-3); + System.out.println(); + + System.out.println(); + printSquare(-2); + System.out.println(); + printSquare(2); +} +``` + +## Challenge 3. diff --git a/src/arguments/declaration.md b/src/arguments/declaration.md new file mode 100644 index 0000000..fad2eb4 --- /dev/null +++ b/src/arguments/declaration.md @@ -0,0 +1,23 @@ +# Declaration + +To declare a method which takes arguments, instead of putting `()` after the method name +you need to put a comma separated list of argument declarations. + +Each argument declaration looks the same as a variable declaration and has both a type and a name. + +```java,no_run +// This declares a single argument named "food" that +// has a type of "String". +void eat(String food) { + System.out.println("I ate " + food); +} + +// This declares two arguments +// "to", which is a String and +// "age", which is an int. +void happyBirthday(String to, int age) { + System.out.println( + "Happy " + age + "th birthday " + to + "!" + ); +} +``` diff --git a/src/arguments/final_arguments.md b/src/arguments/final_arguments.md new file mode 100644 index 0000000..70903f6 --- /dev/null +++ b/src/arguments/final_arguments.md @@ -0,0 +1,35 @@ +# Final Arguments + +Just like normal variable declarations, arguments can be marked +`final`. This makes it so that they cannot be reassigned. + +```java +void eat(final String food) { + System.out.println("I ate " + food); +} + +void main() { + eat("Welsh Rarebit"); +} +``` + +If you try to reassign a final argument, Java will not accept your program. + +```java,panics +void eat(final String food) { + System.out.println("I ate " + food); + // Will not work + food = "toast"; + System.out.println(food); +} + +void main() { + eat("Welsh Rarebit"); +} +``` + +This has the same use as regular final variables. If there are lots of lines +of code where a variable might be reassigned, it can be useful to not have +to read all that code to know that it does happen.[^opinion] + +[^opinion]: Adding `final` to all arguments can make it harder to read the code, simply because of visual noise. diff --git a/src/arguments/inferred_types.md b/src/arguments/inferred_types.md new file mode 100644 index 0000000..5426118 --- /dev/null +++ b/src/arguments/inferred_types.md @@ -0,0 +1,27 @@ +# Inferred Types + +With variable declarations, you can use `var` to let Java figure out the type +of the variable. + +```java,no_run +var name = "Jupiter"; +``` + +This is _not_ allowed with argument declarations. + +```java,does_not_compile,no_run +// You aren't allowed to use var for arguments! +void makeHorchata(var milkFatPercent) { + // ... +} +``` + +You must always explicitly write out the types of arguments. + +```java,no_run +void makeHorchata(double milkFatPercent) { + System.out.println( + "Making a horchata with " + milkFatPercent + "% milk." + ); +} +``` diff --git a/src/arguments/invocation_with_arguments.md b/src/arguments/invocation_with_arguments.md new file mode 100644 index 0000000..1c8800f --- /dev/null +++ b/src/arguments/invocation_with_arguments.md @@ -0,0 +1,31 @@ +# Invocation with Arguments + +To invoke a method which takes arguments you need to, instead of writing +`()` after the method name, write `(` followed by a comma separated list +of literals or variable names ending with `)`. + +```java +void eat(String food) { + System.out.println("I ate " + food); +} + +void happyBirthday(String to, int age) { + System.out.println( + "Happy " + age + "th birthday " + to + "!" + ); +} + +void main() { + // This calls the 'eat' method with the String "cake" + // as an argument. + eat("Cake"); + + // You can also call methods using values stored in + // variables. + String veggie = "carrot"; + eat(veggie); + + // For more than one argument, you separate them with commas + happyBirthday("Charlotte", 24); +} +``` diff --git a/src/arguments/overloading.md b/src/arguments/overloading.md new file mode 100644 index 0000000..c96dcf5 --- /dev/null +++ b/src/arguments/overloading.md @@ -0,0 +1,49 @@ +# Overloading + +Multiple methods can be declared that have the same name. +This is allowed so long as each method takes different types +or different numbers of arguments. + +```java,no_run +void doThing(int x) { + System.out.println(x); +} + +void doThing(String name) { + System.out.println("Hello " + name); +} + +void doThing(int x, int y) { + System.out.println(x + y); +} +``` + +When you call the method, Java will know what code to run +because it knows the types of and number of arguments +you are passing. + +```java +void doThing(int x) { + System.out.println(x); +} + +void doThing(String name) { + System.out.println("Hello " + name); +} + +void doThing(int x, int y) { + System.out.println(x + y); +} + +void main() { + // Java can figure out what to do + doThing(1); + doThing("abc"); + doThing(1, 2); +} +``` + +When there are multiple methods that have the same name but take different arguments, +those methods are considered "overloads" of eachother[^overload] + +[^overload]: "Overloading" in this context means when one word has more than one possible meaning depending on how it is used. Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. \ No newline at end of file diff --git a/src/arguments/reassignment.md b/src/arguments/reassignment.md new file mode 100644 index 0000000..df04c0d --- /dev/null +++ b/src/arguments/reassignment.md @@ -0,0 +1,36 @@ +# Reassignment + +Inside of a method, arguments work the same as normal variable declarations. +This means that their value can be reassigned +within the method body; + +```java +void eat(String food) { + System.out.println("I ate " + food); + food = "nothing"; + System.out.println("Now I have " + food); +} + +void main() { + eat("Cake"); +} +``` + +Reassigning an argument's value will not affect the value assigned to +any variables passed to the method by the caller. + +```java +void eat(String food) { + System.out.println("I ate " + food); + food = "nothing"; + System.out.println("Now I have " + food) +} + +void main() { + String fruit = "apple"; + eat(fruit); + System.out.println( + "But in the caller I still have an " + fruit + ); +} +``` diff --git a/src/arrays.md b/src/arrays.md index f66c16b..328ab33 100644 --- a/src/arrays.md +++ b/src/arrays.md @@ -2,7 +2,7 @@ Arrays are used to represent a fixed-size collection of things. -```java +```java,no_run int[] oddNumbers = { 1, 3, 5, 7, 9 }; ``` @@ -14,7 +14,7 @@ We call the things stored in an array its "elements." You can make an array of any type of element by using the name of the type followed by `[]`. -```java +```java,no_run char[] letters = { 'a', 'b', 'c' }; String[] words = { "its", "as", "easy", "as" } int[] numbers = { 1, 2, 3 }; diff --git a/src/arrays/access_individual_elements.md b/src/arrays/access_individual_elements.md index 1ff35dd..17eb48e 100644 --- a/src/arrays/access_individual_elements.md +++ b/src/arrays/access_individual_elements.md @@ -7,6 +7,7 @@ You write the name of a variable containing an array, `[`, a number, and then a The first element can be accessed by using `0`, the second by using `1`, and so on. ```java +~void main(){ String[] lyrics = { "you", "say", "goodbye" }; String you = lyrics[0]; @@ -17,28 +18,35 @@ System.out.println(say); String goodbye = lyrics[2]; System.out.println(goodbye); +~} ``` The index of the element can also come from a variable. ```java +~void main(){ int index = 2; String[] lyrics = { "I", "say", "hello" }; System.out.println(lyrics[index]); +~} ``` If you give a number equal to or greater than the length of the array or a number less than zero, you will get an error. -```java +```java,panics +~void main(){ String[] lyrics = { "I", "say", "hi" }; // Crash! -lyrics[999]; +System.out.println(lyrics[999]); +~} ``` -```java +```java,panics +~void main(){ String[] lyrics = { "you", "say", "low" }; // Crash! -lyrics[-1]; +System.out.println(lyrics[-1]); +~} ``` diff --git a/src/arrays/aliasing.md b/src/arrays/aliasing.md index 4330f54..8ac0622 100644 --- a/src/arrays/aliasing.md +++ b/src/arrays/aliasing.md @@ -7,6 +7,7 @@ This means that if the contents of the array are updated, that change will be reflected by both variables. ```java +~void main() { char[] lettersOne = { 'B', 'a', 't', 'm', 'a', 'n' }; char[] lettersTwo = lettersOne; @@ -28,6 +29,7 @@ lettersTwo[0] = 'R'; System.out.println(lettersOne); // Ratman System.out.println(lettersTwo); +~} ``` When two variables point to the same thing like this we say that both variables are "aliases" diff --git a/src/arrays/array_initializers.md b/src/arrays/array_initializers.md index e5e0ac5..f222212 100644 --- a/src/arrays/array_initializers.md +++ b/src/arrays/array_initializers.md @@ -2,10 +2,10 @@ To give an initial value to an array you can use an array initializer. -After the equals sign you write `{` followed by a comma separated list of elements and a final `}`. +After the equals sign you write `{` followed by a comma separated list of elements and a final `}`. -```java -int[] numbers = { 1, 2, 3 } +```java,no_run +int[] numbers = { 1, 2, 3 }; // |---------| // this part is // the initializer @@ -13,13 +13,12 @@ int[] numbers = { 1, 2, 3 } The elements in an initializer do not have to be literals and can also be variables or expressions. -```java +```java,no_run int two = 2; -// Will hold 1, 2, 3 just like the array above +// Will hold 1, 2, 3 just like the array above int[] numbers = { 1, two, two + 1 } ``` We call them array initializers because you use them to give an initial value to an array.[^pattern] -[^pattern]: You may be noticing a pattern. Confusing sounding names are often kinda "obvious" -with enough context. +[^pattern]: You may be noticing a pattern. Confusing sounding names are often kinda "obvious" with enough context. diff --git a/src/arrays/challenges.md b/src/arrays/challenges.md new file mode 100644 index 0000000..c210ab0 --- /dev/null +++ b/src/arrays/challenges.md @@ -0,0 +1,83 @@ +# Challenges + +Remember the rules for this are + +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt + +## Challenge 1 + +Edit the following program so that the output is zero. + +```java,editable +void main() { + // Only change this line + String[] words = { "Sam", "I", "Am" }; + System.out.println(array.length); +} +``` + +## Challenge 2 + +Using only `System.out.println` and array accesses, +print `hello world` to the screen. + +```java,editable +void main() { + char[] letters = { + ' ', + 'h', + 'e', + 'l', + 'o', + 'w', + 'r', + 'd' + }; + + // Your code here +} +``` + +## Challenge 3 + +Without editing either the array declaration or the loop at the bottom, +make the output of this program `0`. + +```java,editable +void main() { + final int[] numbers = { 1, 2, 3, 4 }; + + // ----------- + // YOUR CODE HERE + + + // ----------- + int total = 0; + int index = 0; + while (index < numbers.length) { + total += numbers[index]; + index += 1; + } + System.out.println(total); +} +``` + +## Challenge 4 + +Make this program output `bulbasaur` without changing anything +above or below the marked areas. + +```java,editable +void main() { + char[] name = { 'b', 'u', 'l', 'b' }; + + // ----------- + // YOUR CODE HERE + + + // ----------- + char[] toPrint = name; + System.out.println(toPrint); +} +``` diff --git a/src/arrays/empty_array.md b/src/arrays/empty_array.md index ddf683a..12f8da9 100644 --- a/src/arrays/empty_array.md +++ b/src/arrays/empty_array.md @@ -19,4 +19,4 @@ System.out.println(emptyCharArray.length); // Crash System.out.println(emptyCharArray[0]); -``` +``` \ No newline at end of file diff --git a/src/arrays/initialization_with_size.md b/src/arrays/initialization_with_size.md new file mode 100644 index 0000000..e69de29 diff --git a/src/arrays/initialization_without_initializer b/src/arrays/initialization_without_initializer new file mode 100644 index 0000000..90f0f13 --- /dev/null +++ b/src/arrays/initialization_without_initializer @@ -0,0 +1 @@ +# Initializion without Initializer diff --git a/src/arrays/initialization_without_initializer.md b/src/arrays/initialization_without_initializer.md new file mode 100644 index 0000000..e69de29 diff --git a/src/arrays/length.md b/src/arrays/length.md index 34a845c..82c269f 100644 --- a/src/arrays/length.md +++ b/src/arrays/length.md @@ -3,13 +3,15 @@ The number of elements which comprise an array can be accessed by using `.length`.[^unlike_string] ```java +~void main() { String[] veggies = { "brussels", "cabbage", "carrots" }; int numberOfElements = veggies.length; // veggies is 3 elements long System.out.println( - "veggies is " numberOfElements + " characters long" + "veggies is " + numberOfElements + " characters long" ); +~} ``` [^unlike_string]: Unlike with a `String`, you do not write `()` after `.length`. diff --git a/src/arrays/printing_the_contents_of_an_array.md b/src/arrays/printing_the_contents_of_an_array.md index fafbbe2..eed6ad4 100644 --- a/src/arrays/printing_the_contents_of_an_array.md +++ b/src/arrays/printing_the_contents_of_an_array.md @@ -5,14 +5,17 @@ you won't see the contents of the array. Instead you will see something like `[Ljava.lang.String;@1c655221`. ```java +~void main() { String[] shout = { "fus", "ro", "dah" }; // [Ljava.lang.String;@5a07e868 System.out.println(shout); +~} ``` A similar thing will happen with `int[]`, `boolean[]`, and `double[]`.[^gibberish] ```java +~void main() { int[] nums = { 11, 11, 11 }; // [I@5a07e868 System.out.println(nums); @@ -24,15 +27,18 @@ System.out.println(bools); double[] doubles = { 1.1, 1.1, 1.1 }; // [D@5a07e868 System.out.println(bools); +~} ``` The only kind of array which will include its contents when printed is a `char[]`. It will be printed as if it were a `String`. ```java +~void main() { char[] continent = { 'T', 'a', 'm', 'r', 'i', 'e', 'l' }; // Tamriel System.out.println(continent); +~} ``` If you want to actually see the contents of an array, you should @@ -48,8 +54,5 @@ while (index < factions.length) { } ``` -[^gibberish]: What `[I@5a07e868` and co. mean isn't really important. Try not to -get too distracted by it. - -[^future]: Later on, there will be easier ways to do this sort of inspection. This is just the -one I can demonstrate now. +[^gibberish]: What `[I@5a07e868` and co. mean isn't really important. Try not to get too distracted by it. +[^future]: Later on, there will be easier ways to do this sort of inspection. This is just the one I can demonstrate now. diff --git a/src/arrays/reassignment.md b/src/arrays/reassignment.md index e0f0ecb..2b09a02 100644 --- a/src/arrays/reassignment.md +++ b/src/arrays/reassignment.md @@ -3,20 +3,28 @@ The length of an array cannot change, but a variable holding an array can be reassigned to a new array that has a different length. +When reassigning the value of an array variable you need to put `new` followed by a space, the type +of element held by the array, and then `[]` all before the initializer. + +So to reassign an `int[]` you need to write something like `new int[] { 1, 2, 3 }`. + ```java +~void main() { int[] numbers = { 1, 2 }; // 2 System.out.println(numbers.length); -numbers = { numbers[0], numbers[1], 3 }; +numbers = new int[] { numbers[0], numbers[1], 3 }; // 3 System.out.println(numbers.length); +~} ``` This reassignment will not be affect any variables which are aliases for the variable's old value. ```java +~void main() { char[] wordOne = { 'g', 'o' }; char[] wordTwo = wordOne; // go @@ -24,7 +32,7 @@ System.out.println(wordOne); // go System.out.println(wordTwo); -wordOne = { wordOne[0], wordOne[1], 's', 'h' }; +wordOne = new char[] { wordOne[0], wordOne[1], 's', 'h' }; // gosh System.out.println(wordOne); @@ -44,4 +52,5 @@ wordOne[0] = 'p'; System.out.println(wordOne); // no System.out.println(wordTwo); +~} ``` diff --git a/src/arrays/relation_to_final_variables.md b/src/arrays/relation_to_final_variables.md index bb019c4..3472c8b 100644 --- a/src/arrays/relation_to_final_variables.md +++ b/src/arrays/relation_to_final_variables.md @@ -6,6 +6,7 @@ This means that the variable cannot be reassigned, but it does not mean that the array's contents cannot be changed directly or through an alias. ```java +~void main() { final char[] catchphrase = { 'w', 'o', 'a', 'h', '!' }; // woah! System.out.println(catchphrase); @@ -24,4 +25,5 @@ alias[4] = 's'; // egads System.out.println(catchphrase); +~} ``` diff --git a/src/arrays/set_individual_elements.md b/src/arrays/set_individual_elements.md index 6252687..3b5661a 100644 --- a/src/arrays/set_individual_elements.md +++ b/src/arrays/set_individual_elements.md @@ -7,37 +7,44 @@ followed by `[`, an index, and `]`. Then on the right hand side of the equals yo the new value.[^strings] ```java +~void main() { String[] sentence = { "you", "are", "found", "guilty" }; System.out.println(sentence); sentence[1] = "aren't"; System.out.println(sentence); +~} ``` The index of the element to set can also come from a variable. ```java +~void main() { int index = 2; String[] response = { "and", "it", "isn't", "opposite", "day" }; System.out.println(response); response[2] = "is"; System.out.println(response); +~} ``` If you give a number equal to or greater than the length of the array or a number less than zero, you will get an error. ```java +~void main() { String[] response = { "objection" }; // Crash response[1] = "!"; +~} ``` ```java +~void main() { String[] response = { "sustained" }; // Crash response[-1] = "not"; +~} ``` -[^strings]: You cannot change the contents of a `String` like you would an array. This is one of the biggest -differences between a `String` and a `char[]`. +[^strings]: You cannot change the contents of a `String` like you would an array. This is one of the biggest differences between a `String` and a `char[]`. diff --git a/src/arrays_ii.md b/src/arrays_ii.md new file mode 100644 index 0000000..9586633 --- /dev/null +++ b/src/arrays_ii.md @@ -0,0 +1,10 @@ +# Arrays II + +Fairly often you will want to have arrays in your program +which you either do not know the initial values for or which +are too big to physically type out every value in an initializer. + +```java,no_run +String[] everyStudentName = // ??? +char[] everyLetterInEveryAlphabet = // ??? +``` \ No newline at end of file diff --git a/src/arrays_ii/default_values.md b/src/arrays_ii/default_values.md new file mode 100644 index 0000000..7345f27 --- /dev/null +++ b/src/arrays_ii/default_values.md @@ -0,0 +1,45 @@ +# Default Values + +When an array is made by just providing a size, its elements +are initialized to some default value. + +For primitive types like `int` and `double`, each element will be initialized to `0`. + +```java +~void main() { +int[] digits = new int[10]; +// 0 +System.out.println(digits[0]); + +double[] readings = new double[5]; +// 0.0 +System.out.println(readings[0]); +~} +``` + +For `boolean`, each element will be initialized to `false`.[^funfact] + +```java +~void main() { +boolean[] pokedex = new boolean[10]; +// false +System.out.println(pokedex[0]); +~} +``` + +And for every non-primitive type, which is every single type including the boxed primitives, +the default value will be `null`. + +```java +~void main() { +String[] names = new String[10]; +// null +System.out.println(names[0]); + +Integer[] scores = new Integer[26]; +// null +System.out.println(scores[0]); +~} +``` + +[^funfact]: Fun fact. The GameBoy and GameBoy Advance Pokemon games tracked pokedex completion in a big `boolean` array. If you saw a Pokemon it would flip that Pokemon's index in the "seen" array to `true`. If you caught it, it would do the same in a different array. Those games weren't written in Java, but the concept is the same. \ No newline at end of file diff --git a/src/arrays_ii/initialization_with_size.md b/src/arrays_ii/initialization_with_size.md new file mode 100644 index 0000000..463ea05 --- /dev/null +++ b/src/arrays_ii/initialization_with_size.md @@ -0,0 +1,16 @@ +# Initializion with Size + +The Nintendo GameBoy had a screen resolution of 160 x 144. +To store the value of each pixel[^bw] you would need an array 23,040 items +long. + +To support this without you writing the word `false` 23,040 times, +arrays can be made with just by giving a size and skipping the initializer. + +```java,no_run +boolean[] pixels = new boolean[23040]; +``` + +So you have to say `new` followed by the type of element in the array, `[`, the size of the array and `]`. + +[^bw]: The original GameBoy was just black and white, so a `boolean` works just fine to represent a pixel's state. \ No newline at end of file diff --git a/src/arrays_ii/populate_arrays.md b/src/arrays_ii/populate_arrays.md new file mode 100644 index 0000000..c494e07 --- /dev/null +++ b/src/arrays_ii/populate_arrays.md @@ -0,0 +1,33 @@ +# Populate Arrays + +If the default value for an array is not valid for what you are doing, +you will need to populate the array with better initial values. + +For loops are generally good for this purpose. + +```java +~void main() { +char[] letters = new char[26]; +for (int i = 0; i < letters.length; i++) { + letters[i] = (char) ('a' + i); +} +System.out.println(letters); +~} +``` + +But if you are just writing some value to every index +without any other interesting logic, you can use `Arrays.fill`. + +```java +~void main() { +int[] allNines = new char[123]; +Arrays.fill(allNines, 9); + +for (int i = 0; i < allNines.length; i++) { + System.out.println(allNines[i]); +} +~} +``` + +You give that the array and the value to fill it with. In the example above, the array starts +out with everything defaulted to `0` and is then filled with `9`s. diff --git a/src/boolean.md b/src/boolean.md index f957d11..a5ac128 100644 --- a/src/boolean.md +++ b/src/boolean.md @@ -2,7 +2,7 @@ A `boolean` is either `true` or `false`. -```java +```java,no_run boolean onFleek = true; boolean badVibes = false; ``` diff --git a/src/boolean/and.md b/src/boolean/and.md index 99b72ec..0713a8d 100644 --- a/src/boolean/and.md +++ b/src/boolean/and.md @@ -2,7 +2,7 @@ One way multiple booleans can be combined is by using the "and" operator - `&&`. -```java +```java,no_run boolean funToBeAround = true; boolean believesInFundamentalHumanRights = true; boolean willAskOnDate = funToBeAround && believesInFundamentalHumanRights; @@ -12,7 +12,7 @@ So in this case, I will ask someone on a date if they are fun to be around _and_ they wholeheartedly believe in the assertions made in the [Universal Declaration of Human Rights](https://www.un.org/en/about-us/universal-declaration-of-human-rights). | funToBeAround | believesInFundamentalHumanRights | willAskOnDate | -|---------------|----------------------------------|---------------| +| ------------- | -------------------------------- | ------------- | | true | true | true | | true | false | false | | false | true | false | diff --git a/src/boolean/challenges.md b/src/boolean/challenges.md index 322df27..5e204f3 100644 --- a/src/boolean/challenges.md +++ b/src/boolean/challenges.md @@ -2,16 +2,14 @@ Remember the rules for this are -* Try to use only the information given up to this point in this book. -* Try not to give up until you've given it a solid attempt +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt ## Challenge 1 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { boolean a = true; boolean b = false; @@ -24,32 +22,11 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - boolean a = true; - boolean b = false; - boolean c = true; - boolean d = false; - - boolean result = a || b && c || !d; - - System.out.println(result); - } -} -``` - -~ENDIF - ## Challenge 2 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { boolean a = true; boolean b = false; @@ -62,32 +39,11 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - boolean a = true; - boolean b = false; - boolean c = true; - boolean d = false; - - boolean result = !(a || b && c || !d) || (a && b || c); - - System.out.println(result); - } -} -``` - -~ENDIF - ## Challenge 3 Say you have two boolean variables, how could you use the operators we've covered to get the "exclusive or" of the two. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // Change these two variables to test your solution boolean hasIceCream = true; @@ -99,28 +55,10 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Change these two variables to test your solution - boolean hasIceCream = true; - boolean hasCookie = false; - - boolean validChoice = < YOUR CODE HERE >; - - System.out.println(validChoice); - } -} -``` - -~ENDIF - Make sure to test all the possibilities. | hasIceCream | hasCookie | validChoice | -|-------------|-----------|-------------| +| ----------- | --------- | ----------- | | true | true | false | | true | false | true | | false | true | true | diff --git a/src/boolean/not.md b/src/boolean/not.md index c494436..0b20f8c 100644 --- a/src/boolean/not.md +++ b/src/boolean/not.md @@ -2,7 +2,7 @@ Booleans can also be "negated" using the "not" operator - `!`. -```java +```java,no_run boolean haveOreosInHouse = true; boolean stuckToCalorieLimit = !haveOreos; ``` @@ -10,6 +10,6 @@ boolean stuckToCalorieLimit = !haveOreos; So in this case, I have stuck to my calorie limit if there are _not_ Oreos in the house. | haveOreosInHouse | stuckToCalorieLimit | -|------------------|---------------------| +| ---------------- | ------------------- | | false | true | | true | false | diff --git a/src/boolean/operator_precedence.md b/src/boolean/operator_precedence.md index a112b01..dfec44e 100644 --- a/src/boolean/operator_precedence.md +++ b/src/boolean/operator_precedence.md @@ -7,7 +7,7 @@ addition and subtraction. For booleans `!` always happens first. This is followed by `&&` and then by `||`. -```java +```java,no_run boolean a = true; boolean b = false boolean c = false; @@ -21,7 +21,7 @@ boolean result = a && !b || c; Also like mathematics, parentheses can be used to control this order. -```java +```java,no_run // Even though || has a lower precedence than &&, we evaluate // !b || c first because of the parentheses. boolean result = a && (!b || c); diff --git a/src/boolean/or.md b/src/boolean/or.md index aec9949..59984d9 100644 --- a/src/boolean/or.md +++ b/src/boolean/or.md @@ -2,7 +2,7 @@ Another way booleans can be combined is by using the "or" operator - `||`. -```java +```java,no_run boolean dogLooksNice = true; boolean personLooksNice = false; boolean willAskToPetDog = dogLooksNice || personLooksNice; @@ -12,7 +12,7 @@ So in this case, I will ask to pet someone's dog if either the the dog looks nic walking the dog looks nice. | dogLooksNice | personLooksNice | willAskToPetDog | -|--------------|-----------------|-----------------| +| ------------ | --------------- | --------------- | | true | true | true | | true | false | true | | false | true | true | diff --git a/src/boxed_primitives.md b/src/boxed_primitives.md new file mode 100644 index 0000000..d28e978 --- /dev/null +++ b/src/boxed_primitives.md @@ -0,0 +1,33 @@ +# Boxed Primitives + +The fact that `int`, `double`, `char`, and `boolean` cannot have `null` values +can be limiting. + +For this reason there are versions of those primitive[^primitive] types which do not have this restriction. + +```java +void sayAge(Integer age) { + if (age == null) { + System.out.println("Age is not yet known"); + } + else { + System.out.println("Age is " + age); + } +} + +void main() { + Integer age = null; + sayAge(age); + + age = 26; + sayAge(age); +} +``` + +We call these primitives which might be null "Boxed Primitives" because you they are made by taking +the underlying thing and putting it in a "box."[^boxing] + + +[^primitive]: We call them "primitive" types because there isn't a way for you to implement them yourself in Java. They have to be given to you as a fundamental and magic sort of thing. + +[^boxing]: Don't worry too much about the word box in this context. This will make more sense once you learn how to define your own types. I just wanted to at least try to gesture at why it has the silly name that it does. \ No newline at end of file diff --git a/src/boxed_primitives/arrays_of_boxed_primitives.md b/src/boxed_primitives/arrays_of_boxed_primitives.md new file mode 100644 index 0000000..5cece93 --- /dev/null +++ b/src/boxed_primitives/arrays_of_boxed_primitives.md @@ -0,0 +1,17 @@ +# Arrays of Boxed Primitives + +If you have an array of the boxed version of a type, that is not +compatible with an array containing the unboxed version and vice-versa.[^interesting] + +```java,does_not_compile,no_run +int[] numbersOne = { 1, 2, 3 }; +Integer[] numbersTwo = { 4, 5, 6 }; + +// This line won't work +numbersOne = numbersTwo; +// And neither will this one +numbersTwo = numbersOne; +``` + +[^interesting]: The reasons for this are deeply interesting and have to do with the nitty gritty of how +Java is actually implemented. It might also change in the future. \ No newline at end of file diff --git a/src/boxed_primitives/boolean.md b/src/boxed_primitives/boolean.md new file mode 100644 index 0000000..2de4fc6 --- /dev/null +++ b/src/boxed_primitives/boolean.md @@ -0,0 +1,12 @@ +# Boolean + + +The type to use for a `boolean` that might be null is `Boolean`. + +```java +~void main() { +Boolean b = null; +System.out.println(b); +b = true; +System.out.println(true); +~} \ No newline at end of file diff --git a/src/boxed_primitives/boxing_conversion.md b/src/boxed_primitives/boxing_conversion.md new file mode 100644 index 0000000..13e2449 --- /dev/null +++ b/src/boxed_primitives/boxing_conversion.md @@ -0,0 +1,17 @@ +# Boxing Conversion + +If you try to assign to a boxed type like `Integer` from some +code that gives you the unboxed version like `int`, then Java will +automatically do that conversion.[^obvious] + +```java +~void main() { +int x = 5; +Integer y = x; + +System.out.println(x); +System.out.println(y); +~} +``` + +[^obvious]: This might feel obvious, but this is one of the few places in Java where the type of something "magically" changes. `int` and `Integer`, `char` and `Character`, etc. *are* different types. \ No newline at end of file diff --git a/src/arrays/challenges b/src/boxed_primitives/challenges.md similarity index 100% rename from src/arrays/challenges rename to src/boxed_primitives/challenges.md diff --git a/src/boxed_primitives/character.md b/src/boxed_primitives/character.md new file mode 100644 index 0000000..7ec17ce --- /dev/null +++ b/src/boxed_primitives/character.md @@ -0,0 +1,11 @@ +# Character + +The type to use for a `char` that might be null is `Character`. + +```java +~void main() { +Character c = null; +System.out.println(c); +c = '%'; +System.out.println(c); +~} \ No newline at end of file diff --git a/src/boxed_primitives/double.md b/src/boxed_primitives/double.md new file mode 100644 index 0000000..6655c41 --- /dev/null +++ b/src/boxed_primitives/double.md @@ -0,0 +1,11 @@ +# Double + +The type to use for a `double` that might be null is `Double`. + +```java +~void main() { +Double d = null; +System.out.println(d); +d = 3.14; +System.out.println(d); +~} \ No newline at end of file diff --git a/src/boxed_primitives/equality.md b/src/boxed_primitives/equality.md new file mode 100644 index 0000000..2814f34 --- /dev/null +++ b/src/boxed_primitives/equality.md @@ -0,0 +1 @@ +# Equality diff --git a/src/boxed_primitives/integer.md b/src/boxed_primitives/integer.md new file mode 100644 index 0000000..95f8cf0 --- /dev/null +++ b/src/boxed_primitives/integer.md @@ -0,0 +1,12 @@ +# Integer + +The type to use for an `int` that might be null is `Integer`. + +```java +~void main() { +Integer i = null; +System.out.println(i); +i = 5; +System.out.println(i); +~} +``` \ No newline at end of file diff --git a/src/boxed_primitives/primitive_types.md b/src/boxed_primitives/primitive_types.md new file mode 100644 index 0000000..ae84efe --- /dev/null +++ b/src/boxed_primitives/primitive_types.md @@ -0,0 +1 @@ +# Primitive Types diff --git a/src/boxed_primitives/unboxing_conversion.md b/src/boxed_primitives/unboxing_conversion.md new file mode 100644 index 0000000..c0005f9 --- /dev/null +++ b/src/boxed_primitives/unboxing_conversion.md @@ -0,0 +1,40 @@ +# Unboxing Conversion + +If you try to use a boxed primitive in a context where +the normal type is expected, it will be implicitly "unboxed." + +This means you can use `Integer`s directly in math expressions. + +```java +~void main() { +Integer x = 5; +int y = 3; +int z = x * y; + +System.out.println(z); +~} +``` + +As well as `Boolean`s in logical expressions. + +```java +~void main() { +Boolean hasHat = true; +if (hasHat) { + System.out.println("You have a hat!"); +} +~} +``` + +And so on for `Double`, `Character`, etc. + +But if you use one of these types like this and they happen to be `null` you will +get a `NullPointerException`. + +```java,panics +~void main() { +Integer x = null; +// Bool +int y = x; +~} +``` \ No newline at end of file diff --git a/src/branching_logic/boolean_expressions.md b/src/branching_logic/boolean_expressions.md index e3c7f17..be6542f 100644 --- a/src/branching_logic/boolean_expressions.md +++ b/src/branching_logic/boolean_expressions.md @@ -4,6 +4,7 @@ A common thing I've seen students do is set the initial value of some `boolean` variable based on some condition. ```java +~void main() { int age = 22; boolean canRent; @@ -18,14 +19,17 @@ else { // boolean canRent = age > 25 ? true : false; System.out.println(canRent); +~} ``` This is valid code, but very often can be made simpler if you remember that the condition itself already evaluates to a `boolean`. You can directly assign the variable to that value. ```java +~void main() { int age = 22; boolean canRent = age > 25; System.out.println(canRent); +~} ``` diff --git a/src/branching_logic/challenges.md b/src/branching_logic/challenges.md index 1e28a4a..aa102ec 100644 --- a/src/branching_logic/challenges.md +++ b/src/branching_logic/challenges.md @@ -2,16 +2,14 @@ Remember the rules for this are -* Try to use only the information given up to this point in this book. -* Try not to give up until you've given it a solid attempt +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt ## Challenge 1 Write code that will outputs `The number is even` if `x` is an even number. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // Change this variable to different numbers // to test your code @@ -21,22 +19,6 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Change this variable to different numbers - // to test your code - int x = 5; - - // < YOUR CODE HERE > - } -} -``` - -~ENDIF - ## Challenge 2 Make it so that your code from the previous problem will also output `The number is odd` @@ -47,9 +29,7 @@ if the number is odd. Write code that will output `allowed` if the the `password` variable is equal to `"abc123"` and `not allowed` if it isn't. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // Change this variable to different strings // to test your code @@ -59,22 +39,6 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Change this variable to different strings - // to test your code - String password = "apple"; - - // < YOUR CODE HERE > - } -} -``` - -~ENDIF - ## Challenge 4 Write code that will assign the string `The number is {x} even` to `message` if `x` is an even number @@ -82,9 +46,8 @@ and `The number is {x} odd` if `x` is an even number. So if `x` is 12 the string you should assign `The number 12 is even` to `message`. -~IF toplevel_anonymous_class -```java +```java,editable void main() { String message; @@ -97,23 +60,3 @@ void main() { System.out.println(message); } ``` - -~ELSE - -```java -public class Main { - public static void main(String[] args) { - String message; - - // Change this variable to different numbers - // to test your code - int x = 5; - - // < YOUR CODE HERE > - - System.out.println(message); - } -} -``` - -~ENDIF diff --git a/src/branching_logic/conditional_operator.md b/src/branching_logic/conditional_operator.md index 7b0d66b..de895a0 100644 --- a/src/branching_logic/conditional_operator.md +++ b/src/branching_logic/conditional_operator.md @@ -5,19 +5,22 @@ is setting the initial value of a variable, you can use the "conditional operato to perform that assignment instead. ```java +~void main() { int age = 22; -String message = age < 25 +String message = age < 25 ? "You cannot rent a car!" : "You might be able to rent a car"; + +System.out.println(message); +~} ``` You write a condition followed by a `?`, a value to use when that condition evaluates to `true`, a `:`, and then a value to use when that condition evaluates to `false`. -```java +```java,no_run CONDITION ? WHEN_TRUE : WHEN_FALSE ``` -[^ternary]: Some people will call this a ternary expression. Ternary meaning "three things." -Same idea as tres leches. +[^ternary]: Some people will call this a ternary expression. Ternary meaning "three things." Same idea as tres leches. diff --git a/src/branching_logic/else.md b/src/branching_logic/else.md index f07eb9a..940fa27 100644 --- a/src/branching_logic/else.md +++ b/src/branching_logic/else.md @@ -4,6 +4,7 @@ When you want to do one thing when a condition evaluates to `true` and another when that same condition evaluates to `false` you can use `else`. ```java +~void main() { int age = 30; // 🙎‍♀️ if (age < 25) { System.out.println("You cannot rent a car!"); @@ -11,12 +12,13 @@ if (age < 25) { else { System.out.println("You might be able to rent a car."); } +~} ``` You write the word `else` immediately after the `}` at the end of an `if` statement, then some code inside of a new `{` and `}`. -```java +```java,no_run if (CONDITION) { } @@ -29,8 +31,10 @@ When the condition evaluates to `false`, the code inside of `else`'s `{` and `}` `else` cannot exist without a matching `if`, so this code does not work. -```java +```java,does_not_compile +~void main() { else { System.out.println("No if."); } +~} ``` diff --git a/src/branching_logic/else_if.md b/src/branching_logic/else_if.md index ab4dfb5..1c0a04d 100644 --- a/src/branching_logic/else_if.md +++ b/src/branching_logic/else_if.md @@ -4,6 +4,7 @@ If you have an `if` nested in an `else` branch, you can simplify that by using `else if`. ```java +~void main() { boolean cool = true; // 🕶️ int age = 30; // 🙎‍♀️ if (age < 25) { @@ -17,11 +18,13 @@ else { System.out.println("You are rad enough to rent a car."); } } +~} ``` So the following will work the same as the code above. ```java +~void main() { boolean cool = true; // 🕶️ int age = 30; // 🙎‍♀️ @@ -34,12 +37,14 @@ else if (!cool) { else { System.out.println("You are rad enough to rent a car."); } +~} ``` You can have as many `else if`s as you need. Each one will only run if all the previous conditions evaluate to `false`. ```java +~void main() { boolean cool = true; // 🕶️ int age = 100; // 👴 @@ -58,4 +63,5 @@ else if (age > 450) { else { System.out.println("You are rad enough to rent a car."); } +~} ``` diff --git a/src/branching_logic/if.md b/src/branching_logic/if.md index cbf3da7..93e1a5d 100644 --- a/src/branching_logic/if.md +++ b/src/branching_logic/if.md @@ -3,17 +3,19 @@ The way to represent a branching path in Java is by using an `if` statement. ```java +~void main() { int age = 5; // 👶 if (age < 25) { System.out.println("You are too young to rent a car!"); } +~} ``` You write the word `if` followed by an expression which evaluates to a `boolean` inside of `(` and `)`. This expression is the "condition". Then you write some code inside of `{` and `}`. -```java +```java,no_run if (CONDITION) { } @@ -26,10 +28,12 @@ In this example the condition is `age < 25`. When `age` is less than 25 it will and you will be told that you cannot rent a car. ```java +~void main() { int age = 80; // 👵 if (age < 25) { System.out.println("You are too young to rent a car!"); } +~} ``` If this condition evaluates to `false`, then the code inside of `{` and `}` diff --git a/src/branching_logic/nested_ifs.md b/src/branching_logic/nested_ifs.md index e838dd7..a4e04d2 100644 --- a/src/branching_logic/nested_ifs.md +++ b/src/branching_logic/nested_ifs.md @@ -3,6 +3,7 @@ The code inside of the `{` and `}` can be anything, including more `if` statments. ```java +~void main() { int age = 5; // 👶 if (age < 25) { System.out.println("You are too young to rent a car!"); @@ -10,6 +11,7 @@ if (age < 25) { System.out.println("(but it was close)"); } } +~} ``` When an `if` is inside another `if` we say that it is "nested". @@ -17,7 +19,7 @@ When an `if` is inside another `if` we say that it is "nested". If you find yourself nesting more than a few `if`s that might be a sign that you should reach out for help. -```java +```java,no_run if (...) { if (...) { if (...) { diff --git a/src/branching_logic/relation_to_delayed_assignment.md b/src/branching_logic/relation_to_delayed_assignment.md index be22c4d..570d54b 100644 --- a/src/branching_logic/relation_to_delayed_assignment.md +++ b/src/branching_logic/relation_to_delayed_assignment.md @@ -6,6 +6,7 @@ So long as Java can figure out that a variable will always be given an initial v inside of an `if` and `else`, you will be allowed to use that variable. ```java +~void main() { int age = 22; String message; @@ -17,12 +18,14 @@ else { } System.out.println(message); +~} ``` If it will not always be given an initial value, then you will not be allowed to use that variable. -```java +```java,does_not_compile +~void main() { int age = 22; String message; @@ -33,4 +36,5 @@ if (age > 25) { // message is not always given an initial value // so you cannot use it. System.out.println(message); +~} ``` diff --git a/src/branching_logic/scoped_variables.md b/src/branching_logic/scoped_variables.md new file mode 100644 index 0000000..a912580 --- /dev/null +++ b/src/branching_logic/scoped_variables.md @@ -0,0 +1,41 @@ +# Scoped Variables + +If you make a variable declaration inside of an `if` or an `else` block, +that declaration will be "scoped" to the block. + +```java +~void main() { +int age = 5; + +if (age == 5) { + int nextAge = age + 1; + System.out.println(nextAge); +} + +// If you uncomment this line, there will be an issue +// `nextAge` is not available to the scope outside of the `if` +// System.out.println(nextAge); +~} +``` + +This scoping applies even if all branches declare the same variable +within their logic. + +```java +~void main() { +int age = 22; + +if (age > 25) { + String message = "You might be able to rent a car"; +} +else { + String message = "You cannot rent a car!"; +} + +// This will not work, because although `message` is declared +// in all branches, it is not declared in the "outer scope" +System.out.println(message); +~} +``` + +This is why you will sometimes need to use delayed assignment. \ No newline at end of file diff --git a/src/branching_paths_ii.md b/src/branching_paths_ii.md new file mode 100644 index 0000000..2f0a69a --- /dev/null +++ b/src/branching_paths_ii.md @@ -0,0 +1,2 @@ +# Branching Paths II + diff --git a/src/characters.md b/src/characters.md index c94dc1b..398e3d8 100644 --- a/src/characters.md +++ b/src/characters.md @@ -3,7 +3,7 @@ A character, represented by the data type `char`, is a single letter or symbol. -```java +```java,no_run char letter = 'a'; ``` diff --git a/src/characters/challenges.md b/src/characters/challenges.md index a49eb73..3f20799 100644 --- a/src/characters/challenges.md +++ b/src/characters/challenges.md @@ -2,8 +2,8 @@ Remember the rules for this are -* Try to use only the information given up to this point in this book. -* Try not to give up until you've given it a solid attempt +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt ## Challenge 1 @@ -11,9 +11,7 @@ A lot of math problems ask you to find \\( x^2 \\). What is the value of the cha Try to work it out on paper before running the program below. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { char x = 'x'; @@ -21,29 +19,13 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - char x = 'x'; - - System.out.println(x * x); - } -} -``` - -~ENDIF - ## Challenge 2 Alter the program below so that it will output `true` if the character declared at the top is a letter. Make use of the fact that the numeric values for `a` - `z` and `A` - `Z` are contiguous. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { char c = 'a'; @@ -53,22 +35,6 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - char c = 'a'; - - boolean isLetter = ???; - - System.out.println(isLetter); - } -} -``` - -~ENDIF - ## Challenge 3 How many UTF-16 code units does it take to represent this emoji? `👨‍🍳`. diff --git a/src/characters/character_literals.md b/src/characters/character_literals.md index bfcfecf..abc723d 100644 --- a/src/characters/character_literals.md +++ b/src/characters/character_literals.md @@ -3,13 +3,13 @@ In order to write a character in a program, you write that one character surrounded by single quotes. -```java +```java,no_run 'a' ``` This is called a "character literal." It has the same relationship to `char` that an integer literal like 123 has to `int`. -```java +```java,no_run // Same as this "integer literal" is used to write a number int sesameStreet = 123; // A "character literal" is used to write text diff --git a/src/characters/common_escape_sequences.md b/src/characters/common_escape_sequences.md index f6938ca..fdb92b1 100644 --- a/src/characters/common_escape_sequences.md +++ b/src/characters/common_escape_sequences.md @@ -8,20 +8,20 @@ For these, you need to use what is called an "escape sequence." The most common escape sequence you will use will be the one for a "new line." Which is a backslash followed by an `n`. -```java +```java,no_run char newline = '\n'; ``` Because a backslash is used for this special syntax, to put a backslash into a character literal you need to escape it with a backslash of its own. -```java +```java,no_run char backslash = '\\'; ``` And because single quotes are used to mark the start and end of a character literal, they need to be escaped as well. -```java +```java,no_run char singleQuote = '\''; ``` diff --git a/src/characters/conversion_from_integers.md b/src/characters/conversion_from_integers.md index c40bbf7..7ae9056 100644 --- a/src/characters/conversion_from_integers.md +++ b/src/characters/conversion_from_integers.md @@ -4,11 +4,13 @@ An `int` can represent more values than a `char`, so conversion from `int` to `char` requires the use of the cast operator `(char)`. ```java +~void main() { int x = 120; char xAsChar = (char) x; System.out.println(xAsChar); +~} ``` This conversion is narrowing, so information might be lost if the `int` value is too big or too small to fit into a `char`. @@ -16,7 +18,9 @@ This conversion is narrowing, so information might be lost if the `int` value is The initial value of a `char` can also be given by an integer literal if the integer literal represents a small enough letter. ```java +~void main() { char z = 122; System.out.println(z); +~} ``` diff --git a/src/characters/conversion_to_integers.md b/src/characters/conversion_to_integers.md index cc991d7..d3dccb6 100644 --- a/src/characters/conversion_to_integers.md +++ b/src/characters/conversion_to_integers.md @@ -7,20 +7,24 @@ Same as assigning an `int` to a `double`, you can perform a widening conversion by attempting to assign a `char` to an `int`. ```java +~void main() { int valueOfA = 'a'; System.out.println(valueOfA); +~} ``` `char`s will be automatically converted to `int`s when used with mathmatical operators like `+`, `-`, `>`, `<`, etc. ```java +~void main() { char gee = 'g'; // all the letters from a to z have consecutive numeric values. boolean isLetter = gee >= 'a' && gee <= 'z'; System.out.println(isLetter); +~} ``` This can be useful if you are stranded on Mars[^onmars] or diff --git a/src/characters/unicode.md b/src/characters/unicode.md index 98238bf..1d75914 100644 --- a/src/characters/unicode.md +++ b/src/characters/unicode.md @@ -7,7 +7,7 @@ letter or symbol" is generally a good enough mental model. Where this falls apart is with things like emoji (👨‍🍳) which are generally considered to be one symbol, but cannot be represented in a single `char`. -```java +```java,no_run char chef = '👨‍🍳'; ``` diff --git a/src/classes.md b/src/classes.md index 87846ef..94c7d40 100644 --- a/src/classes.md +++ b/src/classes.md @@ -1 +1,12 @@ # Classes + +Up until now all the data types you have used - `int`, `String`, etc. - +came with Java. This works for awhile, but eventually you will need to define your own types. + +The way to do this is with a "class." + +```java +class Person { + +} +``` \ No newline at end of file diff --git a/src/classes/aliasing.md b/src/classes/aliasing.md new file mode 100644 index 0000000..5619569 --- /dev/null +++ b/src/classes/aliasing.md @@ -0,0 +1,26 @@ +# Aliasing + + +When two variables point to the same instance of a class, those variables will be +aliases for the same data. + +This means that, just like arrays, if you change the value of a field on one that change +will be visible on the other. + +```java +class Muppet { + String name; +} + +void main() { + Muppet kermit = new Muppet(); + Muppet darkKermit = kermit; + + kermit.name = "Kermit The Frog"; + + // Kermit The Frog + System.out.println(kermit.name); + // Kermit The Frog + System.out.println(darkKermit.name); +} +``` \ No newline at end of file diff --git a/src/classes/class_declaration.md b/src/classes/class_declaration.md index 3b558c2..c5755bc 100644 --- a/src/classes/class_declaration.md +++ b/src/classes/class_declaration.md @@ -1 +1,9 @@ # Class Declaration + +To declare a class, you say `class` followed by a name for the class and a pair of `{` and `}` + +```java +class Muppet { + +} +``` \ No newline at end of file diff --git a/src/classes/declaration.md b/src/classes/declaration.md new file mode 100644 index 0000000..5364655 --- /dev/null +++ b/src/classes/declaration.md @@ -0,0 +1,5 @@ +# Declaration + +To declare a class, you write the word `class` followed by a name for the class. + +You shoul diff --git a/src/classes/field_access.md b/src/classes/field_access.md new file mode 100644 index 0000000..15706c6 --- /dev/null +++ b/src/classes/field_access.md @@ -0,0 +1,18 @@ +# Field Access + +You can access the value of any field on a class by writing the name of a variable holding an instance +of that class, `.`, then the name of that field. + +```java +class Muppet { + String name; +} + +void main() { + Muppet kermit = new Muppet(); + kermit.name = "Kermit The Frog"; + + // The .name accesses the "name" field + System.out.println(kermit.name); +} +``` diff --git a/src/classes/field_declaration.md b/src/classes/field_declaration.md new file mode 100644 index 0000000..78c2026 --- /dev/null +++ b/src/classes/field_declaration.md @@ -0,0 +1 @@ +# Field Declaration diff --git a/src/classes/field_default_values.md b/src/classes/field_default_values.md new file mode 100644 index 0000000..c80d269 --- /dev/null +++ b/src/classes/field_default_values.md @@ -0,0 +1,28 @@ +# Field Default Values + +Before a field in a class is given a value it will have the same default value as it would +if you made an array of the field's type. + +That is: `0` for `int`, `0.0` for `double`, `false` for `boolean`, and `null` for most all else. + +```java +class Muppet { + int age; + double salary; + boolean talented; + String name; +} + +void main() { + Muppet kermit = new Muppet(); + + // 0 + System.out.println(kermit.age); + // 0.0 + System.out.println(kermit.salary); + // false + System.out.println(kermit.talented); + // null + System.out.println(kermit.name); +} +``` \ No newline at end of file diff --git a/src/classes/field_initialization.md b/src/classes/field_initialization.md new file mode 100644 index 0000000..0a3461f --- /dev/null +++ b/src/classes/field_initialization.md @@ -0,0 +1,30 @@ +# Field Initialization + +You can set an initial value for a field in a few ways. + +One is to access to assign the field directly on the instance created. + +```java +class Muppet { + String name; +} + +void main() { + Muppet kermit = new Muppet(); + kermit.name = "Kermit The Frog"; +} +``` + +Another is to set a default value directly in the field declaration. This makes the most sense +if its a value that most instances will share. + +```java +class Muppet { + // Most are! + boolean talented = true; +} + +void main() { + Muppet kermit = new Muppet(); +} +``` diff --git a/src/classes/fields.md b/src/classes/fields.md new file mode 100644 index 0000000..6d6dd10 --- /dev/null +++ b/src/classes/fields.md @@ -0,0 +1,20 @@ +# Fields + +Classes contain zero or more fields. + +Fields are like variables except they don't live in a method, +they are attached to instances of the class they are a part of. + +To declare a field in a class you say the type of the field, a name for the field, +and then a `;`. + +```java +class Muppet { + String name; +} +``` + +One way to think about it is that when you say `new Muppet()`, Java makes a box big enough to hold +all of the fields that a muppet needs.[^box] + +[^box]: This "box" metaphor is part of where the name "boxed primitives" comes from. diff --git a/src/classes/instances.md b/src/classes/instances.md new file mode 100644 index 0000000..0546560 --- /dev/null +++ b/src/classes/instances.md @@ -0,0 +1,22 @@ +# Instances + +Once you've declared a class, you can make an instance +of that class by saying `new` followed by that class's name +and `()`.[^var] + +```java +class Muppet { + +} + +void main() { + Muppet kermit = new Muppet(); + System.out.println(kermit); +} +``` + +Very similarly to arrays, the output from printing an instance of a class might seem like gibberish (`Main$Muppet@1be6f5c3`). +You will learn how to make it nicer later. + +[^var]: I haven't used it in many code samples thus far, but if you remember `var` this is one of the times +where it can be aethetically convenient. `var kermit = new Muppet();` diff --git a/src/classes/multiple_return_values.md b/src/classes/multiple_return_values.md new file mode 100644 index 0000000..e69de29 diff --git a/src/classes/naming.md b/src/classes/naming.md index e7077a0..987a68e 100644 --- a/src/classes/naming.md +++ b/src/classes/naming.md @@ -1 +1,12 @@ # Naming + +It is social convention to name classes with the first letter of each word capitalized. So if you wanted to +make a class representing an inch worm, you would say the following.[^fuzzy] + +```java +class InchWorm { + +} +``` + +[^fuzzy]: For things that are not English or are acronyms the rules get fuzzy. Use your best judgement. \ No newline at end of file diff --git a/src/classes/naming_fields.md b/src/classes/naming_fields.md new file mode 100644 index 0000000..0e6eced --- /dev/null +++ b/src/classes/naming_fields.md @@ -0,0 +1,14 @@ +# Naming Fields + +Fields are generally named `camelCase`, the same as local variables.[^break] + +```java +class Example { + int x; + String name; + int[] timesOfRacers; + String[] namesOfClowns; +} +``` + +[^break]: If you break a social rule, something Bad happens. diff --git a/src/classes/new.md b/src/classes/new.md new file mode 100644 index 0000000..4f7fd6a --- /dev/null +++ b/src/classes/new.md @@ -0,0 +1 @@ +# new diff --git a/src/classes/return_multiple_values.md b/src/classes/return_multiple_values.md new file mode 100644 index 0000000..a78b9d4 --- /dev/null +++ b/src/classes/return_multiple_values.md @@ -0,0 +1,36 @@ +# Return Multiple Values + +Methods can only ever return one type of thing. This +usually retricts you to only ever returning one `int` or +one `String`. + +But if you make a class that has multiple fields +you can use that to return more than one piece of information.[^manymore] + +```java +class Location { + double latitude; + double longitude; +} + +Location findTreasureIsland() { + Location location = new Location(); + location.latitude = 40.2085; + location.longitude = -3.713; + return location; +} + +void main() { + Location treasureIsland = findTreasureIsland(); + System.out.println( + "Treasure island is located at " + + location.latitude + + " " + + location.longitude + + "." + ); +} +``` + +[^manymore]: There are many more reasons to make your own classes, but this one is +pretty quick to see even at this stage. \ No newline at end of file diff --git a/src/classes/return_values.md b/src/classes/return_values.md new file mode 100644 index 0000000..6b7e4d6 --- /dev/null +++ b/src/classes/return_values.md @@ -0,0 +1 @@ +# Return Multiple Values diff --git a/src/classes/the_meaning_of_the_word_class.md b/src/classes/the_meaning_of_the_word_class.md new file mode 100644 index 0000000..2e42e04 --- /dev/null +++ b/src/classes/the_meaning_of_the_word_class.md @@ -0,0 +1,15 @@ +# The meaning of Class + +Classes are descriptions of a "classification" of +objects in your program. + +The terminology is analagous to biological classification. +Where Plato would classify any "featherless biped" as a human[^idiot], +a `String` is classified by the set of things you can do to it and the data +it stores. The `String` class would specify all of that.[^heady] + + +[^idiot]: What an [idiot](https://www.shardcore.org/spx/2015/05/15/diogenes-and-the-chicken/) + +[^heady]: If thats a bit too heady of an explanation don't fret. You will likely get it intuitively eventually. +There are like 50 different ways to explain it and eventually one will land for you. \ No newline at end of file diff --git a/src/classes/user_defined_types.md b/src/classes/user_defined_types.md new file mode 100644 index 0000000..10d5977 --- /dev/null +++ b/src/classes/user_defined_types.md @@ -0,0 +1,3 @@ +# User Defined Types + +Declaring a class diff --git a/src/classes/zero_values.md b/src/classes/zero_values.md new file mode 100644 index 0000000..fd09e2a --- /dev/null +++ b/src/classes/zero_values.md @@ -0,0 +1 @@ +# Zero Values diff --git a/src/constr b/src/constr new file mode 100644 index 0000000..a902009 --- /dev/null +++ b/src/constr @@ -0,0 +1 @@ +# Declaration diff --git a/src/constructors.md b/src/constructors.md index 177b2c9..c4cbb0a 100644 --- a/src/constructors.md +++ b/src/constructors.md @@ -1 +1,7 @@ # Constructors + +When defining a class, you are allowed to make a special kind of method +called a constructor. + +A constructor runs before any code gets access to an instance of the class. +You use it to set up the "initial state" for an object. \ No newline at end of file diff --git a/src/constructors/arguments.md b/src/constructors/arguments.md new file mode 100644 index 0000000..7a7073a --- /dev/null +++ b/src/constructors/arguments.md @@ -0,0 +1,44 @@ +# Arguments + + +If you declare a constructor which takes arguments, you can use those arguments to give initial values +to fields.[^this] + +You need to pass the arguments in the `()` in the `new` expression, just like any other method invocation. + +```java +class Muppet { + String name; + + Muppet(String name) { + this.name = name; + } +} + +void main() { + Muppet gonzo = new Muppet("Gonzo"); + + // "Gonzo" + System.out.println(gonzo.name); +} +``` + +When you declare a constructor that takes arguments, the default constructor will no longer be available. + +```java,does_not_compile +class Muppet { + String name; + + Muppet(String name) { + this.name = name; + } +} + +void main() { + // Need to provide a name now + Muppet gonzo = new Muppet(); +} +``` + +[^this]: Using `this.` for disambiguation comes in handy here, since often the names of arguments +will be the same as the fields you want to populate with them. \ No newline at end of file diff --git a/src/constructors/declaration.md b/src/constructors/declaration.md new file mode 100644 index 0000000..2ae1b36 --- /dev/null +++ b/src/constructors/declaration.md @@ -0,0 +1,31 @@ +# Declaration + +To declare a constructor you make a method where you don't write any return type +and whose name is the name of the class. + +```java,no_run +class Muppet { + Muppet() { + + } +} +``` + +Inside of the constructor's body, you can set the initial values for any fields +in the class. + +```java +class Muppet { + boolean talented; + + Muppet() { + talented = true; + } +} + +void main() { + Muppet gonzo = new Muppet(); + System.out.println(gonzo.talented); +} +``` + diff --git a/src/constructors/delegation.md b/src/constructors/delegation.md new file mode 100644 index 0000000..b93b1e6 --- /dev/null +++ b/src/constructors/delegation.md @@ -0,0 +1,76 @@ +# Delegation + +It is common for overloaded constructors to be "shortcuts" for eachother. + +That is, if one overload takes two arguments another will take just one argument +and do the same logic as the first but fill in a default value for the un-provided value. + +```java,no_run +class Muppet { + final String name; + final boolean talented; + + Muppet(String name) { + this.name = name; + this.talented = true; + } + + Muppet(String name, boolean talented) { + this.name = name; + this.talented = talented; + } +} +``` + +A downside of this is that any validation logic done in one constructor needs to be copy pasted to +the other. + +```java,no_run +class Muppet { + final String name; + final boolean talented; + + Muppet(String name) { + if (name.length() == 0) { + throw new RuntimeException("Cannot have blank name"); + } + this.name = name; + this.talented = true; + } + + Muppet(String name, boolean talented) { + if (name.length() == 0) { + throw new RuntimeException("Cannot have blank name"); + } + this.name = name; + this.talented = talented; + } +} +``` + +To avoid this situation, you can have one constructor "delegate" to another. + +To do this you write `this` in one constructor and call it as if it were a method. +This will run the logic of the constructor which matches the values passed in. + +```java,no_run +class Muppet { + final String name; + final boolean talented; + + Muppet(String name) { + // Will use the other constructor, but with false filled in + // as a default value + this(name, false); + } + + Muppet(String name, boolean talented) { + // This logic now only needs to live in one place. + if (name.length() == 0) { + throw new RuntimeException("Cannot have blank name"); + } + this.name = name; + this.talented = talented; + } +} +``` \ No newline at end of file diff --git a/src/constructors/final_fields.md b/src/constructors/final_fields.md new file mode 100644 index 0000000..6654227 --- /dev/null +++ b/src/constructors/final_fields.md @@ -0,0 +1,42 @@ +# Final Fields + + +If you declare a field as `final`, its value cannot be changed after an instance of a class is made. + +You are required to explicitly initialize `final` fields in the constructor. + +```java +class Muppet { + final String name; + + Muppet(String name) { + // Without this, it wouldn't work + this.name = name; + } +} + +void main() { + Muppet gonzo = new Muppet("Gonzo"); + System.out.println(gonzo.name); + + // Cannot update the .name field later + // gonzo.name = "Gonzo, the great"; +} +``` + +You can also do this directly when declaring the field.[^constant] + +```java +class Muppet { + // Aren't they all though? + final boolean talented = true; +} + +void main() { + Muppet gonzo = new Muppet(); + System.out.println(gonzo.talented); +} +``` + +[^constant]: This is primarily useful for "constant" values. You will need these, but +having constants attached to instances is a bit unique and won't happen that often. \ No newline at end of file diff --git a/src/constructors/invariants.md b/src/constructors/invariants.md new file mode 100644 index 0000000..c09a7bc --- /dev/null +++ b/src/constructors/invariants.md @@ -0,0 +1,39 @@ +# Invariants + + +Just like any other method, constructors can throw exceptions. + +You can use this fact to establish what we call an "invariant." + +Say we have a `final` age field and that the constructor for a class throws an exception +if a given age is negative. + +```java +class Muppet { + final String name; + final int age; + + Muppet(String name, int age) { + this.name = name; + + if (age < 0) { + throw new RuntimeException("Age cannot be negative"); + } + this.age = age; + } +} + +void main() { + Muppet bigBird = new Muppet("Big Bird", 6); + System.out.println( + bigBird.name + " is " + bigBird.age + " years old." + ); +} +``` + +In every other part of our program now we can rely on age being a non-negative number. +That is a property of instances that will not change.[^naming] + +This is a lot more useful than it seems at first, stay tuned. + +[^naming]: It will not change. It will not vary, it is in-variant. Get it? diff --git a/src/constructors/multiple_constructors.md b/src/constructors/multiple_constructors.md new file mode 100644 index 0000000..efcb197 --- /dev/null +++ b/src/constructors/multiple_constructors.md @@ -0,0 +1 @@ +# Multiple Constructors diff --git a/src/constructors/overloads.md b/src/constructors/overloads.md new file mode 100644 index 0000000..7ef5c4e --- /dev/null +++ b/src/constructors/overloads.md @@ -0,0 +1,61 @@ +# Overloads + + +Just like normal methods, you can have multiple constructors so long as each constructor +takes different types or different numbers of arguments. + +```java,no_run +class Muppet { + String name; + boolean talented; + + Muppet(String name) { + this.name = name; + this.talented = true; + } + + Muppet(String name, boolean talented) { + this.name = name; + this.talented = talented; + } +} +``` + +When you call a constructor, Java will know what code to run because it knows the types of and number of arguments you are passing. + +```java +class Muppet { + String name; + boolean talented; + + Muppet(String name) { + this.name = name; + this.talented = true; + } + + Muppet(String name, boolean talented) { + this.name = name; + this.talented = talented; + } +} + +void announce(Muppet muppet) { + System.out.print(muppet.name); + if (muppet.talented) { + System.out.print(" is "); + } + else { + System.out.print(" is not "); + } + System.out.println("talented."); +} + +void main() { + Muppet fozzie = new Muppet("Fozzie"); + announce(fozzie); + + // Always a critic... + Muppet waldorf = new Muppet("Waldorf", false); + announce(waldorf); +} +``` \ No newline at end of file diff --git a/src/constructors/the_default_constructor.md b/src/constructors/the_default_constructor.md new file mode 100644 index 0000000..cd75169 --- /dev/null +++ b/src/constructors/the_default_constructor.md @@ -0,0 +1,23 @@ +# The Default Constructor + +If you don't declare a constructor, it will be the same as declaring an "empty" +constructor. All fields will be initialized to their default values. + +```java +class Muppet { + String name; + boolean talented; + + Muppet() { + } +} + +void main() { + Muppet gonzo = new Muppet(); + + // null + System.out.println(gonzo.name); + // false + System.out.println(gonzo.talented); +} +``` \ No newline at end of file diff --git a/src/constructors/this.md b/src/constructors/this.md new file mode 100644 index 0000000..d742220 --- /dev/null +++ b/src/constructors/this.md @@ -0,0 +1 @@ +# this diff --git a/src/drawing_shapes/right_triangles.md b/src/drawing_shapes/right_triangles.md new file mode 100644 index 0000000..fa13278 --- /dev/null +++ b/src/drawing_shapes/right_triangles.md @@ -0,0 +1 @@ +# Right Triangles diff --git a/src/enums.md b/src/enums.md new file mode 100644 index 0000000..6d5b3a8 --- /dev/null +++ b/src/enums.md @@ -0,0 +1,20 @@ +# Enums + +While you can use `String`, `int`, `boolean`, and friends +alongside your own custom classes to represent many situations, +that is not always enough. + +Consider a stop light. At any given time it is either red, +yellow, or green. + +The tool we use to model that kind of thing is enums. + +```java,no_run +enum StopLight { + RED, + YELLOW, + GREEN +} +``` + +We call them enums because they enumerate multiple different possibilities. \ No newline at end of file diff --git a/src/enums/comparison_to_boolean.md b/src/enums/comparison_to_boolean.md new file mode 100644 index 0000000..c889bd7 --- /dev/null +++ b/src/enums/comparison_to_boolean.md @@ -0,0 +1,35 @@ +# Comparison to boolean + +Enums are very similar in spirit to `boolean`s. + +A `boolean` has one of two values. `true` or `false`. + +An enum also has one of a fixed set of values. The difference is that +each item in this fixed set can have its own name and that there might be +more than two values. + +Depending on context and personal taste, it might even make sense to use an enum +with two variants as a replacement for a boolean. + +```java +enum Power { + ON, + OFF +} + +void main() { + Power power = Power.ON; + + if (power == Power.ON) { + System.out.println("The power is on"); + } + else { + System.out.println("The power is off"); + } +} +``` + +The benefit here being that the names you give to the enum and to the variants +might be clearer to read in code than `boolean`, `true`, and `false`. + +The downside being that you needed to write more code. \ No newline at end of file diff --git a/src/enums/declaration.md b/src/enums/declaration.md new file mode 100644 index 0000000..a4e93b0 --- /dev/null +++ b/src/enums/declaration.md @@ -0,0 +1,12 @@ +# Declaration + +To declare an `enum`, you write `enum` followed by a name for the enumeration +and the names of the different possibilities separated by commas. + +```java +enum StopLight { + RED, + YELLOW, + GREEN +} +``` \ No newline at end of file diff --git a/src/enums/equality.md b/src/enums/equality.md new file mode 100644 index 0000000..23b4375 --- /dev/null +++ b/src/enums/equality.md @@ -0,0 +1,23 @@ +# Equality + +You can check if two enums contain the same variant +using the `==` operator. + +```java +enum StopLight { + RED, + YELLOW, + GREEN +} + +void main() { + StopLight light = StopLight.RED; + + if (light == StopLight.RED) { + System.out.println("You must stop"); + } + else { + System.out.println("Full speed ahead!"); + } +} +``` \ No newline at end of file diff --git a/src/enums/naming.md b/src/enums/naming.md new file mode 100644 index 0000000..cec37ab --- /dev/null +++ b/src/enums/naming.md @@ -0,0 +1,16 @@ +# Naming + +You are expected to name enums the same as you would regular classes: `WithCapitals`. + +The variants of enums are expected to be named in all capital letters, with underscores[^scream] + +```java +enum CarSeat { + DRIVER, + SHOTGUN, + BACK_LEFT, + BACK_RIGHT +} +``` + +[^scream]: We call this convention "`SCREAMING_SNAKE_CASE`", which is silly. Snakes can't speak, let alone scream. I should know. \ No newline at end of file diff --git a/src/enums/switch.md b/src/enums/switch.md new file mode 100644 index 0000000..5e103c9 --- /dev/null +++ b/src/enums/switch.md @@ -0,0 +1,20 @@ +# Switch + +```java +enum StopLight { + RED, + YELLOW, + GREEN +} + +void main() { + StopLight light = StopLight.RED; + + if (light == StopLight.RED) { + System.out.println("You must stop"); + } + else { + System.out.println("Full speed ahead!"); + } +} +``` \ No newline at end of file diff --git a/src/enums/usage.md b/src/enums/usage.md new file mode 100644 index 0000000..51f91eb --- /dev/null +++ b/src/enums/usage.md @@ -0,0 +1,23 @@ +# Usage + +To use an enum, first make a variable or field whose type is +the name of the enum. Then assign to it one of the variants. + +You can access the variants of an enum by writing the enum's name, +a `.`, then the name of the variant. + +```java +enum StopLight { + RED, + YELLOW, + GREEN +} + +void main() { + StopLight light = StopLight.RED; + + System.out.println( + "The light is " + light + ); +} +``` \ No newline at end of file diff --git a/src/enums/variants.md b/src/enums/variants.md new file mode 100644 index 0000000..39404fa --- /dev/null +++ b/src/enums/variants.md @@ -0,0 +1,14 @@ +# Variants + +We call the different possibilities that an enum represents its "variants." + +So in the following code we would say that the `TirePressure` enum has three variants: `LOW`, `NORMAL`, +and `HIGH`. + +```java,no_run +enum TirePressure { + LOW, + NORMAL, + HIGH +} +``` \ No newline at end of file diff --git a/src/ex b/src/ex new file mode 100644 index 0000000..f0aebb4 --- /dev/null +++ b/src/ex @@ -0,0 +1 @@ +# Exception Messages diff --git a/src/exceptions.md b/src/exceptions.md new file mode 100644 index 0000000..b37b472 --- /dev/null +++ b/src/exceptions.md @@ -0,0 +1,18 @@ +# Exceptions + +When you do something that Java doesn't know how to handle, like +dividing a number by zero, your program will fail. + +The way that this happens is that an "exception" is thrown. + +Say that in "normal conditions" code will proceed top to bottom, line by line. +In "exceptional conditions" code will no longer be able to proceed. + +```java,panics +void main() { + int x = 5 / 0; + System.out.println("Won't get here, an exception will occur"); +} +``` + + diff --git a/src/exceptions/exception_messages b/src/exceptions/exception_messages new file mode 100644 index 0000000..f0aebb4 --- /dev/null +++ b/src/exceptions/exception_messages @@ -0,0 +1 @@ +# Exception Messages diff --git a/src/exceptions/exception_messages.md b/src/exceptions/exception_messages.md new file mode 100644 index 0000000..360f6a9 --- /dev/null +++ b/src/exceptions/exception_messages.md @@ -0,0 +1,2 @@ +# Exception Messages + diff --git a/src/exceptions/messages.md b/src/exceptions/messages.md new file mode 100644 index 0000000..7364aa6 --- /dev/null +++ b/src/exceptions/messages.md @@ -0,0 +1,23 @@ +# Messages + +You can attach a message to an exception to give context to +whoever sees the program crash as to why that happened. + +You do this by putting a `String` in the parentheses when throwing +your exception. + +```java,panics +void crashesOnFive(int x) { + if (x == 5) { + throw new RuntimeException("5 is an evil number"); + } +} + +void main() { + crashesOnFive(1); + System.out.println("Made it to step 1"); + + crashesOnFive(5); + System.out.println("Will not make it to step 2"); +} +``` \ No newline at end of file diff --git a/src/exceptions/stack_traces.md b/src/exceptions/stack_traces.md new file mode 100644 index 0000000..8d4be8f --- /dev/null +++ b/src/exceptions/stack_traces.md @@ -0,0 +1,41 @@ +# Stack Traces + +When you get an exception, it will contain what is known as a "stack trace." + +If a method `a` calls a method `b` which in turn calls a method `c`, that chain of +calls forms a "stack." + +If the method at the bottom, `c`, throws an exception that exception will contain +information about that entire "call stack." + +```java,panics +void c() { + throw new RuntimeException(); +} + +void b() { + c(); +} + +void a() { + b(); +} + +void main() { + a(); +} +``` + +```text,no_run +Exception in thread "main" java.lang.RuntimeException + at Main.c(Main.java:2) + at Main.b(Main.java:6) + at Main.a(Main.java:10) + at Main.main(Main.java:14) +``` + +This makes exceptions somewhat offensive to the eyes, but is extremely useful if something goes +wrong in a real program. You can see exactly what method had an issue and figure out where it was +called from. + +Since figuring out what went wrong is a detective game, every clue helps. \ No newline at end of file diff --git a/src/exceptions/throw.md b/src/exceptions/throw.md new file mode 100644 index 0000000..ba0bf63 --- /dev/null +++ b/src/exceptions/throw.md @@ -0,0 +1,23 @@ +# throw + +In order to throw an exception from your own code, you say `throw` then the name +of the exception and `()`. + +`RuntimeException` is one of many kinds of exceptions, but you can make do with only +that in your own code for a bit. + +```java,panics +void crashesOnFive(int x) { + if (x == 5) { + throw new RuntimeException(); + } +} + +void main() { + crashesOnFive(1); + System.out.println("Made it to step 1"); + + crashesOnFive(5); + System.out.println("Will not make it to step 2"); +} +``` \ No newline at end of file diff --git a/src/exceptions/try_catch.md b/src/exceptions/try_catch.md new file mode 100644 index 0000000..f4f2e13 --- /dev/null +++ b/src/exceptions/try_catch.md @@ -0,0 +1,67 @@ +# try/catch + + +If you know that some code might fail, and you have an idea of what to do if it does, +you can prevent an exception from crashing your program by `catch`-ing it. + +To do this, you write `try` and put the code that might fail inside of `{` and `}`. + +```java,no_run,panics +try { + mightFail(); +} +``` + +Then you write `catch` and in parentheses the kind of exception you want to handle as well as a variable name.[^needvar] + +```java,no_run +try { + mightFail(); +} catch (RuntimeException e) { + +} +``` + +And inside the catch block you can write code to run when such an exception occurs. + +```java,panics +void doThing(int x) { + if (x == 0) { + throw new RuntimeException("Cannot do something zero times"); + } +} + +void main() { + int x = 0; + try { + doThing(x); + } catch (RuntimeException e) { + System.out.println("Something went wrong doing a thing."); + } +} +``` + +Just as you cannot have an `else` without an `if`, you cannot have a `catch` without a `try`. + +```java,does_not_compile +void main() { + catch (RuntimeException e) { + System.out.println("Hello"); + } +} +``` + +Nor can you have a `try` without a `catch`.[^trywithresources] + +```java,does_not_compile +void main() { + try { + System.out.println("Hello"); + } +} +``` + +[^needvar]: Generally you will just use `e` for this. Even if you don't call any instance methods on the exception, you still need to give a name for it. + +[^trywithresources]: Technically you can have a `try` without a `catch`, but only when using another feature of +Java you haven't been shown yet. It will make sense when the time comes. diff --git a/src/first_steps.md b/src/first_steps.md index 43dc6a0..d8bbf5b 100644 --- a/src/first_steps.md +++ b/src/first_steps.md @@ -2,68 +2,32 @@ If you made it through the [Getting Started section](./getting_started/hello_world.md) you've successfully run this program. -~IF toplevel_anonymous_class - ```java void main() { System.out.println("Hello, World!"); } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - System.out.println("Hello, World!"); - } -} -``` - -~ENDIF - This "prints" - not in the sense of a physical printer, but like "displays on the screen" - the text `"Hello, World!"`. Its a tradition for this to be your first program in any language. -~IF toplevel_anonymous_class We aren't quite at the point where I can explain what `void main()` means, but all you need to know for now is that it is what Java looks for to know where to start the program. -```java +```java,no_run void main() { < WRITE YOUR CODE HERE > } ``` -~ELSE - -Unfortunately, for reasons that are impossible to explain with the context you have at this point, -half of this probably reads as cryptic nonsense. - -```java -public class Main { - public static void main(String[] args) { -``` - -I don't _want_ it to stay cryptic nonsense, but until we get there all you truly need to know -is that Java uses all of that to know where to start the program. - -```java -public class Main { - public static void main(String[] args) { - < WRITE YOUR CODE HERE > - } -} -``` - -~ENDIF - So for all intents and purposes, this is the whole program. ```java +~void main() { System.out.println("Hello, World!"); +~} ``` This bit of magic here - `System.out.println` - is a "statement" that "prints" the text inside the `(` and `)` as well as a "new line" to the screen. @@ -73,13 +37,13 @@ This bit of magic here - `System.out.println` - is a "statement" that "prints" t If you were to replace it with `System.out.print`, then the output would lack that new line. This makes the following program be functionally identical to the first. ```java +~void main() { System.out.print("Hello, "); System.out.print("World"); System.out.println("!"); +~} ``` -~IF toplevel_anonymous_class - Which, when we add back `void main()`, looks like this. ```java @@ -90,23 +54,8 @@ void main() { } ``` -~ELSE - -Which, when we add back the part you are squinting past, looks like this. - -```java -public class Main { - public static void main(String[] args) { - System.out.print("Hello, "); - System.out.print("World"); - System.out.println("!"); - } -} -``` - -~ENDIF - You should get in the habit of, whenever you see some bit of code, trying to physically type it out, run it, tweak it, and play with it. -So try playing around with this program. If you are not actively engaging then the whole thing is a bit of a wash. +So try playing around with this program. If you actively engage then you will retain information better. +So try playing around with this program. If you actively engage then you will retain information better. diff --git a/src/first_steps/challenges.md b/src/first_steps/challenges.md index 74d2bdc..0584a1b 100644 --- a/src/first_steps/challenges.md +++ b/src/first_steps/challenges.md @@ -5,14 +5,14 @@ to make sure you get what was just gone over. The rules for this are -* Try to use only the information given up to this point in this book. -* Try not to give up until you've given it a solid attempt +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt ## Challenge 1 Write a program that prints your name twice. So if your name is "Jasmine", the output of the program should be this. -```text +```text,no_run Jasmine Jasmine ``` @@ -21,8 +21,6 @@ Jasmine What will this program output when run? Write down your guess and then try actually running it. -~IF toplevel_anonymous_class - ```text void main() { System.out.println("A"); @@ -36,34 +34,13 @@ void main() { } ``` -~ELSE - -```text -public class Main { - public static void main(String[] args) { - System.out.println("A"); - //System.out.println("B"); - System.out.println("C");// - System.out.println("D"); - /* - System.out.println("E"); - System.out.println("F");*/ - System.out.println("G"); - } -} -``` - -~ENDIF - ## Challenge 3 There are four semicolons in this perfectly functional program. Delete one of them at random and see what the errors you get look like. How could you use that error to figure out where you might have forgotten to put a semicolon? -~IF toplevel_anonymous_class - -```java +```java,editable void main() { System.out.println("Apple"); System.out.println("Banana"); @@ -71,18 +48,3 @@ void main() { System.out.println("Durian"); } ``` - -~ELSE - -```java -public class Main { - public static void main(String[] args) { - System.out.println("Apple"); - System.out.println("Banana"); - System.out.println("Clementine"); - System.out.println("Durian"); - } -} -``` - -~ENDIF diff --git a/src/first_steps/comments.md b/src/first_steps/comments.md index c5b0731..46b12a5 100644 --- a/src/first_steps/comments.md +++ b/src/first_steps/comments.md @@ -4,7 +4,7 @@ At various points, I am going to leave "comments" in the code. Comments are part are solely there for a human to be able to read as an explanation and can be written in regular words. -~IF toplevel_anonymous_class +## Single-line Comments ```java void main() { @@ -13,26 +13,11 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // This prints hello world! - System.out.println("Hello, World!"); - } -} -``` - -~ENDIF - The rules for this are that if you see a `//`, everything after that in the same line is ignored. If you put `//` in front of something that is "code" and not an English explanation we colloquially call that "commenting out" the line. -~IF toplevel_anonymous_class - ```java void main() { System.out.println("Hello, World!"); @@ -41,28 +26,14 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - System.out.println("Hello, World!"); - // The line that prints out goodbye is "commented out" - // System.out.println("Goodbye!"); - } -} -``` - -~ENDIF - You might want to do that at various points where you want to see what happens if you "turn off" parts of the code. +## Multi-line comments + If you put `/*` in the code then everything up until the next `*/` will be treated as a comment. The distinction here is that this style of comment can span multiple lines. -~IF toplevel_anonymous_class - ```java void main() { /* @@ -83,30 +54,4 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - /* - I have eaten - the plums - that were in - the icebox - and which - you were probably - saving - for breakfast - Forgive me - they were delicious - so sweet - and so cold - */ - System.out.println("Hello, World!"); - } -} -``` - -~ENDIF - So that's a mechanism you will see me use and you can use yourself however you see fit. diff --git a/src/first_steps/formatting.md b/src/first_steps/formatting.md index 2390117..1bbbaf1 100644 --- a/src/first_steps/formatting.md +++ b/src/first_steps/formatting.md @@ -2,34 +2,12 @@ You may have noticed that after each `{` all the code that comes after it is "indented" in one "level." -~IF toplevel_anonymous_class - ```java void main() { System.out.println("Hello, World!"); } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - System.out.println("Hello, World!"); - } -} -``` - -~ENDIF - -~IF toplevel_anonymous_class - -~ELSE - -Then, when there is a `}` everything is "de-dented" one level. - -~ENDIF - I will kindly ask that you try to stick to this rule when writing your own code as well. If you try to find help online and you haven't, it will be hard for people to read your code. @@ -37,7 +15,6 @@ to read your code. This is easier to show than to explain in detail. Just try to make your code look like this. ✅ -~IF toplevel_anonymous_class ```java void main() { @@ -45,42 +22,14 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - System.out.println("Hello, World!"); - } -} -``` - -~ENDIF - And not like this. ❌ -~IF toplevel_anonymous_class - ```java -void main() +void main() { System.out.println("Hello, World!");} ``` -~ELSE - -```java -public class Main - { - public static void main(String[] args) - { - System.out.println("Hello, World!"); - } - } -``` - -~ENDIF - -And keep in mind that this rule of thumb applies to every language constrict that requires a `{` and `}` many of which I will introduce later. +And keep in mind that this rule of thumb applies to every language construct that requires a `{` and `}` many of which I will introduce later. diff --git a/src/first_steps/semicolon.md b/src/first_steps/semicolon.md index d6dba04..676991b 100644 --- a/src/first_steps/semicolon.md +++ b/src/first_steps/semicolon.md @@ -3,40 +3,42 @@ The `;` at the end of each of those lines is a "semicolon". ```java -~IF simple_io -print("Hello, "); // <-- this thing - // ^ -~ELSE +~void main(){ System.out.print("Hello, "); // <-- this thing // ^ -~ENDIF -``` +~} +``` It indicates that the statement has finished. A "statement" is a line of code that "does something." The reason we call it a statement and not just a "line of code" is that it can technically span multiple lines and be more complicated than these examples. ```java +~void main(){ System.out.print( "Hello, " ); +~} ``` The `;` at the end is needed so that Java knows that the statement is over. - You need to put a `;` +You need to put a `;` at the end of every statement. If you do not, Java will get confused and your code will not work. If you happen to have an extra semi-colon or two that is technically okay. It just reads it as an "empty statement." It's pointless, but it is allowed. ```java +~void main() { System.out.print( "Hello, " );; +~} ``` Or even ```java +~void main() { System.out.print( "Hello, " ); @@ -52,4 +54,5 @@ System.out.print( ; ; ; ; ; ; ; ; ;;; ;;; +~} ``` diff --git a/src/floating_point_numbers.md b/src/floating_point_numbers.md index 6218b17..39d365f 100644 --- a/src/floating_point_numbers.md +++ b/src/floating_point_numbers.md @@ -3,7 +3,7 @@ Floating point numbers are used to represent numbers which cannot be stored as Integers like `2.5` or `3.14`. -```java +```java,no_run double x = 1.5; double y = 8.0; double z = -3.14; diff --git a/src/floating_point_numbers/accuracy.md b/src/floating_point_numbers/accuracy.md index a80e5d2..044c0b7 100644 --- a/src/floating_point_numbers/accuracy.md +++ b/src/floating_point_numbers/accuracy.md @@ -5,7 +5,7 @@ Floating Point numbers are not an exact representation of numbers. The reasons for this are twofold. 1. It is much more efficient for a computer to work with data that is a "fixed size". You can't cram all the infinite possible -numbers into 32, 64, or any fixed number of bits. + numbers into 32, 64, or any fixed number of bits. 2. For most systems, the inaccuracy is okay. When it is not, there are ways to do "real math" that we will cover much later. diff --git a/src/floating_point_numbers/addition.md b/src/floating_point_numbers/addition.md index b645ee6..d0e4e5a 100644 --- a/src/floating_point_numbers/addition.md +++ b/src/floating_point_numbers/addition.md @@ -3,21 +3,33 @@ You can add any two `double`s using the `+` operator. ```java +~void main() { double x = 5.1; // y will be 14.2 double y = x + 9.1; + +System.out.println(y); +~} ``` Because of the previously mentioned inaccuracy, the results of additions might not always be what you expect. ```java +~void main() { +~double x = 5.1; +~// y will be 14.2 +~double y = x + 9.1; // z will be 19.299999999999997 double z = x + y; + +System.out.println(z); +~} ``` You can add any `int` to a `double` and the result of any such addition will also be a `double`. ```java +~void main() { int x = 5; double y = 4.4; // z will be 9.4 @@ -26,11 +38,13 @@ double z = x + y; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` Even if the result of such an expression will not have any fractional parts, you cannot directly assign it to an int. -```java +```java,does_not_compile +~void main() { int x = 5; double y = 4; // even though z would be 9, which can be stored in an int @@ -40,4 +54,5 @@ int z = x + y; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` diff --git a/src/floating_point_numbers/challenges.md b/src/floating_point_numbers/challenges.md index f079972..ecf069f 100644 --- a/src/floating_point_numbers/challenges.md +++ b/src/floating_point_numbers/challenges.md @@ -2,16 +2,14 @@ Remember the rules for this are -* Try to use only the information given up to this point in this book. -* Try not to give up until you've given it a solid attempt +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt ## Challenge 1 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { double x = 5.1; double y = 2.4; @@ -19,27 +17,11 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - double x = 5.1; - double y = 2.4; - System.out.println(x + y); - } -} -``` - -~ENDIF - ## Challenge 2 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { double x = 5.1; double y = 2.1; @@ -47,58 +29,31 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - double x = 5.1; - double y = 2.1; - System.out.println(x + y); - } -} -``` - -~ENDIF - ## Challenge 3 What will this program output when run? Write down your guess and then try running it. How can you make it give the "right" answer? -~IF toplevel_anonymous_class - -```java +```java,editable void main() { double x = 5 / 2; System.out.println(x); } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - double x = 5 / 2; - System.out.println(x); - } -} -``` - -~ENDIF - ## Challenge 4 These two expressions give different results. Why is that, and what results do they give? -```java -double resultOne = (int) 5.0 / 2 + 5.0 / 2; -double resultTwo = (int) (5.0 / 2 + 5.0 / 2); +```java,editable +void main() { + double resultOne = (int) 5.0 / 2 + 5.0 / 2; + double resultTwo = (int) (5.0 / 2 + 5.0 / 2); -System.out.println(resultOne); -System.out.println(resultTwo); + System.out.println(resultOne); + System.out.println(resultTwo); +} ``` ## Challenge 5 @@ -118,9 +73,7 @@ Where \\(a\\), \\(b\\), and \\(c\\) are the prefixes of each term in the followi Write some code that finds both solutions to any quadratic equation defined by some variables `a`, `b`, and `c`. If the equation has imaginary solutions, you are allowed to just output `NaN`. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // For this one in particular, you should output // -3.5811388300842 and -0.41886116991581 @@ -138,26 +91,3 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // For this one in particular, you should output - // -3.5811388300842 and -0.41886116991581 - // but your code should work with these three numbers changed to - // represent any given quadratic equation. - double a = 2; - double b = 8; - double c = 3; - - double resultOne = ???; - double resultTwo = ???; - - System.out.println(resultOne); - System.out.println(resultTwo); - } -} -``` - -~ENDIF diff --git a/src/floating_point_numbers/comparison.md b/src/floating_point_numbers/comparison.md index 1e103e0..076c068 100644 --- a/src/floating_point_numbers/comparison.md +++ b/src/floating_point_numbers/comparison.md @@ -6,6 +6,7 @@ In addition to comparing for equality with `==` and `!=`, `doubles`s can be comp This works the same as it does with `int`s. ```java +~void main() { double x = 1.5; double y = 0.2; @@ -13,4 +14,5 @@ double y = 0.2; System.out.println(x > y); // false System.out.println(x < y); +~} ``` diff --git a/src/floating_point_numbers/conversion_from_integers.md b/src/floating_point_numbers/conversion_from_integers.md index 9b99c81..54e3930 100644 --- a/src/floating_point_numbers/conversion_from_integers.md +++ b/src/floating_point_numbers/conversion_from_integers.md @@ -5,29 +5,34 @@ representable as `double`s so it is a "widening conversion" and will be handled by Java when performing an assignment. ```java +~void main() { int x = 5; double y = x; System.out.println(x); System.out.println(y); +~} ``` This is not true in an expression. Even if the result of a computation between `int`s is being assigned to a `double`, the computation will still be performed using the same rules `int`s usually follow. ```java +~void main() { int x = 7; int y = 2; // integer division of 7 and 2 gives 3. double z = x / y; System.out.println(z); +~} ``` To perform math on an `int` and have that `int` behave as if it were a `double`, you need to convert said `int` into a `double` using a cast expression and the `(double)` cast operator. ```java +~void main() { int x = 7; int y = 2; // This converts x into a double before performing the division @@ -35,4 +40,5 @@ int y = 2; double z = (double) x / y; System.out.println(z); +~} ``` diff --git a/src/floating_point_numbers/conversion_to_integers.md b/src/floating_point_numbers/conversion_to_integers.md index 3a11cb7..57f9f3f 100644 --- a/src/floating_point_numbers/conversion_to_integers.md +++ b/src/floating_point_numbers/conversion_to_integers.md @@ -2,10 +2,12 @@ Normally, a `double` value cannot be assigned to an `int`. -```java +```java,does_not_compile +~void main() { double x = 5.0; // will not work int y = x; +~} ``` The reason for this is that there are numbers like `2.5`, the infinities, and `NaN` which do not have an @@ -22,17 +24,20 @@ To perform such a narrowing conversion, you need to put `(int)` before a literal evaluates to a `double`. ```java +~void main() { double x = 5.0; // will be 5 int y = (int) x; System.out.println(y); +~} ``` Any decimal part of the number will be dropped. So numbers like `2.1`, `2.5`, and `2.9` will all be converted into simply `2`. ```java +~void main() { int x = (int) 2.1; int y = (int) 2.5; int z = (int) 2.9; @@ -40,35 +45,42 @@ int z = (int) 2.9; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` Any number that is too big to store in an `int` will be converted to the biggest possible `int`, 231 - 1. ```java +~void main() { // 2147483647 System.out.println((int) 4207483647.0); double positiveInfinity = 5.0 / 0.0; // 2147483647 System.out.println((int) positiveInfinity); +~} ``` Any number that is too small to store in an `int` will be converted to the smallest possible `int`, -231. ```java +~void main() { // -2147483648 System.out.println((int) -9999999999.0); double negativeInfinity = -5.0 / 0.0; // -2147483648 System.out.println((int) negativeInfinity); +~} ``` And `NaN` will be converted to zero. ```java +~void main() { double nan = 0.0 / 0.0; System.out.println((int) nan); +~} ``` When you use `(int)` to convert, we call that a "cast[^cast] expression". The `(int)` is a "cast operator." It even has diff --git a/src/floating_point_numbers/division.md b/src/floating_point_numbers/division.md index 0435b7d..7563a95 100644 --- a/src/floating_point_numbers/division.md +++ b/src/floating_point_numbers/division.md @@ -3,6 +3,7 @@ You can divide any two `double`s using the `/` operator. ```java +~void main() { double x = 8; // y will be 4.0 double y = x / 2; @@ -12,6 +13,7 @@ double z = y / 3; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` Unlike with integer division, floating point division will include the remainder in the result.[^caveat] diff --git a/src/floating_point_numbers/equality.md b/src/floating_point_numbers/equality.md index 6778ac4..fa72695 100644 --- a/src/floating_point_numbers/equality.md +++ b/src/floating_point_numbers/equality.md @@ -3,15 +3,20 @@ Just like `int`s, `double`s can be inspected to see if they are equal to one another using `==`. ```java +~void main() { double numberOfToes = 10.0; double numberOfFingers = 10.0; boolean humanGenerated = numberOfToes == numberOfFingers; + +System.out.println(humanGenerated); +~} ``` Because of floating point inaccuracy, this might not always give you the result you expect though. ```java +~void main() { double x = 0.1; double y = 0.2; // z will be 0.30000000000000004 @@ -19,14 +24,21 @@ double z = x + y; // this will be false. boolean doesWhatYouExpect = z == 0.3; + +System.out.println(doesWhatYouExpect); +~} ``` A `double` can also be compared to an `int` and, if they represent the same value, they will be reported as equal. ```java +~void main() { int x = 5; double y = 5.0; // will be true boolean fiveIsFive = x == y; + +System.out.println(fiveIsFive); +~} ``` diff --git a/src/floating_point_numbers/floating_point_literals.md b/src/floating_point_numbers/floating_point_literals.md index 7bd65dd..4cb1d9c 100644 --- a/src/floating_point_numbers/floating_point_literals.md +++ b/src/floating_point_numbers/floating_point_literals.md @@ -2,26 +2,26 @@ In order to write a floating point number in a program, you use a "floating-point literal." -```java +```java,no_run 1.5 ``` Any number written with a decimal point is a floating point literal. -```java +```java,no_run double pi = 3.14; ``` This includes numbers where a decimal point is written, but there is no fractional part to the number. -```java +```java,no_run 5.0 ``` You cannot directly give a value to an integer variable using a floating point literal, even if there is no fractional part to the number. -```java +```java,no_run // this will not work int x = 5.0; ``` @@ -29,6 +29,6 @@ int x = 5.0; The reverse is possible though. You can give a value to a variable that stores a floating point number using an integer literal. -```java +```java,no_run double x = 5; ``` diff --git a/src/floating_point_numbers/multiplication.md b/src/floating_point_numbers/multiplication.md index 5471d9d..24c126e 100644 --- a/src/floating_point_numbers/multiplication.md +++ b/src/floating_point_numbers/multiplication.md @@ -3,6 +3,7 @@ You can multiply any two `double`s using the `*` operator. ```java +~void main() { double x = 3; // y will be 27 double y = x * 9; @@ -12,12 +13,16 @@ double z = y * 0.5; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` Just like with addition and subtraction, it is fine to use both integers and integer literals when doing multiplication on doubles. So long as any number being used is a `double` the overall result will be a double. ```java -// a will be 3 +~void main() { +// a will be 3.0 double a = 1.5 * 2; +System.out.println(a); +~} ``` diff --git a/src/floating_point_numbers/nan.md b/src/floating_point_numbers/nan.md index 0020221..cf22e18 100644 --- a/src/floating_point_numbers/nan.md +++ b/src/floating_point_numbers/nan.md @@ -4,44 +4,56 @@ There is a special floating point number called `NaN`, which stands for "Not a N You generally only encounter `NaN` as the result of doing something silly like dividing zero by zero. -```java +```java,no_run double nan = 0.0 / 0.0; ``` `NaN` is not equal to itself. ```java +~void main() { +~double nan = 0.0 / 0.0; // will be false boolean equalToItself = nan == nan; System.out.println(equalToItself); +~} ``` `NaN` is not greater than itself. ```java +~void main() { +~double nan = 0.0 / 0.0; // will be false boolean greaterThanItself = nan > nan; System.out.println(greaterThanItself); +~} ``` `NaN` is not less than itself. ```java +~void main() { +~double nan = 0.0 / 0.0; // will be false boolean lessThanItself = nan < nan; System.out.println(lessThanItself); +~} ``` `NaN` is not greater than, less than, or equal to any number. ```java +~void main() { +~double nan = 0.0 / 0.0; // will all be false System.out.println(nan < 5); System.out.println(nan > 5); System.out.println(nan == 5); +~} ``` None of this is usually useful, but it is fun to know about. diff --git a/src/floating_point_numbers/positive_and_negative_infinity.md b/src/floating_point_numbers/positive_and_negative_infinity.md index 3dc10d7..d87468e 100644 --- a/src/floating_point_numbers/positive_and_negative_infinity.md +++ b/src/floating_point_numbers/positive_and_negative_infinity.md @@ -5,29 +5,36 @@ and negative infinity. You can get positive infinity by dividing any positive number by zero. -```java +```java,no_run double positiveInfinity = 1.0 / 0.0; ``` You can get negative infinity by dividing any negative number by zero. -```java +```java,no_run double negativeInfinity = -1.0 / 0.0; ``` As you might expect, positive infinity is greater than any number and negative infinity is less than any number. ```java +~void main() { +~double positiveInfinity = 1.0 / 0.0; +~double negativeInfinity = -1.0 / 0.0; // true System.out.println(positiveInfinity > 99999999); // true System.out.println(negativeInfinity < -99999999); +~} ``` Except for `NaN`, of course. ```java +~void main() { +~double positiveInfinity = 1.0 / 0.0; +~double negativeInfinity = -1.0 / 0.0; double nan = 0.0 / 0.0; // false @@ -35,4 +42,5 @@ System.out.println(positiveInfinity > nan); // false System.out.println(negativeInfinity < nan); +~} ``` diff --git a/src/floating_point_numbers/shorthands_for_reassignment.md b/src/floating_point_numbers/shorthands_for_reassignment.md index ec0104d..42ece4c 100644 --- a/src/floating_point_numbers/shorthands_for_reassignment.md +++ b/src/floating_point_numbers/shorthands_for_reassignment.md @@ -3,6 +3,7 @@ All the same shorthands for reassignment work with `double`s the same as they do with `int`s. ```java +~void main() { double x = 0.5; // 0.5 System.out.println(x); @@ -30,4 +31,5 @@ System.out.println(x); x /= 2; // 6.25 System.out.println(x); +~} ``` diff --git a/src/floating_point_numbers/square_root.md b/src/floating_point_numbers/square_root.md index d65d76a..dca6221 100644 --- a/src/floating_point_numbers/square_root.md +++ b/src/floating_point_numbers/square_root.md @@ -6,27 +6,33 @@ is to find their square root. You can do this with `Math.sqrt`. ```java +~void main() { double x = 4; double y = Math.sqrt(x); // This will output 2 System.out.println(y); +~} ``` You need to write `Math.sqrt` and then inside of parentheses the expression whose value you want to take the square root of.. ```java +~void main() { double x = 5; double y = 13; double z = Math.sqrt(9 * x + y); - + // This will output 7.615773105863909 System.out.println(z); +~} ``` If you try to take the square root of a negative number, the result will be `NaN`. ```java +~void main() { // will output NaN System.out.println(Math.sqrt(-5.2)); +~} ``` diff --git a/src/floating_point_numbers/subtraction.md b/src/floating_point_numbers/subtraction.md index 078ce84..cc89f7b 100644 --- a/src/floating_point_numbers/subtraction.md +++ b/src/floating_point_numbers/subtraction.md @@ -3,26 +3,34 @@ You can subtract any two `double`s using the `-` operator. ```java +~void main() { double x = 5.1; // y will be 4.1 double y = x - 9.2; System.out.println(x); System.out.println(y); +~} ``` Because of the previously mentioned inaccuracy, the results of subtractions might not always be what you expect. ```java +~void main() { +~double x = 5.1; +~// y will be 4.1 +~double y = x - 9.2; // z will be -4.199999999999999 double z = y - 0.1; System.out.println(z); +~} ``` You can subtract any `int` to or from a `double` and the result of any such subtraction will also be a `double`. ```java +~void main() { int x = 5; double y = 4.5; // z will be 0.5 @@ -31,14 +39,17 @@ double z = x - y; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` Even if the result of such an expression will not have any fractional parts, you cannot directly assign it to an `int`. -```java +```java,does_not_compile +~void main() { int x = 5; double y = 4; // even though z would be 1, which can be stored in an int // this will not work. The result of the expression is a double. int z = x - y; +~} ``` diff --git a/src/for.md b/src/for.md index ed4b4da..3756722 100644 --- a/src/for.md +++ b/src/for.md @@ -4,3 +4,4 @@ for (int index = 0; index < array.length; index++) { char element = array[index]; } +``` diff --git a/src/for/i.md b/src/for/i.md deleted file mode 100644 index 60e03e5..0000000 --- a/src/for/i.md +++ /dev/null @@ -1,27 +0,0 @@ -# i - -One thing you will very often see if you read other peoples' -code is that the variable being tracked in a for loop is often called -`i`. - -```java -String word = "bird"; -for (int i = 0; i < array.length; i++) { - char letter = word.charAt(i); - System.out.println(letter); -} - -// b -// i -// r -// d -``` - -While usually naming variables with single letters isn't a great idea, -most developers carve out an exception for cases like this. - -If a for loop that starts its variable at `0`, keeps going until while -it is `<` the length of some collection, and goes up by one each iteration -it should be "obvious" what `i` means. - -Just do not start naming all your variables single letters. diff --git a/src/getting_started.md b/src/getting_started.md index c193ec0..4b356a4 100644 --- a/src/getting_started.md +++ b/src/getting_started.md @@ -2,39 +2,34 @@ There are a lot of ways to "get set up" to run Java code. -For the purposes of this book, I am going to reccomend that you -start with [replit.com](https://replit.com). +For at least the first chunk of this, you should be able to get away with using +the editor on [https://run.mccue.dev](https://run.mccue.dev). That might be the easiest. -It requires an internet connection and you will have to make an account, but -of the available options it is the easiest to set up. - -If you are in school and your teacher has helped you get set up in some other -way it is okay to skip this section and just do it the way you were shown. - -All that matters is that in the end you have the ability to run and +I will add tutorials here as they are requested or as I have time, but for the start +all that matters is that you have the ability to run and edit the following code. -~IF toplevel_anonymous_class - ```java void main() { System.out.println("Hello, World"); } ``` -~ELSE +## repl.it -```java -public class Main { - public static void main(String[] args) { - System.out.println("Hello, World"); - } -} -``` +[replit.com](https://replit.com) is a pretty common choice for teachers because +they will be able to give you assignments and have you share back your results. +It is also a decent option if your school only provides you with Chromebooks +or similar. + +It requires an internet connection and you will have to make an account, but +otherwise it is fairly convenient. + +If you are in school and your teacher has helped you get set up in some other +way it is okay to skip this section and just do it the way you were shown. -~ENDIF -## Step 1. Make an account +### Step 1. Make an account Go to [replit.com](https://replit.com) and find the "Sign Up" button. Websites change every now and then so these screenshots might be out of date. @@ -49,7 +44,7 @@ Click it and sign up for an account. alt="Picture of the sign up form on replit's website" width = "200"> -## Step 2. Create a Java REPL +### Step 2. Create a Java REPL Find the "Create REPL" button and click it. @@ -68,27 +63,19 @@ Find the Java template and click "Create". alt="Filled in create from template menu on replit" width = "200"> -## Step 3. Run code +### Step 3. Run code You should land on a screen with a big green run button, an open file called "Main.java", and a blank window labeled "console". Picture of an unran hello world program +src="/getting_started/repl_4_voidmain.png" +alt="Picture of an unran hello world program" +width = "800"> Click it and you should see the text `Hello, world!` appear under the console window. Picture of a hello world program after running +src="/getting_started/repl_5_voidmain.png" +alt="Picture of a hello world program after running" +width = "800"> diff --git a/src/identity_types.md b/src/identity_types.md new file mode 100644 index 0000000..39e2c2a --- /dev/null +++ b/src/identity_types.md @@ -0,0 +1 @@ +# Identity Types diff --git a/src/identity_types/comparison_with_equalsequals.md b/src/identity_types/comparison_with_equalsequals.md new file mode 100644 index 0000000..3ad9d98 --- /dev/null +++ b/src/identity_types/comparison_with_equalsequals.md @@ -0,0 +1 @@ +# Comparison with == diff --git a/src/img/Agent.svg b/src/img/Agent.svg new file mode 100644 index 0000000..1c08b91 --- /dev/null +++ b/src/img/Agent.svg @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/Boxer.svg b/src/img/Boxer.svg new file mode 100644 index 0000000..9e5c00a --- /dev/null +++ b/src/img/Boxer.svg @@ -0,0 +1,1030 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/ChezDuke.svg b/src/img/ChezDuke.svg new file mode 100644 index 0000000..2ecce97 --- /dev/null +++ b/src/img/ChezDuke.svg @@ -0,0 +1,432 @@ + + + + + + + + + + diff --git a/src/img/NyaNya.svg b/src/img/NyaNya.svg new file mode 100644 index 0000000..56bd253 --- /dev/null +++ b/src/img/NyaNya.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/PalmTree.svg b/src/img/PalmTree.svg new file mode 100644 index 0000000..279d939 --- /dev/null +++ b/src/img/PalmTree.svg @@ -0,0 +1,764 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/Paper.svg b/src/img/Paper.svg new file mode 100644 index 0000000..3dcafee --- /dev/null +++ b/src/img/Paper.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/Wave.svg b/src/img/Wave.svg new file mode 100644 index 0000000..4f2fc39 --- /dev/null +++ b/src/img/Wave.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/does_not_compile.svg b/src/img/does_not_compile.svg new file mode 100644 index 0000000..c85fee7 --- /dev/null +++ b/src/img/does_not_compile.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/does_not_compile_ferris.svg b/src/img/does_not_compile_ferris.svg new file mode 100644 index 0000000..48b7b4d --- /dev/null +++ b/src/img/does_not_compile_ferris.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/not_desired_behavior.svg b/src/img/not_desired_behavior.svg new file mode 100644 index 0000000..47f4024 --- /dev/null +++ b/src/img/not_desired_behavior.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/panics.svg b/src/img/panics.svg new file mode 100644 index 0000000..9a0a105 --- /dev/null +++ b/src/img/panics.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/panics_ferris.svg b/src/img/panics_ferris.svg new file mode 100644 index 0000000..be55f5e --- /dev/null +++ b/src/img/panics_ferris.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/instanc b/src/instanc new file mode 100644 index 0000000..7eff5f5 --- /dev/null +++ b/src/instanc @@ -0,0 +1 @@ +# Invoke Other Methods diff --git a/src/instance b/src/instance new file mode 100644 index 0000000..d742220 --- /dev/null +++ b/src/instance @@ -0,0 +1 @@ +# this diff --git a/src/instance_methods.md b/src/instance_methods.md new file mode 100644 index 0000000..e499cb0 --- /dev/null +++ b/src/instance_methods.md @@ -0,0 +1,23 @@ +# Instance Methods + +In addition to having fields, classes can also have their own method +definitions. + +These look the same as the method definitions you've +seen so far, they are just put within a class definition.[^kermitangry] + +```java +class Muppet { + String name; + + void freakOut() { + System.out.println("**ANGRY KERMIT NOISES**") + } +} +``` + +We call these instance methods because you need an instance of the class in order +to call the method. + +[^kermitangry]: If you haven't seen the muppets this might have go over your head, +but Kermit [randomly gets really mad.](https://www.youtube.com/watch?v=SVDgHEg2jnY) \ No newline at end of file diff --git a/src/instance_methods/aliasing.md b/src/instance_methods/aliasing.md new file mode 100644 index 0000000..81497a6 --- /dev/null +++ b/src/instance_methods/aliasing.md @@ -0,0 +1 @@ +# Aliasing diff --git a/src/instance_methods/arguments.md b/src/instance_methods/arguments.md new file mode 100644 index 0000000..b0f6f78 --- /dev/null +++ b/src/instance_methods/arguments.md @@ -0,0 +1,22 @@ +# Arguments + +Instance methods can take arguments the same as the methods you have +seen so far. + +```java +class Muppet { + String name; + + void singLyric(int verse) { + if (verse == 1) { + System.out.println("Why are there so many"); + } + else if (verse == 2) { + System.out.println("Songs about rainbows"); + } + else { + System.out.println("And what's on the other side?"); + } + } +} +``` \ No newline at end of file diff --git a/src/instance_methods/clarity.md b/src/instance_methods/clarity.md new file mode 100644 index 0000000..dd1085e --- /dev/null +++ b/src/instance_methods/clarity.md @@ -0,0 +1,30 @@ +# Clarity + +Another reason you might want to use `this` is for code clarity. + +It is a lot easier to know that a particular line refers to a field +or method on the same class if there is an explicit `this.` before +the reference.[^preference] + +```java +class Elmo { + int age; + + void sayHello() { + System.out.println("Hi, I'm Elmo"); + System.out.print("I am "); + System.out.print(this.age); + System.out.println(" years old."); + } +} + +void main() { + Elmo elmo = new Elmo(); + elmo.age = 3; + + elmo.sayHello(); +} +``` + +[^preference]: This is very much a personal preference thing. I generally choose to write +`this.` whenever I am able to for this reason. \ No newline at end of file diff --git a/src/instance_methods/declaration.md b/src/instance_methods/declaration.md new file mode 100644 index 0000000..a902009 --- /dev/null +++ b/src/instance_methods/declaration.md @@ -0,0 +1 @@ +# Declaration diff --git a/src/instance_methods/derived_values.md b/src/instance_methods/derived_values.md new file mode 100644 index 0000000..8228ee0 --- /dev/null +++ b/src/instance_methods/derived_values.md @@ -0,0 +1,24 @@ +# Derived Values + +A common use for methods is to provide a value that is derived from +the values of other fields. + +```java +class Elmo { + int age; + + int nextAge() { + return age + 1; + } +} + +void main() { + Elmo elmo = new Elmo(); + elmo.age = 3; + + System.out.println("Elmo is " + elmo.age + " right now,"); + System.out.println("but next year Elmo will be " + elmo.nextAge()); +} +``` + +Which is useful for situations like where you store someones first and last name \ No newline at end of file diff --git a/src/instance_methods/disambiguation.md b/src/instance_methods/disambiguation.md new file mode 100644 index 0000000..d768fa5 --- /dev/null +++ b/src/instance_methods/disambiguation.md @@ -0,0 +1,28 @@ +# Disambiguation + +One reason you might need to use `this` is if the name +of an argument to a method is the same as the name of a field. + +```java +class Elmo { + int age; + + boolean isOlderThan(int age) { + return this.age > age; + } +} + +void main() { + Elmo elmo = new Elmo(); + elmo.age = 3; + + // true + System.out.println(elmo.isOlderThan(2)); +} +``` + +If you didn't do this, it would be ambiguous whether you were referring to the field +or the argument. This removes the ambiguity.[^javanotconfused] + +[^javanotconfused]: Really it isn't ambiguous for Java. It will just think you are referring to the argument. +It is ambiguous from the perspective of a human being reading the code though. \ No newline at end of file diff --git a/src/instance_methods/field_access.md b/src/instance_methods/field_access.md new file mode 100644 index 0000000..b062662 --- /dev/null +++ b/src/instance_methods/field_access.md @@ -0,0 +1,26 @@ +# Field Access + +Within an instance method's definition, you can access the values +of any fields declared in the class by just writing their name. + +```java +class Elmo { + int age; + + void sayHello() { + System.out.println("Hi, I'm Elmo"); + System.out.print("I am "); + + // You can use elmo's age by just writing "age" + System.out.print(age); + System.out.println(" years old."); + } +} + +void main() { + Elmo elmo = new Elmo(); + elmo.age = 3; + + elmo.sayHello(); +} +``` \ No newline at end of file diff --git a/src/instance_methods/field_updates.md b/src/instance_methods/field_updates.md new file mode 100644 index 0000000..9f03007 --- /dev/null +++ b/src/instance_methods/field_updates.md @@ -0,0 +1,30 @@ +# Field Updates + +You can also update the value of any field from within an instance +method the same as if it were a local variable. + +```java +class Elmo { + int age; + + void sayHello() { + System.out.println("Hi, I'm Elmo"); + System.out.print("I am "); + System.out.print(age); + System.out.println(" years old."); + } + + void haveBirthday() { + age = age + 1; + } +} + +void main() { + Elmo elmo = new Elmo(); + elmo.age = 3; + + elmo.sayHello(); + elmo.haveBirthday(); + elmo.sayHello(); +} +``` \ No newline at end of file diff --git a/src/instance_methods/invocation.md b/src/instance_methods/invocation.md new file mode 100644 index 0000000..cd86fc3 --- /dev/null +++ b/src/instance_methods/invocation.md @@ -0,0 +1,20 @@ +# Invocation + +To invoke an instance method you first need an instance of the class. + +You then write `.` followed by the name of the instance method and a list of arguments.[^elmo] + +```java +class Elmo { + void talkAboutRocko() { + System.out.println("ROCKO'S NOT ALIVE!!") + } +} + +void main() { + Elmo elmo = new Elmo(); + elmo.talkAboutRocko(); +} +``` + +[^elmo]: Daily reminder that Elmo absolutely [hates Rocko](https://www.youtube.com/watch?v=DFBMcwaSdns) \ No newline at end of file diff --git a/src/instance_methods/invoke_other_methods.md b/src/instance_methods/invoke_other_methods.md new file mode 100644 index 0000000..d15d11c --- /dev/null +++ b/src/instance_methods/invoke_other_methods.md @@ -0,0 +1,29 @@ +# Invoke Other Methods + +Inside of an instance method you can invoke other instance methods +on the same class by writing their name and providing any needed arguments. + +```java +class Elmo { + int age; + + void sayHello() { + System.out.println("Hi, I'm Elmo"); + System.out.print("I am "); + System.out.print(age); + System.out.println(" years old."); + } + + void startTheShow(String showName) { + sayHello(); + System.out.println("Welcome to " + showName); + } +} + +void main() { + Elmo elmo = new Elmo(); + elmo.age = 3; + + elmo.startTheShow("Sesame Street"); +} +``` \ No newline at end of file diff --git a/src/instance_methods/this.md b/src/instance_methods/this.md new file mode 100644 index 0000000..5b56b55 --- /dev/null +++ b/src/instance_methods/this.md @@ -0,0 +1,32 @@ +# this + +Within an instance method, you have access to a magic variable called `this`. + +`this` is a variable that contains the current instance of the class. + +You can use `this` to access fields or invoke any method. + +```java +class Elmo { + int age; + + void sayHello() { + System.out.println("Hi, I'm Elmo"); + System.out.print("I am "); + System.out.print(this.age); + System.out.println(" years old."); + } + + void startTheShow(String showName) { + this.sayHello(); + System.out.println("Welcome to " + showName); + } +} + +void main() { + Elmo elmo = new Elmo(); + elmo.age = 3; + + elmo.startTheShow("Sesame Street"); +} +``` \ No newline at end of file diff --git a/src/integers/addition.md b/src/integers/addition.md index 007006f..ca2bade 100644 --- a/src/integers/addition.md +++ b/src/integers/addition.md @@ -3,6 +3,7 @@ You can add any two `int`s using the `+` operator. ```java +~void main() { int x = 5; // y will be 6 int y = x + 1; @@ -12,15 +13,18 @@ int z = x + y; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` Adding a negative number does the same thing as subtraction. ```java +~void main() { int x = 5; // y will be 1 int y = x + -4; System.out.println(x); System.out.println(y); +~} ``` diff --git a/src/integers/chained_comparisons.md b/src/integers/chained_comparisons.md index 81d1d4f..334e010 100644 --- a/src/integers/chained_comparisons.md +++ b/src/integers/chained_comparisons.md @@ -4,13 +4,13 @@ When writing an expression in math to say something along the lines of "`x` is greater than zero and less than 5," it is natural to put that `x` in the middle of both operators like so. -```text +```text,no_run 0 < x < 5 ``` This does not work in Java. In order to "chain" comparisons like this, you should combine the results of comparisons using the `&&` operator. -```java +```java,no_run boolean xInRange = 0 < x && x < 5; ``` diff --git a/src/integers/challenges.md b/src/integers/challenges.md index e4dd1c5..a4be09f 100644 --- a/src/integers/challenges.md +++ b/src/integers/challenges.md @@ -2,16 +2,14 @@ Remember the rules for this are -* Try to use only the information given up to this point in this book. -* Try not to give up until you've given it a solid attempt +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt ## Challenge 1 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { int x = 5; int y = 8; @@ -19,27 +17,11 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 5; - int y = 8; - System.out.println(x + y); - } -} -``` - -~ENDIF - ## Challenge 2 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { int x = 5; x--; @@ -49,22 +31,6 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 5; - x--; - x--; - x = x + x; - System.out.println(x); - } -} -``` - -~ENDIF - ## Challenge 3 Make it so that this program correctly determines if the numbers are even or not. @@ -72,9 +38,7 @@ Make it so that this program correctly determines if the numbers are even or not Assume that the values of `x`, `y`, and `z` could be changed. Don't just write out literally `true` and `false` for their current values. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { int x = 5; int y = 4; @@ -91,62 +55,23 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 5; - int y = 4; - int z = 98; - - boolean xIsEven = < CODE HERE >; - System.out.println(xIsEven); - - boolean yIsEven = < CODE HERE >; - System.out.println(yIsEven); - - boolean zIsEven = < CODE HERE >; - System.out.println(zIsEven); - } -} -``` - -~ENDIF - ## Challenge 4 Try dividing a number by zero. What happens? Write down your guess and then try running the program below to see. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { System.out.println(5 / 0); } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - System.out.println(5 / 0); - } -} -``` - -~ENDIF - ## Challenge 5 What can you write in the spot marked that will make the program output 2? -~IF toplevel_anonymous_class - -```java +```java,editable void main() { int x = 5; int y = ; @@ -154,27 +79,11 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 5; - int y = ; - System.out.println(x + y); - } -} -``` - -~ENDIF - ## Challenge 6 What is the output of this code.[^fbarticle] -~IF toplevel_anonymous_class - -```java +```java,editable void main() { System.out.println( 6 / 2 * (1 + 2) @@ -182,18 +91,4 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - System.out.println( - 6 / 2 * (1 + 2) - ); - } -} -``` - -~ENDIF - [^fbarticle]: [Now get in a fight with your relatives about it](https://slate.com/technology/2013/03/facebook-math-problem-why-pemdas-doesnt-always-give-a-clear-answer.html) diff --git a/src/integers/comparison.md b/src/integers/comparison.md index d484cff..d3233b3 100644 --- a/src/integers/comparison.md +++ b/src/integers/comparison.md @@ -5,14 +5,14 @@ In addition to comparing for equality with `==` and `!=`, `int`s can be compared `>` will evaluate to true if the number on the left is greater than the one on the right. -```java +```java,no_run boolean willBeTrue = 5 > 2; boolean willBeFalse = 2 > 5; ``` `<` will evaluate to true if the number on the right is greater than the one on the left. -```java +```java,no_run boolean willBeFalse = 5 < 2; boolean willBeTrue = 2 < 5; ``` @@ -20,7 +20,7 @@ boolean willBeTrue = 2 < 5; If you went to public school like I did, you should be used to imagining that the `>` was the jaw of a shark. Whatever direction the Jaws are facing, thats the one that would need to be bigger for the statement to be true.[^sharks] -```java +```java,no_run // true if the shark is facing the bigger number // false otherwise. boolean result = 9 🦈 5; @@ -28,14 +28,14 @@ boolean result = 9 🦈 5; `>=` behaves the same as `>` except `>=` will evaluate to `true` if the numbers are identical, `>` will not. -```java +```java,no_run boolean willBeTrue = 5 >= 5; boolean willBeFalse = 5 > 5; ``` `<=` has the same relationship to `<` as `>=` does to `>`. -```java +```java,no_run boolean willBeTrue = 5 <= 5; boolean willBeFalse = 5 < 5; ``` diff --git a/src/integers/division.md b/src/integers/division.md index 32fcd5b..87f8ce6 100644 --- a/src/integers/division.md +++ b/src/integers/division.md @@ -3,12 +3,14 @@ You can divide any two `int`s using the `/` operator. ```java +~void main() { int x = 8; // y will be 4 int y = x / 2; System.out.println(x); System.out.println(y); +~} ``` Division with integers gives results in only the [quotient](https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/the-quotient-remainder-theorem) of the result, not the remainder. @@ -16,11 +18,13 @@ Division with integers gives results in only the [quotient](https://www.khanacad So `5 / 2` does not result in `2.5`, but instead just `2`. ```java +~void main() { // 5 / 2 is not 2.5, but instead 2. int x = 5 / 2; // 13 / 3 is not 4.3333, but instead 4. -int y = 13 / 2; +int y = 13 / 3; System.out.println(x); System.out.println(y); +~} ``` diff --git a/src/integers/equality.md b/src/integers/equality.md index 4c47ced..931f100 100644 --- a/src/integers/equality.md +++ b/src/integers/equality.md @@ -6,17 +6,19 @@ Unlike the previous operators, which all take `int`s and produce `int`s as their and produces a `boolean` as its result. ```java +~void main() { // 1 is never equal to 2 // this will be false boolean universeBroken = 1 == 2; System.out.println(universeBroken); -boolean loneliestNumber = 1; -boolean otherLonelyNumber = 2; +int loneliestNumber = 1; +int otherLonelyNumber = 2; // this will be true boolean bothLonely = loneliestNumber == (otherLonelyNumber - 1); System.out.println(bothLonely); +~} ``` It is very important to remember that a single `=` does an assignment. Two equals signs `==` checks for equality. @@ -24,8 +26,10 @@ It is very important to remember that a single `=` does an assignment. Two equal The opposite check, whether things are not equal, can be done with `!=`. ```java +~void main() { // 1 is never equal to 2 // this will be true boolean universeOkay = 1 != 2; System.out.println(universeOkay); +~} ``` diff --git a/src/integers/limits.md b/src/integers/limits.md index d1908e5..425b755 100644 --- a/src/integers/limits.md +++ b/src/integers/limits.md @@ -12,20 +12,24 @@ the type `int` can represent numbers from -231 to 231 - 1. If you try to directly write out a number that is outside of that range, Java will not let you. -```java +```java,does_not_compile +~void main() { // This will not run int tooBig = 999999999999; +~} ``` If you do math that should produce a larger number than is representable, the value will "loop around." ```java +~void main() { // This is the value of 2^31 - 1 int atLimit = 2147483647; // The value will "loop around" to -2^31 int beyondLimit = atLimit + 1; // This will output -2147483648 System.out.println(beyondLimit); +~} ``` There are other types which can represent a larger range of integers, as well as types diff --git a/src/integers/multiplication.md b/src/integers/multiplication.md index a92a890..bd20c08 100644 --- a/src/integers/multiplication.md +++ b/src/integers/multiplication.md @@ -3,6 +3,7 @@ You can multiply any two `int`s using the `*` operator. ```java +~void main() { // x will be 15 int x = 3 * 5; // y will be 75 @@ -13,4 +14,5 @@ int z = x * y; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` diff --git a/src/integers/operator_precedence.md b/src/integers/operator_precedence.md index ee2f20f..6384a87 100644 --- a/src/integers/operator_precedence.md +++ b/src/integers/operator_precedence.md @@ -9,6 +9,7 @@ Parentheses can be used to control this order. None of this should be a surprise if you learned [PEMDAS](https://www.khanacademy.org/math/cc-seventh-grade-math/cc-7th-negative-numbers-multiply-and-divide/cc-7th-order-of-operations/v/introduction-to-order-of-operations) in school. ```java +~void main() { // Following the order of operations: // 2 * 3 + 3 * 9 / 2 - 2 @@ -19,7 +20,7 @@ None of this should be a surprise if you learned [PEMDAS](https://www.khanacadem // 6 + 27 / 2 - 2 // 27 / 2 happens next -// because of integer division, that gives 13 +// because of integer division, that gives 13 // 6 + 13 - 2 // 6 + 13 comes next @@ -28,14 +29,18 @@ None of this should be a surprise if you learned [PEMDAS](https://www.khanacadem // and the final result is 17; int result = 2 * 3 + 3 * 9 / 2 - 2; System.out.println(result); +~} ``` The `==`, `!=`, `>`, `<`, `>=`, and `<=` operators play a part here too[^theyalldo]. They all have a lower precedence order than all the math operators, so you can put them in the middle of any two math expressions. ```java +~void main() { // The == check happens last. boolean areThingsSame = 3 * (4 - 1 + 3) * 4 == 5 * 3 + 1 * 3 * 9; +System.out.println(areThingsSame); +~} ``` [^theyalldo]: Every operator in the language has a defined order of operations with respect to all of the others. I am just showing them to you as they become relevant. diff --git a/src/integers/reassignment.md b/src/integers/reassignment.md index f03b591..b00359a 100644 --- a/src/integers/reassignment.md +++ b/src/integers/reassignment.md @@ -6,11 +6,12 @@ before the reassignment can be used to compute the new value. This is true for all data types, but it is easiest to demonstrate with numbers. ```java +~void main() { int x = 1; System.out.println(x); // x starts as 1, 1 + 1 is 2. -// 2 is the new value of x. +// 2 is the new value of x. x = x + 1; System.out.println(x); @@ -18,6 +19,7 @@ System.out.println(x); // 12 is the new value of x. x = x * x * 3; System.out.println(x); +~} ``` This property was used in the previous example for the `%` operator, but I think it worth calling attention to even if it is "intuitive". diff --git a/src/integers/remainder.md b/src/integers/remainder.md index e1b7de9..97250df 100644 --- a/src/integers/remainder.md +++ b/src/integers/remainder.md @@ -4,6 +4,7 @@ To get the remainder of the division between two integers you can use the `%` op This is called the "modulo operator." ```java +~void main() { int x = 5; // The remainder of 5 / 2 is 1 // y will be 1 @@ -15,6 +16,7 @@ int z = x % 3; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` A common use for this is to make numbers "go in a circle." @@ -22,6 +24,7 @@ A common use for this is to make numbers "go in a circle." For instance, say you wanted to count from 0 up to 3 and then go back to 0. ```java +~void main() { int value = 0; System.out.println(value); @@ -48,6 +51,7 @@ value = (value + 1) % 3; System.out.println(value); // and so on. +~} ``` The fact that all the reassignments of value look identical is something that will be useful in tandem diff --git a/src/integers/shorthands_for_reassignment.md b/src/integers/shorthands_for_reassignment.md index d77b04b..112a402 100644 --- a/src/integers/shorthands_for_reassignment.md +++ b/src/integers/shorthands_for_reassignment.md @@ -4,16 +4,19 @@ A very common thing to do is to take the current value of a variable, perform so computed value back into the variable. ```java +~void main() { int x = 2; System.out.println(x); -x = x * 5 // 10 +x = x * 5; // 10 System.out.println(x); +~} ``` As such, there is a dedicated way to do just that. ```java +~void main() { int x = 1; // This is the same as @@ -26,7 +29,7 @@ x *= 4; // This is the same as // x = x - (x * 5) -x -= (x * 5) +x -= (x * 5); // This is the same as // x = x / 6 @@ -38,12 +41,14 @@ x %= 3; // Pop quiz! System.out.println(x); +~} ``` Of note is that adding or subtracting exactly 1 is common enough that it has its own special shorthand. ```java +~void main() { int x = 0; System.out.println(x); @@ -58,4 +63,5 @@ System.out.println(x); // x -= 1; x--; System.out.println(x); +~} ``` diff --git a/src/integers/subtraction.md b/src/integers/subtraction.md index 7422a2e..109a097 100644 --- a/src/integers/subtraction.md +++ b/src/integers/subtraction.md @@ -3,6 +3,7 @@ You can subtract any two `int`s using the `-` operator. ```java +~void main() { int x = 5; // y will be 4 int y = x - 1; @@ -12,15 +13,18 @@ int z = x - y; System.out.println(x); System.out.println(y); System.out.println(z); +~} ``` Subtracting a negative number does the same thing as addition. ```java +~void main() { int x = 5; // y will be 9 int y = x - -4; System.out.println(x); System.out.println(y); +~} ``` diff --git a/src/loops/break.md b/src/loops/break.md index 830f828..fbb9c03 100644 --- a/src/loops/break.md +++ b/src/loops/break.md @@ -6,6 +6,7 @@ to `false`. This can be bypassed by using the `break` statement. ```java +~void main() { int x = 5; while (x > 0) { if (x == 2) { @@ -17,6 +18,7 @@ while (x > 0) { System.out.println( "Final value of x is " + x ); +~} ``` If a `break` is reached, the code in the loop stops running immediately. @@ -26,6 +28,7 @@ This can be useful in a variety of situations, but notably it is the only way to from an otherwise endless loop. ```java +~void main() { while (true) { System.out.println( "The people started singing it not knowing what it was" @@ -34,4 +37,5 @@ while (true) { // Will immediately leave the loop break; } +~} ``` diff --git a/src/loops/challenges.md b/src/loops/challenges.md index 023bd2f..8ab05c3 100644 --- a/src/loops/challenges.md +++ b/src/loops/challenges.md @@ -11,40 +11,27 @@ It might take awhile before you feel truly comfortable with this. That is normal Remember the rules for this are -* Try to use only the information given up to this point in this book. -* Try not to give up until you've given it a solid attempt +- Try to use only the information given up to this point in this book. +- Try not to give up until you've given it a solid attempt ## Challenge 1 Write code that outputs every number from `1` to `10`. -~IF toplevel_anonymous_class -```java +```java,editable void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - - } -} -``` - -~ENDIF ## Challenge 2 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class -```java +```java,editable void main() { int x = 0; while (x < 10) { @@ -54,29 +41,12 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 0; - while (x < 10) { - System.out.println(x); - x++; - } - } -} -``` - -~ENDIF ## Challenge 3 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { int x = 0; while (x <= 10) { @@ -86,29 +56,11 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 0; - while (x <= 10) { - System.out.println(x); - x++; - } - } -} -``` - -~ENDIF - ## Challenge 4 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { int x = 0; while (x < 10) { @@ -121,32 +73,12 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 0; - while (x < 10) { - if (x % 3 == 0) { - break; - } - System.out.println(x); - x++; - } - } -} -``` - -~ENDIF ## Challenge 5 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { int x = 0; while (x < 10) { @@ -159,33 +91,12 @@ void main() { } ``` -~ELSE - -```java -public class Main { - - public static void main(String[] args) { - int x = 0; - while (x < 10) { - if (x % 3 == 0) { - continue; - } - System.out.println(x); - x++; - } - } -} -``` - -~ENDIF ## Challenge 6 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { int x = 1; while (x < 10) { @@ -194,62 +105,22 @@ void main() { System.out.println(x * y); y++; } - - x++; - } -} -``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 1; - while (x < 10) { - int y = 2; - while (y < 5) { - System.out.println(x * y); - y++; - } - - x++; - } + x++; } } ``` -~ENDIF - ## Challenge 7 What will this program output when run? Write down your guess and then try running it. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - int x = 0; - String scream = "a"; - while (!scream.equals("aaaaaaaa")) { - scream = scream + "a"; - System.out.println(x); - System.out.println(scream); - } - } -} -``` - -~ENDIF ## Challenge 8 @@ -267,28 +138,12 @@ e t ``` -~IF toplevel_anonymous_class - -```java +```java,editable void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Change this value to test your code. - String name = "Bridget"; - - // - } -} -``` - -~ENDIF ## Challenge 9 @@ -308,9 +163,7 @@ a S ``` -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // Change this value to test your code. String name = "Samantha"; @@ -319,20 +172,6 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Change this value to test your code. - String name = "Samantha"; - - // - } -} -``` - -~ENDIF ## Challenge 10 @@ -377,9 +216,7 @@ If the initial number is `15` you should have this as output. 1 ``` -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // Change this value to test your code. int n = 15; @@ -388,44 +225,17 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Change this value to test your code. - int n = 15; - - // - } -} -``` - -~ENDIF ## Challenge 11 Write code that outputs every third number from `37` to `160`. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - - } -} -``` - -~ENDIF ## Challenge 12 @@ -433,9 +243,7 @@ Write code that outputs the number of vowels in `name`. Treat `y` as a vowel. Treat the characters `a`, `A`, `e`, `E`, `i`, `I`, `o`, `O`, `u`, `U`, `y`, and `Y` as vowels. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // Change this value to test your code. String name = "Damian"; @@ -444,20 +252,6 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Change this value to test your code. - String name = "Damian"; - - // - } -} -``` - -~ENDIF ## Challenge 13 @@ -468,9 +262,7 @@ same. Make sure to not treat non-alphabetic characters like `!` and `?` as consonants. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // Change this value to test your code. String name = "Messi"; @@ -479,29 +271,13 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Change this value to test your code. - String name = "Messi"; - - // - } -} -``` - -~ENDIF ## Challenge 14 Rewrite the following code to not have the `shouldBreak` variable and instead to use a labeled break. -~IF toplevel_anonymous_class - -```java +```java,editable void main() { // Don't think too hard about what these numbers mean. int x = 3; @@ -525,32 +301,3 @@ void main() { } ``` -~ELSE - -```java -public class Main { - public static void main(String[] args) { - // Don't think too hard about what these numbers mean. - int x = 3; - int y = 0; - - boolean shouldBreak = false; - while (shouldBreak && x < 100) { - while (y < 100) { - System.out.println("x is " + x); - System.out.println("y is " + y); - x = x * y; - if (x == 0) { - shouldBreak = true; - break; - } - y++; - } - } - - System.out.println("Done"); - } -} -``` - -~ENDIF diff --git a/src/loops/continue.md b/src/loops/continue.md index 9ce9b18..fc4f700 100644 --- a/src/loops/continue.md +++ b/src/loops/continue.md @@ -5,6 +5,7 @@ Unless there is a `break`, while loops will usually run all the code in their bo The only other situation this will not happen is if a `continue` statement is reached. ```java +~void main() { // Will output a message for every number except 4 int x = 5; while (x > 0) { @@ -14,6 +15,7 @@ while (x > 0) { System.out.println(x + " is a good number"); x--; } +~} ``` If a `continue` is reached the code in the loop stops running immediately but, unlike `break`, diff --git a/src/loops/counting_down.md b/src/loops/counting_down.md index 4d0be13..4110733 100644 --- a/src/loops/counting_down.md +++ b/src/loops/counting_down.md @@ -8,21 +8,25 @@ number, but with a loop whose condition is that the number is greater than the n to stop at, and a line at the bottom of the loop which decrements the current number. ```java +~void main() { int currentNumber = 100; while (currentNumber >= 1) { System.out.println(currentNumber); currentNumber--; } +~} ``` Similar to when counting up if the condition was not `currentNumber >= 1` and instead was `currentNumber > 1`, the loop would stop at `2` ```java +~void main() { int currentNumber = 100; // Stops at 2 while (currentNumber > 1) { System.out.println(currentNumber); currentNumber--; } +~} ``` diff --git a/src/loops/counting_up.md b/src/loops/counting_up.md index 48805b5..030fc74 100644 --- a/src/loops/counting_up.md +++ b/src/loops/counting_up.md @@ -7,11 +7,13 @@ number, a loop whose condition is that the number is less than the number you wa to stop at, and a line at the bottom of the loop which increments the current number. ```java +~void main() { int currentNumber = 1; while (currentNumber <= 100) { System.out.println(currentNumber); currentNumber++; } +~} ``` Take note that in this example the condition is `currentNumber <= 100`, so the code in the @@ -19,10 +21,12 @@ loop will run when `currentNumber` is equal to `100`. If the condition was `curr it would stop at `99`. ```java +~void main() { int currentNumber = 1; // Stops at 99 while (currentNumber < 100) { System.out.println(currentNumber); currentNumber++; } +~} ``` diff --git a/src/loops/do_while.md b/src/loops/do_while.md index b79f22f..711b119 100644 --- a/src/loops/do_while.md +++ b/src/loops/do_while.md @@ -1,19 +1,21 @@ # Do -One variation on a while loop is a "do-while loop." +One variation on a `while` loop is a "do-while loop." ```java +~void main() { int x = 0; do { System.out.println(x); - x++ + x++; } while(x < 5); +~} ``` You write `do`, some code inside of `{` and `}`, and then `while`, a condition inside of `(` and `)`, and finally a semicolon. -```java +```java,no_run do { } while (CONDITION); @@ -23,14 +25,16 @@ In most situations it works exactly the same as a regular while loop. The only d is that the first time the loop is reached the condition for the loop is not checked. ```java +~void main() { int x = 0; do { System.out.println("this will run"); -} while (x != 0) +} while (x != 0); while (x != 0) { System.out.println("this will not run"); } +~} ``` One way to remember the difference is that in a "do-while loop" you always "do the thing" diff --git a/src/loops/endless_loops.md b/src/loops/endless_loops.md index d8c0c10..94b7fad 100644 --- a/src/loops/endless_loops.md +++ b/src/loops/endless_loops.md @@ -4,20 +4,24 @@ If a while loop will never end, we call that an endless loop. This can happen if the condition is a constant like `while (true)` -```java +```java,no_run +~void main() { while (true) { System.out.println("This is the song that never ends"); } +~} ``` Or if the variables tested in the condition are not updated inside of the loop. -```java +```java,no_run +~void main() { // x is never changed int x = 0; while (x != 1) { System.out.println("It goes on and on my friends"); } +~} ``` Many games should never really "finish" so at the very start of that sort of program it is not uncommon diff --git a/src/loops/iterate_over_a_string.md b/src/loops/iterate_over_a_string.md index 57e5ed4..4aecc60 100644 --- a/src/loops/iterate_over_a_string.md +++ b/src/loops/iterate_over_a_string.md @@ -5,6 +5,7 @@ especially useful when you want to iterate over each character in a `String`. ```java +~void main() { String name = "Avril"; int index = 0; @@ -12,4 +13,5 @@ while (index < name.length()) { System.out.println(name.charAt(index)); index++; } +~} ``` diff --git a/src/loops/iteration.md b/src/loops/iteration.md index 95b7911..2f4ec38 100644 --- a/src/loops/iteration.md +++ b/src/loops/iteration.md @@ -4,6 +4,7 @@ Loops potentially run code multiple times. Each time one goes from its top to it we call that an "iteration" of the loop. ```java +~void main() { int x = 0; while (x < 5) { // On the 1st iteration x will be 0 @@ -13,6 +14,7 @@ while (x < 5) { System.out.println(x); x++ } +~} ``` When the purpose of a loop is to run for every thing in some sequence of things, diff --git a/src/loops/labeled_break.md b/src/loops/labeled_break.md index ac61352..8329ddb 100644 --- a/src/loops/labeled_break.md +++ b/src/loops/labeled_break.md @@ -3,25 +3,27 @@ If you want to break out of a nested loop from one of the inner loops, you can use a "labeled break." ```java +~void main() { outerLoop: while (true) { while (true) { break outerLoop; } } +~} ``` To do this, before your outer while or do-while loop you need to add a "label" followed by a `:`. A label is an arbitrary name just like a variable's name. -```java +```java,no_run