Skip to content

Commit b420f22

Browse files
committed
Loops III
1 parent 1af9198 commit b420f22

File tree

10 files changed

+374
-24
lines changed

10 files changed

+374
-24
lines changed

src/SUMMARY.md

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,16 @@ Make them do one. -->
564564
- [Recurse Over a String](./recursion/recursing_over_strings.md)
565565
- [Recurse Over an Array](./recursion/recursing_over_arrays.md)
566566

567-
<!--- [HashMap](./hash_map.md)
568-
- [Multi-Dimensional Arrays](./multi_dimensional_arrays.md)
569-
- [Iterable and Iterator](./iterable_and_iterator.md)
567+
- [Loops III](./loops_iii.md)
568+
- [For-each loops](./loops_iii/for_each_loops.md)
569+
- [Arrays](./loops_iii/arrays.md)
570+
- [Iterable and Iterator](./loops_iii/iterable_and_iterator.md)
571+
- [ArrayList](./loops_iii/arraylist.md)
572+
- [String](./loops_iii/string.md)
573+
- [Concurrent Modifications](./loops_iii/concurrent_modifications.md)
574+
- [Inferred Types](./loops_iii/inferred_types.md)
575+
576+
# Concepts II
570577

571578
- [Encapsulation](./encapsulation.md)
572579
- [Implementation Details](./encapsulation/implementation_details.md)
@@ -577,6 +584,34 @@ Make them do one. -->
577584
- [Leaky Abstractions](./encapsulation/leaky_abstractions.md)
578585
- [Information Hiding](./encapsulation/information_hiding.md)
579586

587+
# Metaprogramming
588+
589+
- [Reflection](./reflection.md)
590+
- [Class Objects](./reflection/class_objects.md)
591+
- [Get all Fields](./reflection/get_all_fields.md)
592+
- [Get a Field]()
593+
- [Set a Field]()
594+
- [Get a Method]()
595+
- [Call a Method]()
596+
- [Get a Constructor]()
597+
598+
- [Annotations](./annotations.md)
599+
600+
# Concepts III
601+
602+
- [Acronyms](./acronyms.md)
603+
- [Niches](./acronyms/niches.md)
604+
- [Usage Contexts](./acronyms/usage_contexts.md)
605+
- [Ambiguity](./acronyms/ambiguity.md)
606+
- [Familiarity](./acronyms/familiarity.md)
607+
- [Elaboration](./acronyms/elaboration.md)
608+
609+
<!--- [HashMap](./hash_map.md)
610+
- [Multi-Dimensional Arrays](./multi_dimensional_arrays.md)
611+
- [Iterable and Iterator](./iterable_and_iterator.md)
612+
613+
614+
580615
581616
- [Loops III](./loops_iii.md)
582617
- [For-each loops](./loops_iii/for_each_loops.md)
@@ -618,27 +653,7 @@ Make them do one. -->
618653
- [Low Level versus High Level](./tcp_over_ip/low_level_versus_high_level.md)
619654
- [Data Formats]()
620655
621-
# Metaprogramming
622656
623-
- [Reflection](./reflection.md)
624-
- [Class Objects](./reflection/class_objects.md)
625-
- [Get all Fields](./reflection/get_all_fields.md)
626-
- [Get a Field]()
627-
- [Set a Field]()
628-
- [Get a Method]()
629-
- [Call a Method]()
630-
- [Get a Constructor]()
631-
632-
- [Annotations]()
633-
634-
# Concepts III
635-
636-
- [Acronyms](./acronyms.md)
637-
- [Niches](./acronyms/niches.md)
638-
- [Usage Contexts](./acronyms/usage_contexts.md)
639-
- [Ambiguity](./acronyms/ambiguity.md)
640-
- [Familiarity](./acronyms/familiarity.md)
641-
- [Elaboration](./acronyms/elaboration.md)
642657
643658
# Code Structure VI
644659

src/annotations.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Annotations

src/loops_iii/arraylist.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ArrayList
2+
3+
One class which implements `Iterable` is `ArrayList`.
4+
5+
```java
6+
~import java.util.ArrayList;
7+
~
8+
~class Main {
9+
~ void main() {
10+
ArrayList<String> donutEaters = new ArrayList<>();
11+
donutEaters.add("Chief Wiggum");
12+
donutEaters.add("Homer Simpson");
13+
14+
Iterator<String> donutEatersIterator = donutEaters.iterator();
15+
// Check if there is a next element
16+
while (donutEatersIterator.hasNext()) {
17+
// If there is, get it and advance the iterator
18+
String donutEater = donutEatersIterator.next();
19+
20+
System.out.println(donutEater + " eats donuts");
21+
}
22+
~ }
23+
~}
24+
```
25+
26+
This means you can loop over it with a for-each loop same as an array.
27+
28+
```java
29+
~import java.util.ArrayList;
30+
~
31+
~class Main {
32+
~ void main() {
33+
ArrayList<String> donutEaters = new ArrayList<>();
34+
donutEaters.add("Chief Wiggum");
35+
donutEaters.add("Homer Simpson");
36+
37+
for (String donutEater : donutEaters) {
38+
System.out.println(donutEater + " eats donuts");
39+
}
40+
~ }
41+
~}
42+
```

src/loops_iii/arrays.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Arrays
2+
3+
When you use a for-each loop on an array, it acts the same as the kind of for-loop
4+
you would have written before with an explicit index.
5+
6+
```java
7+
record Drink(String name, double mgCaffeinePerCup) {}
8+
9+
~class Main {
10+
~ void main() {
11+
Drink[] drinks = {
12+
new Drink("Black Coffee", 95),
13+
new Drink("Milk", 0),
14+
new Drink("Green Tea", 35)
15+
};
16+
17+
// This loop functions the same as the loop below
18+
for (int i = 0; i < drinks.length; i++) {
19+
Drink drink = drinks[i];
20+
21+
System.out.println(
22+
drink.name()
23+
+ " has "
24+
+ drink.mgCaffeinePerCup()
25+
+ "mg caffiene per cup"
26+
);
27+
}
28+
29+
System.out.println("------------------");
30+
31+
for (Drink drink : drinks) {
32+
System.out.println(
33+
drink.name()
34+
+ " has "
35+
+ drink.mgCaffeinePerCup()
36+
+ "mg caffiene per cup"
37+
);
38+
}
39+
~ }
40+
~}
41+
```
42+
43+
This doesn't mean that the old style of for loop is useless now. You will still want that
44+
if you need to know which element in your array you are dealing with
45+
or if you are doing a more interesting form of iteration.
46+
47+
```java
48+
record Drink(String name, double mgCaffeinePerCup) {}
49+
50+
~class Main {
51+
~ void main() {
52+
Drink[] drinks = {
53+
new Drink("Black Coffee", 95),
54+
new Drink("Milk", 0),
55+
new Drink("Green Tea", 35)
56+
};
57+
58+
59+
// If loop actually cares to use `i` beyond just accessing
60+
// the right element in the array
61+
for (int i = 0; i < drinks.length; i++) {
62+
Drink drink = drinks[i];
63+
64+
// Which you might want for display logic
65+
System.out.println(
66+
"[" + i + "]: " + drink.name()
67+
);
68+
69+
// Or to mutate the original array
70+
drinks[i] = new Drink(
71+
drink.name(),
72+
drink.mgCaffeinePerCup() + 100
73+
);
74+
}
75+
~ }
76+
~}
77+
```
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,81 @@
11
# Concurrent Modifications
2+
3+
If you are looping over a collection with a for-each loop you generally
4+
cannot remove things from that collection at the same time. Doing so should
5+
trigger a `ConcurrentModificationException`.[^should]
6+
7+
```java,panics
8+
~import java.util.ArrayList;
9+
~
10+
record Sandwich(
11+
int turkeySlices,
12+
int cheeseSlices,
13+
boolean mayo
14+
) {}
15+
16+
~class Main {
17+
~ void main() {
18+
ArrayList<Sandwich> sandwiches = new ArrayList<>();
19+
var turkeyAndCheddar = new Sandwich(2, 2, true);
20+
var grilledCheese = new Sandwich(0, 4, false);
21+
var bigTurkeyAndCheddar = new Sandwich(10, 10, true);
22+
var theWisconsinFreak = new Sandwich(0, 20, true);
23+
24+
sandwiches.add(turkeyAndCheddar);
25+
sandwiches.add(grilledCheese);
26+
sandwiches.add(bigTurkeyAndCheddar);
27+
sandwiches.add(theWisconsinFreak);
28+
29+
for (Sandwich sandwich : sandwiches) {
30+
if (sandwich.mayo()) { // Some people don't like Mayo
31+
// But we can't get rid of them during the loop
32+
sandwiches.remove(sandwich);
33+
}
34+
}
35+
~ }
36+
~}
37+
```
38+
39+
If you want to remove an element at the same time as iterating over specifically an `ArrayList`, you
40+
can get creative with indexes and regular loops.[^remove]
41+
42+
```java
43+
~import java.util.ArrayList;
44+
~
45+
record Sandwich(
46+
int turkeySlices,
47+
int cheeseSlices,
48+
boolean mayo
49+
) {}
50+
51+
~class Main {
52+
~ void main() {
53+
ArrayList<Sandwich> sandwiches = new ArrayList<>();
54+
var turkeyAndCheddar = new Sandwich(2, 2, true);
55+
var grilledCheese = new Sandwich(0, 4, false);
56+
var bigTurkeyAndCheddar = new Sandwich(10, 10, true);
57+
var theWisconsinFreak = new Sandwich(0, 20, true);
58+
59+
sandwiches.add(turkeyAndCheddar);
60+
sandwiches.add(grilledCheese);
61+
sandwiches.add(bigTurkeyAndCheddar);
62+
sandwiches.add(theWisconsinFreak);
63+
64+
for (int i = 0; i < sandwiches.size(); i++) {
65+
Sandwich sandwich = sandwiches.get(i);
66+
if (sandwich.mayo()) { // Some people don't like Mayo
67+
sandwiches.remove(sandwich);
68+
i--; // Subtracting one from our current index sycs us back up
69+
}
70+
}
71+
72+
System.out.println(sandwiches);
73+
~ }
74+
~}
75+
```
76+
77+
[^should]: The reason I say "should" is that doing the book keeping needed to know when
78+
this has happened can be hard and not all `Iterator`s in the world will do it. The check is what we would call "best effort."
79+
80+
[^remove]: And, as these footnotes have alluded, there is a `.remove` method on `Iterator`. We'll cover it
81+
later.

src/loops_iii/for_each_loops.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,38 @@
11
# For-each loops
2+
3+
Where a normal `for` loop is more or less a shorthand for a certain kind of `while` loop,
4+
a for-each loop[^enhanced] is a shorthand for the general concept of iterating over a collection
5+
of elements.
6+
7+
To use a for-each loop, write `for` then in the parentheses write a variable declaration, a `:`, and the
8+
collection of elements you are iterating over.
9+
10+
```
11+
for (<VARIABLE DECLARATION> : <COLLECTION>) {
12+
<BODY>
13+
}
14+
```
15+
16+
```java
17+
record Bread(String name, boolean french) {}
18+
19+
~class Main {
20+
~ void main() {
21+
Bread[] breads = {
22+
new Bread("Croissant", true),
23+
new Bread("Baguette", true),
24+
new Bread("Boston Brown Bread", false)
25+
};
26+
27+
for (Bread bread : breads) {
28+
System.out.println(
29+
bread.name()
30+
+ (bread.french() ? " is french" : " is not french")
31+
);
32+
}
33+
~ }
34+
~}
35+
```
36+
37+
38+
[^enhanced]: You might see this referred to as an "enhanced for statement." [That is its name in the language spec](https://docs.oracle.com/javase/specs/jls/se23/html/jls-14.html#jls-14.14.2) but not the name most people will use.

src/loops_iii/inferred_types.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Inferred Types
2+
3+
A variable declaration in a for-each loop can make use of `var` to infer its type.
4+
5+
```java
6+
~class Main {
7+
~ void main() {
8+
String[] chairMaterials = { "wicker", "wood", "plastic" }
9+
for (var chairMaterial : chairMaterials) {
10+
System.out.println(chairMaterial);
11+
}
12+
~ }
13+
~}
14+
```
15+
16+
And this is good to know for the same reasons you would use `var` other places in Java.
17+
Writing `Book book` can be a drain on the soul.

0 commit comments

Comments
 (0)