Generics
Generic Methods
Method-Level Type Parameters
Your utility class needs a swap method that works with any type. You don't want a generic class - just one method. Generic methods declare their own type parameters, independent of any class generics.
Basic generic method
Declare type parameter before return type.
import java.util.*;
public class Basic {
public static <T> void print(T item) {
System.out.println(" Item: " + item);
}
public static <T> void printArray(T[] array) {
System.out.print(" Array: [");
for (int i = 0; i < array.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(array[i]);
}
System.out.println("]");
}
public static void main(String[] args) {
System.out.println("Basic generic methods:\n");
print(42);
print("Hello");
print(3.14);
Integer[] ints = {1, 2, 3, 4, 5};
String[] strs = {"a", "b", "c"};
printArray(ints);
printArray(strs);
// Generic methods have type parameters: <T>
// Type parameter comes before return type
// Can be used in parameters and return type
// Java infers type from arguments
System.out.println("\nIdentity function:");
class Utils {
public static <T> T identity(T value) {
return value;
}
}
Integer num = Utils.identity(42);
String text = Utils.identity("Hello");
System.out.println(" Number: " + num);
System.out.println(" Text: " + text);
System.out.println("\nSwap elements:");
class ArrayOps {
public static <T> void swap(T[] array, int i, int j) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Integer[] numbers = {1, 2, 3, 4, 5};
System.out.println(" Before: " + Arrays.toString(numbers));
ArrayOps.swap(numbers, 0, 4);
System.out.println(" After: " + Arrays.toString(numbers));
System.out.println("\nGet first:");
class Getter {
public static <T> T getFirst(T[] array) {
return array.length > 0 ? array[0] : null;
}
public static <T> T getFirst(List<T> list) {
return list.isEmpty() ? null : list.get(0);
}
}
System.out.println(" First int: " + Getter.getFirst(ints));
System.out.println(" First string: " + Getter.getFirst(strs));
System.out.println("\nCreate pair:");
class Pair<K, V> {
K key;
V value;
Pair(K key, V value) {
this.key = key;
this.value = value;
}
public String toString() {
return "(" + key + ", " + value + ")";
}
}
class PairFactory {
public static <K, V> Pair<K, V> create(K key, V value) {
return new Pair<>(key, value);
}
}
Pair<String, Integer> p1 = PairFactory.create("age", 30);
Pair<Integer, String> p2 = PairFactory.create(1, "first");
System.out.println(" Pair 1: " + p1);
System.out.println(" Pair 2: " + p2);
System.out.println("\nContains check:");
class Checker {
public static <T> boolean contains(T[] array, T item) {
for (T element : array) {
if (element.equals(item)) {
return true;
}
}
return false;
}
}
int searchNumber = 3;
System.out.println(" ints contains " + searchNumber + ": " +
Checker.contains(ints, searchNumber));
System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));
}
}
import java.util.*;
public class Basic {
public static <T> void print(T item) {
System.out.println(" Item: " + item);
}
public static <T> void printArray(T[] array) {
System.out.print(" Array: [");
for (int i = 0; i < array.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(array[i]);
}
System.out.println("]");
}
public static void main(String[] args) {
System.out.println("Basic generic methods:\n");
print(42);
print("Hello");
print(3.14);
Integer[] ints = {1, 2, 3, 4, 5};
String[] strs = {"a", "b", "c"};
printArray(ints);
printArray(strs);
// Generic methods have type parameters: <T>
// Type parameter comes before return type
// Can be used in parameters and return type
// Java infers type from arguments
System.out.println("\nIdentity function:");
class Utils {
public static <T> T identity(T value) {
return value;
}
}
Integer num = Utils.identity(42);
String text = Utils.identity("Hello");
System.out.println(" Number: " + num);
System.out.println(" Text: " + text);
System.out.println("\nSwap elements:");
class ArrayOps {
public static <T> void swap(T[] array, int i, int j) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Integer[] numbers = {1, 2, 3, 4, 5};
System.out.println(" Before: " + Arrays.toString(numbers));
ArrayOps.swap(numbers, 0, 4);
System.out.println(" After: " + Arrays.toString(numbers));
System.out.println("\nGet first:");
class Getter {
public static <T> T getFirst(T[] array) {
return array.length > 0 ? array[0] : null;
}
public static <T> T getFirst(List<T> list) {
return list.isEmpty() ? null : list.get(0);
}
}
System.out.println(" First int: " + Getter.getFirst(ints));
System.out.println(" First string: " + Getter.getFirst(strs));
System.out.println("\nCreate pair:");
class Pair<K, V> {
K key;
V value;
Pair(K key, V value) {
this.key = key;
this.value = value;
}
public String toString() {
return "(" + key + ", " + value + ")";
}
}
class PairFactory {
public static <K, V> Pair<K, V> create(K key, V value) {
return new Pair<>(key, value);
}
}
Pair<String, Integer> p1 = PairFactory.create("age", 30);
Pair<Integer, String> p2 = PairFactory.create(1, "first");
System.out.println(" Pair 1: " + p1);
System.out.println(" Pair 2: " + p2);
System.out.println("\nContains check:");
class Checker {
public static <T> boolean contains(T[] array, T item) {
for (T element : array) {
if (element.equals(item)) {
return true;
}
}
return false;
}
}
int searchNumber = 1;
System.out.println(" ints contains " + searchNumber + ": " +
Checker.contains(ints, searchNumber));
System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));
}
}
import java.util.*;
public class Basic {
public static <T> void print(T item) {
System.out.println(" Item: " + item);
}
public static <T> void printArray(T[] array) {
System.out.print(" Array: [");
for (int i = 0; i < array.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(array[i]);
}
System.out.println("]");
}
public static void main(String[] args) {
System.out.println("Basic generic methods:\n");
print(42);
print("Hello");
print(3.14);
Integer[] ints = {1, 2, 3, 4, 5};
String[] strs = {"a", "b", "c"};
printArray(ints);
printArray(strs);
// Generic methods have type parameters: <T>
// Type parameter comes before return type
// Can be used in parameters and return type
// Java infers type from arguments
System.out.println("\nIdentity function:");
class Utils {
public static <T> T identity(T value) {
return value;
}
}
Integer num = Utils.identity(42);
String text = Utils.identity("Hello");
System.out.println(" Number: " + num);
System.out.println(" Text: " + text);
System.out.println("\nSwap elements:");
class ArrayOps {
public static <T> void swap(T[] array, int i, int j) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Integer[] numbers = {1, 2, 3, 4, 5};
System.out.println(" Before: " + Arrays.toString(numbers));
ArrayOps.swap(numbers, 0, 4);
System.out.println(" After: " + Arrays.toString(numbers));
System.out.println("\nGet first:");
class Getter {
public static <T> T getFirst(T[] array) {
return array.length > 0 ? array[0] : null;
}
public static <T> T getFirst(List<T> list) {
return list.isEmpty() ? null : list.get(0);
}
}
System.out.println(" First int: " + Getter.getFirst(ints));
System.out.println(" First string: " + Getter.getFirst(strs));
System.out.println("\nCreate pair:");
class Pair<K, V> {
K key;
V value;
Pair(K key, V value) {
this.key = key;
this.value = value;
}
public String toString() {
return "(" + key + ", " + value + ")";
}
}
class PairFactory {
public static <K, V> Pair<K, V> create(K key, V value) {
return new Pair<>(key, value);
}
}
Pair<String, Integer> p1 = PairFactory.create("age", 30);
Pair<Integer, String> p2 = PairFactory.create(1, "first");
System.out.println(" Pair 1: " + p1);
System.out.println(" Pair 2: " + p2);
System.out.println("\nContains check:");
class Checker {
public static <T> boolean contains(T[] array, T item) {
for (T element : array) {
if (element.equals(item)) {
return true;
}
}
return false;
}
}
int searchNumber = 6;
System.out.println(" ints contains " + searchNumber + ": " +
Checker.contains(ints, searchNumber));
System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));
}
}
public static void main(String[] args)
17public static void main(String[] args) {18 System.out.println("Basic generic methods:\n");outputBasic generic methods: Basic generic methods:public static <T> void print(T item)
pass 1 of 33public class Basic {4 public static <T> void print(T item42) {5 System.out.println(" Item: " + item42);6 }output Item: 42All 3 passes — pass 1 is the card above pass item1 42 2 Hello 3 3.14 public static <T> void printArray(T[] array)
pass 1 of 28public static <T> void printArray(T[] array) {9 System.out.print(" Array: [");10 for (int i = 0; i < array.length; i++) {output Array: [for (int i = 0; i < array.length; i++)
pass 1 of 89System.out.print(" Array: [");10for (int i0 = 0; i < array.length5; i++) {11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]1);13}output1All 8 passes — pass 1 is the card above pass iarray.lengtharray[i]1 0 5 1 2 1 5 — 3 2 5 — 4 3 5 — 5 4 5 — 6 0 3 a 7 1 3 — 8 2 3 — if (i > 0)
pass 1 of 610for (int i = 0; i < array.length; i++) {11 if (i1 > 0) System.out.print(", ");12 System.out.print(array[i]);output,All 6 passes — pass 1 is the card above pass i1 1 2 2 3 3 4 4 5 1 6 2 System.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]2);13}output2values this step1iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]3);13}output3values this step2iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]4);13}output4values this step3iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]5);13}output5values this step4iSystem.out.println("]");
13 }14 System.out.println("]");15}output]public static <T> void printArray(T[] array)
pass 2 of 28public static <T> void printArray(T[] array) {9 System.out.print(" Array: [");10 for (int i = 0; i < array.length; i++) {output Array: [System.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]b);13}outputbvalues this step1iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]c);13}outputcvalues this step2iSystem.out.println("]");
13 }14 System.out.println("]");15}output]System.out.println(" Identity function:");
35System.out.println("\nIdentity function:");output Identity function: Identity function:public static <T> T identity(T value)
pass 1 of 237class Utils {38 public static <T> T identity(T value42) {39 return value42;40 }public static <T> T identity(T value)
pass 2 of 237class Utils {38 public static <T> T identity(T valueHello) {39 return valueHello;40 }System.out.println(" Number: " + num);
46System.out.println(" Number: " + num42);47System.out.println(" Text: " + textHello);4849System.out.println("\nSwap elements:");5051class ArrayOps {52 public static <T> void swap(T[] array, int i, int j) {53 T temp = array[i];54 array[i] = array[j];55 array[j] = temp;56 }57}5859Integer[] numbers = {1, 2, 3, 4, 5};60System.out.println(" Before: " + Arrays.toString(numbers));61ArrayOps.swap(numbers, 0, 4);output Number: 42 Number: 42 Text: Hello Text: Hello Swap elements: Swap elements: Before: [1, 2, 3, 4, 5] Before: [1, 2, 3, 4, 5]temp ← 1, array[i] ← 5, array[j] ← 1
51class ArrayOps {52 public static <T> void swap(T[] array, int i0, int j4) {53 T temp→ 1 = array[i]1;54 array[i]→ 5 = array[j]5;55 array[j]→ 1 = temp1;56 }System.out.println(" After: " + Arrays.toString(numbers));
61ArrayOps.swap(numbers, 0, 4);62System.out.println(" After: " + Arrays.toString(numbers));6364System.out.println("\nGet first:");output After: [5, 2, 3, 4, 1] After: [5, 2, 3, 4, 1] Get first: Get first:public static <T> T getFirst(T[] array)
pass 1 of 366class Getter {67 public static <T> T getFirst(T[] array) {68 return array.length5 > 0 ? array[0]1 : null;69 }All 3 passes — pass 1 is the card above pass array.lengtharray[0]1 5 1 2 3 a 3 3 a System.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));System.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));output First string: aSystem.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));7879System.out.println("\nCreate pair:");output First string: a Create pair: Create pair:public static <K, V> Pair<K, V> create(K key, V value)
pass 1 of 295class PairFactory {96 public static <K, V> Pair<K, V> create(K keyage, V value30) {97 return new Pair<>(key, value);98 }this.key ← age, this.value ← 30
pass 1 of 285Pair(K keyage, V value30) {86 this.key→ age = keyage;87 this.value→ 30 = value30;88}public static <K, V> Pair<K, V> create(K key, V value)
pass 2 of 295class PairFactory {96 public static <K, V> Pair<K, V> create(K key1, V valuefirst) {97 return new Pair<>(key, value);98 }this.key ← 1, this.value ← first
pass 2 of 285Pair(K key1, V valuefirst) {86 this.key→ 1 = key1;87 this.value→ first = valuefirst;88}System.out.println(" Pair 1: " + p1);
104System.out.println(" Pair 1: " + p1(age, 30));105System.out.println(" Pair 2: " + p2(1, first));106107System.out.println("\nContains check:");108109class Checker {110 public static <T> boolean contains(T[] array, T item) {111 for (T element : array) {112 if (element.equals(item)) {113 return true;114 }115 }116 return false;117 }118}119120int searchNumber = 3; //@searchNumber=3, 1, 6121System.out.println(" ints contains " + searchNumber3 + ": " +122 Checker.contains(ints, searchNumber3));123System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));output Pair 1: (age, 30) Pair 1: (age, 30) Pair 2: (1, first) Pair 2: (1, first) Contains check: Contains check:public static <T> boolean contains(T[] array, T item)
pass 1 of 2109class Checker {110 public static <T> boolean contains(T[] array, T item3) {111 for (T element : array) {for (T element : array)
pass 1 of 6110public static <T> boolean contains(T[] array, T item) {111 for (T element1 : array) {112 if (element.equals(item)) {All 6 passes — pass 1 is the card above pass elementitem1 1 — 2 2 — 3 3 3 4 a — 5 b — 6 c — if (element.equals(item))
111for (T element : array) {112 if (element.equals(item3)) {113 return true;114 }System.out.println(" ints contains " + searchNumber + ": " +
120 int searchNumber = 3; //@searchNumber=3, 1, 6121 System.out.println(" ints contains " + searchNumber3 + ": " +122 Checker.contains(ints, searchNumber3));123 System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));124}output ints contains 3: truepublic static <T> boolean contains(T[] array, T item)
pass 2 of 2109class Checker {110 public static <T> boolean contains(T[] array, T itemd) {111 for (T element : array) {return false;
115 }116 return false;117}System.out.println(" strs contains 'd': " + Checker.contains(strs, "d…
122 Checker.contains(ints, searchNumber));123 System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));124}output strs contains 'd': false
public static void main(String[] args)
17public static void main(String[] args) {18 System.out.println("Basic generic methods:\n");outputBasic generic methods: Basic generic methods:public static <T> void print(T item)
pass 1 of 33public class Basic {4 public static <T> void print(T item42) {5 System.out.println(" Item: " + item42);6 }output Item: 42All 3 passes — pass 1 is the card above pass item1 42 2 Hello 3 3.14 public static <T> void printArray(T[] array)
pass 1 of 28public static <T> void printArray(T[] array) {9 System.out.print(" Array: [");10 for (int i = 0; i < array.length; i++) {output Array: [for (int i = 0; i < array.length; i++)
pass 1 of 89System.out.print(" Array: [");10for (int i0 = 0; i < array.length5; i++) {11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]1);13}output1All 8 passes — pass 1 is the card above pass iarray.lengtharray[i]1 0 5 1 2 1 5 — 3 2 5 — 4 3 5 — 5 4 5 — 6 0 3 a 7 1 3 — 8 2 3 — if (i > 0)
pass 1 of 610for (int i = 0; i < array.length; i++) {11 if (i1 > 0) System.out.print(", ");12 System.out.print(array[i]);output,All 6 passes — pass 1 is the card above pass i1 1 2 2 3 3 4 4 5 1 6 2 System.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]2);13}output2values this step1iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]3);13}output3values this step2iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]4);13}output4values this step3iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]5);13}output5values this step4iSystem.out.println("]");
13 }14 System.out.println("]");15}output]public static <T> void printArray(T[] array)
pass 2 of 28public static <T> void printArray(T[] array) {9 System.out.print(" Array: [");10 for (int i = 0; i < array.length; i++) {output Array: [System.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]b);13}outputbvalues this step1iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]c);13}outputcvalues this step2iSystem.out.println("]");
13 }14 System.out.println("]");15}output]System.out.println(" Identity function:");
35System.out.println("\nIdentity function:");output Identity function: Identity function:public static <T> T identity(T value)
pass 1 of 237class Utils {38 public static <T> T identity(T value42) {39 return value42;40 }public static <T> T identity(T value)
pass 2 of 237class Utils {38 public static <T> T identity(T valueHello) {39 return valueHello;40 }System.out.println(" Number: " + num);
46System.out.println(" Number: " + num42);47System.out.println(" Text: " + textHello);4849System.out.println("\nSwap elements:");5051class ArrayOps {52 public static <T> void swap(T[] array, int i, int j) {53 T temp = array[i];54 array[i] = array[j];55 array[j] = temp;56 }57}5859Integer[] numbers = {1, 2, 3, 4, 5};60System.out.println(" Before: " + Arrays.toString(numbers));61ArrayOps.swap(numbers, 0, 4);output Number: 42 Number: 42 Text: Hello Text: Hello Swap elements: Swap elements: Before: [1, 2, 3, 4, 5] Before: [1, 2, 3, 4, 5]temp ← 1, array[i] ← 5, array[j] ← 1
51class ArrayOps {52 public static <T> void swap(T[] array, int i0, int j4) {53 T temp→ 1 = array[i]1;54 array[i]→ 5 = array[j]5;55 array[j]→ 1 = temp1;56 }System.out.println(" After: " + Arrays.toString(numbers));
61ArrayOps.swap(numbers, 0, 4);62System.out.println(" After: " + Arrays.toString(numbers));6364System.out.println("\nGet first:");output After: [5, 2, 3, 4, 1] After: [5, 2, 3, 4, 1] Get first: Get first:public static <T> T getFirst(T[] array)
pass 1 of 366class Getter {67 public static <T> T getFirst(T[] array) {68 return array.length5 > 0 ? array[0]1 : null;69 }All 3 passes — pass 1 is the card above pass array.lengtharray[0]1 5 1 2 3 a 3 3 a System.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));System.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));output First string: aSystem.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));7879System.out.println("\nCreate pair:");output First string: a Create pair: Create pair:public static <K, V> Pair<K, V> create(K key, V value)
pass 1 of 295class PairFactory {96 public static <K, V> Pair<K, V> create(K keyage, V value30) {97 return new Pair<>(key, value);98 }this.key ← age, this.value ← 30
pass 1 of 285Pair(K keyage, V value30) {86 this.key→ age = keyage;87 this.value→ 30 = value30;88}public static <K, V> Pair<K, V> create(K key, V value)
pass 2 of 295class PairFactory {96 public static <K, V> Pair<K, V> create(K key1, V valuefirst) {97 return new Pair<>(key, value);98 }this.key ← 1, this.value ← first
pass 2 of 285Pair(K key1, V valuefirst) {86 this.key→ 1 = key1;87 this.value→ first = valuefirst;88}System.out.println(" Pair 1: " + p1);
104System.out.println(" Pair 1: " + p1(age, 30));105System.out.println(" Pair 2: " + p2(1, first));106107System.out.println("\nContains check:");108109class Checker {110 public static <T> boolean contains(T[] array, T item) {111 for (T element : array) {112 if (element.equals(item)) {113 return true;114 }115 }116 return false;117 }118}119120int searchNumber = 1;121System.out.println(" ints contains " + searchNumber1 + ": " +122 Checker.contains(ints, searchNumber1));123System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));output Pair 1: (age, 30) Pair 1: (age, 30) Pair 2: (1, first) Pair 2: (1, first) Contains check: Contains check:public static <T> boolean contains(T[] array, T item)
pass 1 of 2109class Checker {110 public static <T> boolean contains(T[] array, T item1) {111 for (T element : array) {for (T element : array)
pass 1 of 4110public static <T> boolean contains(T[] array, T item) {111 for (T element1 : array) {112 if (element.equals(item)) {All 4 passes — pass 1 is the card above pass elementitem1 1 1 2 a — 3 b — 4 c — if (element.equals(item))
111for (T element : array) {112 if (element.equals(item1)) {113 return true;114 }System.out.println(" ints contains " + searchNumber + ": " +
120 int searchNumber = 1;121 System.out.println(" ints contains " + searchNumber1 + ": " +122 Checker.contains(ints, searchNumber1));123 System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));124}output ints contains 1: truepublic static <T> boolean contains(T[] array, T item)
pass 2 of 2109class Checker {110 public static <T> boolean contains(T[] array, T itemd) {111 for (T element : array) {return false;
115 }116 return false;117}System.out.println(" strs contains 'd': " + Checker.contains(strs, "d…
122 Checker.contains(ints, searchNumber));123 System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));124}output strs contains 'd': false
public static void main(String[] args)
17public static void main(String[] args) {18 System.out.println("Basic generic methods:\n");outputBasic generic methods: Basic generic methods:public static <T> void print(T item)
pass 1 of 33public class Basic {4 public static <T> void print(T item42) {5 System.out.println(" Item: " + item42);6 }output Item: 42All 3 passes — pass 1 is the card above pass item1 42 2 Hello 3 3.14 public static <T> void printArray(T[] array)
pass 1 of 28public static <T> void printArray(T[] array) {9 System.out.print(" Array: [");10 for (int i = 0; i < array.length; i++) {output Array: [for (int i = 0; i < array.length; i++)
pass 1 of 89System.out.print(" Array: [");10for (int i0 = 0; i < array.length5; i++) {11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]1);13}output1All 8 passes — pass 1 is the card above pass iarray.lengtharray[i]1 0 5 1 2 1 5 — 3 2 5 — 4 3 5 — 5 4 5 — 6 0 3 a 7 1 3 — 8 2 3 — if (i > 0)
pass 1 of 610for (int i = 0; i < array.length; i++) {11 if (i1 > 0) System.out.print(", ");12 System.out.print(array[i]);output,All 6 passes — pass 1 is the card above pass i1 1 2 2 3 3 4 4 5 1 6 2 System.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]2);13}output2values this step1iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]3);13}output3values this step2iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]4);13}output4values this step3iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]5);13}output5values this step4iSystem.out.println("]");
13 }14 System.out.println("]");15}output]public static <T> void printArray(T[] array)
pass 2 of 28public static <T> void printArray(T[] array) {9 System.out.print(" Array: [");10 for (int i = 0; i < array.length; i++) {output Array: [System.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]b);13}outputbvalues this step1iSystem.out.print(array[i]);
11 if (i > 0) System.out.print(", ");12 System.out.print(array[i]c);13}outputcvalues this step2iSystem.out.println("]");
13 }14 System.out.println("]");15}output]System.out.println(" Identity function:");
35System.out.println("\nIdentity function:");output Identity function: Identity function:public static <T> T identity(T value)
pass 1 of 237class Utils {38 public static <T> T identity(T value42) {39 return value42;40 }public static <T> T identity(T value)
pass 2 of 237class Utils {38 public static <T> T identity(T valueHello) {39 return valueHello;40 }System.out.println(" Number: " + num);
46System.out.println(" Number: " + num42);47System.out.println(" Text: " + textHello);4849System.out.println("\nSwap elements:");5051class ArrayOps {52 public static <T> void swap(T[] array, int i, int j) {53 T temp = array[i];54 array[i] = array[j];55 array[j] = temp;56 }57}5859Integer[] numbers = {1, 2, 3, 4, 5};60System.out.println(" Before: " + Arrays.toString(numbers));61ArrayOps.swap(numbers, 0, 4);output Number: 42 Number: 42 Text: Hello Text: Hello Swap elements: Swap elements: Before: [1, 2, 3, 4, 5] Before: [1, 2, 3, 4, 5]temp ← 1, array[i] ← 5, array[j] ← 1
51class ArrayOps {52 public static <T> void swap(T[] array, int i0, int j4) {53 T temp→ 1 = array[i]1;54 array[i]→ 5 = array[j]5;55 array[j]→ 1 = temp1;56 }System.out.println(" After: " + Arrays.toString(numbers));
61ArrayOps.swap(numbers, 0, 4);62System.out.println(" After: " + Arrays.toString(numbers));6364System.out.println("\nGet first:");output After: [5, 2, 3, 4, 1] After: [5, 2, 3, 4, 1] Get first: Get first:public static <T> T getFirst(T[] array)
pass 1 of 366class Getter {67 public static <T> T getFirst(T[] array) {68 return array.length5 > 0 ? array[0]1 : null;69 }All 3 passes — pass 1 is the card above pass array.lengtharray[0]1 5 1 2 3 a 3 3 a System.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));System.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));output First string: aSystem.out.println(" First string: " + Getter.getFirst(strs));
76System.out.println(" First int: " + Getter.getFirst(ints));77System.out.println(" First string: " + Getter.getFirst(strs));7879System.out.println("\nCreate pair:");output First string: a Create pair: Create pair:public static <K, V> Pair<K, V> create(K key, V value)
pass 1 of 295class PairFactory {96 public static <K, V> Pair<K, V> create(K keyage, V value30) {97 return new Pair<>(key, value);98 }this.key ← age, this.value ← 30
pass 1 of 285Pair(K keyage, V value30) {86 this.key→ age = keyage;87 this.value→ 30 = value30;88}public static <K, V> Pair<K, V> create(K key, V value)
pass 2 of 295class PairFactory {96 public static <K, V> Pair<K, V> create(K key1, V valuefirst) {97 return new Pair<>(key, value);98 }this.key ← 1, this.value ← first
pass 2 of 285Pair(K key1, V valuefirst) {86 this.key→ 1 = key1;87 this.value→ first = valuefirst;88}System.out.println(" Pair 1: " + p1);
104System.out.println(" Pair 1: " + p1(age, 30));105System.out.println(" Pair 2: " + p2(1, first));106107System.out.println("\nContains check:");108109class Checker {110 public static <T> boolean contains(T[] array, T item) {111 for (T element : array) {112 if (element.equals(item)) {113 return true;114 }115 }116 return false;117 }118}119120int searchNumber = 6;121System.out.println(" ints contains " + searchNumber6 + ": " +122 Checker.contains(ints, searchNumber6));123System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));output Pair 1: (age, 30) Pair 1: (age, 30) Pair 2: (1, first) Pair 2: (1, first) Contains check: Contains check:public static <T> boolean contains(T[] array, T item)
pass 1 of 2109class Checker {110 public static <T> boolean contains(T[] array, T item6) {111 for (T element : array) {for (T element : array)
pass 1 of 8110public static <T> boolean contains(T[] array, T item) {111 for (T element1 : array) {112 if (element.equals(item)) {All 8 passes — pass 1 is the card above pass element1 1 2 2 3 3 4 4 5 5 6 a 7 b 8 c return false;
115 }116 return false;117}System.out.println(" ints contains " + searchNumber + ": " +
120 int searchNumber = 6;121 System.out.println(" ints contains " + searchNumber6 + ": " +122 Checker.contains(ints, searchNumber6));123 System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));124}output ints contains 6: falsepublic static <T> boolean contains(T[] array, T item)
pass 2 of 2109class Checker {110 public static <T> boolean contains(T[] array, T itemd) {111 for (T element : array) {return false;
115 }116 return false;117}System.out.println(" strs contains 'd': " + Checker.contains(strs, "d…
122 Checker.contains(ints, searchNumber));123 System.out.println(" strs contains 'd': " + Checker.contains(strs, "d"));124}output strs contains 'd': false
<T> T method(T arg) - T is scoped to this method only.
Bounded generic methods
Restrict type parameter to certain types.
import java.util.*;
public class Bounds {
public static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
public static <T extends Comparable<T>> T min(T a, T b) {
return a.compareTo(b) < 0 ? a : b;
}
public static void main(String[] args) {
System.out.println("Bounded generic methods:\n");
System.out.println(" max(5, 10): " + max(5, 10));
System.out.println(" max('a', 'z'): " + max('a', 'z'));
System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));
// <T extends Type> constrains T to be Type or subclass
// Allows calling Type's methods on T
// Common with Comparable, Number, Serializable
// Can combine multiple bounds with &
System.out.println("\nSum numbers:");
class NumberOps {
public static <T extends Number> double sum(T[] numbers) {
double total = 0;
for (T num : numbers) {
total += num.doubleValue();
}
return total;
}
public static <T extends Number> double average(T[] numbers) {
if (numbers.length == 0) {
return 0;
}
return sum(numbers) / numbers.length;
}
}
Integer[] ints = {1, 2, 3, 4, 5};
Double[] doubles = {1.5, 2.5, 3.5};
System.out.println(" Sum ints: " + NumberOps.sum(ints));
System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
System.out.println(" Average: " + NumberOps.average(ints));
System.out.println("\nFind maximum:");
class Finder {
public static <T extends Comparable<T>> T findMax(T[] array) {
if (array.length == 0) {
return null;
}
T max = array[0];
for (T item : array) {
if (item.compareTo(max) > 0) {
max = item;
}
}
return max;
}
}
System.out.println(" Max int: " + Finder.findMax(ints));
String[] words = {"apple", "zebra", "banana", "cherry"};
System.out.println(" Max string: " + Finder.findMax(words));
System.out.println("\nSort array:");
class Sorter {
public static <T extends Comparable<T>> void sort(T[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i].compareTo(array[j]) > 0) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
}
Integer[] nums = {5, 2, 8, 1, 9};
System.out.println(" Before: " + Arrays.toString(nums));
Sorter.sort(nums);
System.out.println(" After: " + Arrays.toString(nums));
System.out.println("\nClamp value:");
class RangeOps {
public static <T extends Comparable<T>> T clamp(
T value, T min, T max) {
if (value.compareTo(min) < 0) {
return min;
}
if (value.compareTo(max) > 0) {
return max;
}
return value;
}
}
System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));
System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));
System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));
System.out.println("\nCount greater:");
class Counter {
public static <T extends Comparable<T>> int countGreater(
T[] array, T threshold) {
int count = 0;
for (T item : array) {
if (item.compareTo(threshold) > 0) {
count++;
}
}
return count;
}
}
int countThreshold = 3;
System.out.println(" Count > " + countThreshold + ": " +
Counter.countGreater(ints, countThreshold));
System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));
}
}
import java.util.*;
public class Bounds {
public static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
public static <T extends Comparable<T>> T min(T a, T b) {
return a.compareTo(b) < 0 ? a : b;
}
public static void main(String[] args) {
System.out.println("Bounded generic methods:\n");
System.out.println(" max(5, 10): " + max(5, 10));
System.out.println(" max('a', 'z'): " + max('a', 'z'));
System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));
// <T extends Type> constrains T to be Type or subclass
// Allows calling Type's methods on T
// Common with Comparable, Number, Serializable
// Can combine multiple bounds with &
System.out.println("\nSum numbers:");
class NumberOps {
public static <T extends Number> double sum(T[] numbers) {
double total = 0;
for (T num : numbers) {
total += num.doubleValue();
}
return total;
}
public static <T extends Number> double average(T[] numbers) {
if (numbers.length == 0) {
return 0;
}
return sum(numbers) / numbers.length;
}
}
Integer[] ints = {1, 2, 3, 4, 5};
Double[] doubles = {1.5, 2.5, 3.5};
System.out.println(" Sum ints: " + NumberOps.sum(ints));
System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
System.out.println(" Average: " + NumberOps.average(ints));
System.out.println("\nFind maximum:");
class Finder {
public static <T extends Comparable<T>> T findMax(T[] array) {
if (array.length == 0) {
return null;
}
T max = array[0];
for (T item : array) {
if (item.compareTo(max) > 0) {
max = item;
}
}
return max;
}
}
System.out.println(" Max int: " + Finder.findMax(ints));
String[] words = {"apple", "zebra", "banana", "cherry"};
System.out.println(" Max string: " + Finder.findMax(words));
System.out.println("\nSort array:");
class Sorter {
public static <T extends Comparable<T>> void sort(T[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i].compareTo(array[j]) > 0) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
}
Integer[] nums = {5, 2, 8, 1, 9};
System.out.println(" Before: " + Arrays.toString(nums));
Sorter.sort(nums);
System.out.println(" After: " + Arrays.toString(nums));
System.out.println("\nClamp value:");
class RangeOps {
public static <T extends Comparable<T>> T clamp(
T value, T min, T max) {
if (value.compareTo(min) < 0) {
return min;
}
if (value.compareTo(max) > 0) {
return max;
}
return value;
}
}
System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));
System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));
System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));
System.out.println("\nCount greater:");
class Counter {
public static <T extends Comparable<T>> int countGreater(
T[] array, T threshold) {
int count = 0;
for (T item : array) {
if (item.compareTo(threshold) > 0) {
count++;
}
}
return count;
}
}
int countThreshold = 5;
System.out.println(" Count > " + countThreshold + ": " +
Counter.countGreater(ints, countThreshold));
System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));
}
}
import java.util.*;
public class Bounds {
public static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
public static <T extends Comparable<T>> T min(T a, T b) {
return a.compareTo(b) < 0 ? a : b;
}
public static void main(String[] args) {
System.out.println("Bounded generic methods:\n");
System.out.println(" max(5, 10): " + max(5, 10));
System.out.println(" max('a', 'z'): " + max('a', 'z'));
System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));
// <T extends Type> constrains T to be Type or subclass
// Allows calling Type's methods on T
// Common with Comparable, Number, Serializable
// Can combine multiple bounds with &
System.out.println("\nSum numbers:");
class NumberOps {
public static <T extends Number> double sum(T[] numbers) {
double total = 0;
for (T num : numbers) {
total += num.doubleValue();
}
return total;
}
public static <T extends Number> double average(T[] numbers) {
if (numbers.length == 0) {
return 0;
}
return sum(numbers) / numbers.length;
}
}
Integer[] ints = {1, 2, 3, 4, 5};
Double[] doubles = {1.5, 2.5, 3.5};
System.out.println(" Sum ints: " + NumberOps.sum(ints));
System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
System.out.println(" Average: " + NumberOps.average(ints));
System.out.println("\nFind maximum:");
class Finder {
public static <T extends Comparable<T>> T findMax(T[] array) {
if (array.length == 0) {
return null;
}
T max = array[0];
for (T item : array) {
if (item.compareTo(max) > 0) {
max = item;
}
}
return max;
}
}
System.out.println(" Max int: " + Finder.findMax(ints));
String[] words = {"apple", "zebra", "banana", "cherry"};
System.out.println(" Max string: " + Finder.findMax(words));
System.out.println("\nSort array:");
class Sorter {
public static <T extends Comparable<T>> void sort(T[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i].compareTo(array[j]) > 0) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
}
Integer[] nums = {5, 2, 8, 1, 9};
System.out.println(" Before: " + Arrays.toString(nums));
Sorter.sort(nums);
System.out.println(" After: " + Arrays.toString(nums));
System.out.println("\nClamp value:");
class RangeOps {
public static <T extends Comparable<T>> T clamp(
T value, T min, T max) {
if (value.compareTo(min) < 0) {
return min;
}
if (value.compareTo(max) > 0) {
return max;
}
return value;
}
}
System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));
System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));
System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));
System.out.println("\nCount greater:");
class Counter {
public static <T extends Comparable<T>> int countGreater(
T[] array, T threshold) {
int count = 0;
for (T item : array) {
if (item.compareTo(threshold) > 0) {
count++;
}
}
return count;
}
}
int countThreshold = 8;
System.out.println(" Count > " + countThreshold + ": " +
Counter.countGreater(ints, countThreshold));
System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));
}
}
public static void main(String[] args)
12public static void main(String[] args) {13 System.out.println("Bounded generic methods:\n");14 15 System.out.println(" max(5, 10): " + max(5, 10));16 System.out.println(" max('a', 'z'): " + max('a', 'z'));outputBounded generic methods: Bounded generic methods:public static <T extends Comparable<T>> T max(T a, T b)
pass 1 of 43public class Bounds {4 public static <T extends Comparable<T>> T max(T a5, T b10) {5 return a.compareTo(b10) > 0 ? a5 : b;6 }All 4 passes — pass 1 is the card above pass ab1 5 10 2 5 10 3 a z 4 a z System.out.println(" max(5, 10): " + max(5, 10));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));output max(5, 10): 10System.out.println(" max(5, 10): " + max(5, 10));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max(5, 10): 10System.out.println(" max('a', 'z'): " + max('a', 'z'));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max('a', 'z'): zSystem.out.println(" max('a', 'z'): " + max('a', 'z'));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max('a', 'z'): zpublic static <T extends Comparable<T>> T min(T a, T b)
pass 1 of 28public static <T extends Comparable<T>> T min(T aapple, T bbanana) {9 return a.compareTo(bbanana) < 0 ? aapple : b;10}System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "ba…
16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output min("apple", "banana"): applepublic static <T extends Comparable<T>> T min(T a, T b)
pass 2 of 28public static <T extends Comparable<T>> T min(T aapple, T bbanana) {9 return a.compareTo(bbanana) < 0 ? aapple : b;10}System.out.println(" Sum ints: " + NumberOps.sum(ints));
16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));1819// <T extends Type> constrains T to be Type or subclass20// Allows calling Type's methods on T21// Common with Comparable, Number, Serializable22// Can combine multiple bounds with &2324System.out.println("\nSum numbers:");2526class NumberOps {27 public static <T extends Number> double sum(T[] numbers) {28 double total = 0;29 for (T num : numbers) {30 total += num.doubleValue();31 }32 return total;33 }34 35 public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length;40 }41}4243Integer[] ints = {1, 2, 3, 4, 5};44Double[] doubles = {1.5, 2.5, 3.5};4546System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));output min("apple", "banana"): apple Sum numbers: Sum numbers:total ← 0.0
pass 1 of 626class NumberOps {27 public static <T extends Number> double sum(T[] numbers) {28 double total→ 0.0 = 0;29 for (T num : numbers) {All 6 passes — pass 1 is the card above pass total1 0.0 2 0.0 3 0.0 4 0.0 5 0.0 6 0.0 total ← 1.0
pass 1 of 2628double total = 0;29for (T num1 : numbers) {30 total→ 1.0 += num.doubleValue();31}26 passes — pass 1 is the card above pass numtotal1 1 0.0 → 1.0 2 2 1.0 → 3.0 3 3 3.0 → 6.0 4 4 6.0 → 10.0 5 5 10.0 → 15.0 6 1 0.0 → 1.0 7 2 1.0 → 3.0 8 3 3.0 → 6.0 9 4 6.0 → 10.0 ⋯ 15 more passes ⋯ 25 4 6.0 → 10.0 26 5 10.0 → 15.0 return total;
31 }32 return total15.0;33}System.out.println(" Sum ints: " + NumberOps.sum(ints));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));output Sum ints: 15.0return total;
31 }32 return total15.0;33}System.out.println(" Sum ints: " + NumberOps.sum(ints));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum ints: 15.0return total;
31 }32 return total7.5;33}System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum doubles: 7.5return total;
31 }32 return total7.5;33}System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum doubles: 7.5public static <T extends Number> double average(T[] numbers)
pass 1 of 235public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length5;40}return total;
31 }32 return total15.0;33}System.out.println(" Average: " + NumberOps.average(ints));
47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Average: 3.0public static <T extends Number> double average(T[] numbers)
pass 2 of 235public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length5;40}return total;
31 }32 return total15.0;33}System.out.println(" Average: " + NumberOps.average(ints));
47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));4950System.out.println("\nFind maximum:");output Average: 3.0 Find maximum: Find maximum:max ← 1
pass 1 of 352class Finder {53 public static <T extends Comparable<T>> T findMax(T[] array) {54 if (array.length == 0) {55 return null;56 }57 58 T max→ 1 = array[0]1;59 for (T item : array) {All 3 passes — pass 1 is the card above pass array[0]max1 1 1 2 apple apple 3 apple apple for (T item : array)
pass 1 of 1358T max = array[0];59for (T item1 : array) {60 if (item.compareTo(max) > 0) {13 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 6 apple 7 zebra 8 banana 9 cherry ⋯ 2 more passes ⋯ 12 banana 13 cherry max ← 2
pass 1 of 659for (T item : array) {60 if (item.compareTo(max1) > 0) {61 max→ 2 = item2;62 }All 6 passes — pass 1 is the card above pass itemmax1 2 1 → 2 2 3 2 → 3 3 4 3 → 4 4 5 4 → 5 5 zebra apple → zebra 6 zebra apple → zebra return max;
63 }64 return max5;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));return max;
63 }64 return maxzebra;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));output Max string: zebrareturn max;
63 }64 return maxzebra;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));7273System.out.println("\nSort array:");7475class Sorter {76 public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i = 0; i < array.length - 1; i++) {78 for (int j = i + 1; j < array.length; j++) {79 if (array[i].compareTo(array[j]) > 0) {80 T temp = array[i];81 array[i] = array[j];82 array[j] = temp;83 }84 }85 }86 }87}8889Integer[] nums = {5, 2, 8, 1, 9};90System.out.println(" Before: " + Arrays.toString(nums));91Sorter.sort(nums);output Max string: zebra Sort array: Sort array: Before: [5, 2, 8, 1, 9] Before: [5, 2, 8, 1, 9]public static <T extends Comparable<T>> void sort(T[] array)
75class Sorter {76 public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i = 0; i < array.length - 1; i++) {for (int i = 0; i < array.length - 1; i++)
pass 1 of 476public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i0 = 0; i < array.length5 - 1; i++) {78 for (int j = i + 1; j < array.length; j++) {All 4 passes — pass 1 is the card above pass i1 0 2 1 3 2 4 3 for (int j = i + 1; j < array.length; j++)
pass 1 of 1077for (int i = 0; i < array.length - 1; i++) {78 for (int j1 = i0 + 1; j < array.length5; j++) {79 if (array[i].compareTo(array[j]) > 0) {All 10 passes — pass 1 is the card above pass ji1 1 0 2 2 0 3 3 0 4 4 0 5 2 1 6 3 1 7 4 1 8 3 2 9 4 2 10 4 3 temp ← 5, array[i] ← 2, array[j] ← 5
pass 1 of 478for (int j = i + 1; j < array.length; j++) {79 if (array[i]5.compareTo(array[j]2) > 0) {80 T temp→ 5 = array[i]5;81 array[i]→ 2 = array[j]2;82 array[j]→ 5 = temp5;83 }All 4 passes — pass 1 is the card above pass ijtemparray[i]array[j]1 0 1 5 5 → 2 2 → 5 2 0 3 2 2 → 1 1 → 2 3 1 3 5 5 → 2 2 → 5 4 2 3 8 8 → 5 5 → 8 System.out.println(" After: " + Arrays.toString(nums));
91Sorter.sort(nums);92System.out.println(" After: " + Arrays.toString(nums));9394System.out.println("\nClamp value:");output After: [1, 2, 5, 8, 9] After: [1, 2, 5, 8, 9] Clamp value: Clamp value:public static <T extends Comparable<T>> T clamp( T…
pass 1 of 596class RangeOps {97 public static <T extends Comparable<T>> T clamp(98 T value5, T min0, T max10) {99 if (value.compareTo(min) < 0) {100 return min;101 }102 if (value.compareTo(max) > 0) {103 return max;104 }105 return value5;106 }All 5 passes — pass 1 is the card above pass value1 5 2 15 3 15 4 -5 5 -5 System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));if (value.compareTo(max) > 0)
pass 1 of 2101}102if (value.compareTo(max10) > 0) {103 return max10;104}System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(15, 0, 10): 10if (value.compareTo(max) > 0)
pass 2 of 2101}102if (value.compareTo(max10) > 0) {103 return max10;104}System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(15, 0, 10): 10if (value.compareTo(min) < 0)
pass 1 of 298 T value, T min, T max) {99if (value.compareTo(min0) < 0) {100 return min0;101}System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10))…
110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(-5, 0, 10): 0if (value.compareTo(min) < 0)
pass 2 of 298 T value, T min, T max) {99if (value.compareTo(min0) < 0) {100 return min0;101}System.out.println(" Count > " + countThreshold + ": " +
110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));112113System.out.println("\nCount greater:");114115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T threshold) {118 int count = 0;119 for (T item : array) {120 if (item.compareTo(threshold) > 0) {121 count++;122 }123 }124 return count;125 }126}127128int countThreshold = 3; //@countThreshold=3, 5, 8129System.out.println(" Count > " + countThreshold3 + ": " +130 Counter.countGreater(ints, countThreshold3));131System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));output clamp(-5, 0, 10): 0 Count greater: Count greater:count ← 0
pass 1 of 2115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T threshold3) {118 int count→ 0 = 0;119 for (T item : array) {for (T item : array)
pass 1 of 9118int count = 0;119for (T item1 : array) {120 if (item.compareTo(threshold) > 0) {All 9 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 6 apple 7 zebra 8 banana 9 cherry count ← 1
pass 1 of 4119for (T item : array) {120 if (item.compareTo(threshold3) > 0) {121 count→ 1++;122 }All 4 passes — pass 1 is the card above pass thresholdcount1 3 0 → 1 2 3 1 → 2 3 c 0 → 1 4 c 1 → 2 return count;
123 }124 return count2;125}System.out.println(" Count > " + countThreshold + ": " +
128 int countThreshold = 3; //@countThreshold=3, 5, 8129 System.out.println(" Count > " + countThreshold3 + ": " +130 Counter.countGreater(ints, countThreshold3));131 System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));132}output Count > 3: 2count ← 0
pass 2 of 2115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T thresholdc) {118 int count→ 0 = 0;119 for (T item : array) {return count;
123 }124 return count2;125}System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"…
130 Counter.countGreater(ints, countThreshold));131 System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));132}output Count > 'c': 2
public static void main(String[] args)
12public static void main(String[] args) {13 System.out.println("Bounded generic methods:\n");14 15 System.out.println(" max(5, 10): " + max(5, 10));16 System.out.println(" max('a', 'z'): " + max('a', 'z'));outputBounded generic methods: Bounded generic methods:public static <T extends Comparable<T>> T max(T a, T b)
pass 1 of 43public class Bounds {4 public static <T extends Comparable<T>> T max(T a5, T b10) {5 return a.compareTo(b10) > 0 ? a5 : b;6 }All 4 passes — pass 1 is the card above pass ab1 5 10 2 5 10 3 a z 4 a z System.out.println(" max(5, 10): " + max(5, 10));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));output max(5, 10): 10System.out.println(" max(5, 10): " + max(5, 10));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max(5, 10): 10System.out.println(" max('a', 'z'): " + max('a', 'z'));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max('a', 'z'): zSystem.out.println(" max('a', 'z'): " + max('a', 'z'));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max('a', 'z'): zpublic static <T extends Comparable<T>> T min(T a, T b)
pass 1 of 28public static <T extends Comparable<T>> T min(T aapple, T bbanana) {9 return a.compareTo(bbanana) < 0 ? aapple : b;10}System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "ba…
16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output min("apple", "banana"): applepublic static <T extends Comparable<T>> T min(T a, T b)
pass 2 of 28public static <T extends Comparable<T>> T min(T aapple, T bbanana) {9 return a.compareTo(bbanana) < 0 ? aapple : b;10}System.out.println(" Sum ints: " + NumberOps.sum(ints));
16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));1819// <T extends Type> constrains T to be Type or subclass20// Allows calling Type's methods on T21// Common with Comparable, Number, Serializable22// Can combine multiple bounds with &2324System.out.println("\nSum numbers:");2526class NumberOps {27 public static <T extends Number> double sum(T[] numbers) {28 double total = 0;29 for (T num : numbers) {30 total += num.doubleValue();31 }32 return total;33 }34 35 public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length;40 }41}4243Integer[] ints = {1, 2, 3, 4, 5};44Double[] doubles = {1.5, 2.5, 3.5};4546System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));output min("apple", "banana"): apple Sum numbers: Sum numbers:total ← 0.0
pass 1 of 626class NumberOps {27 public static <T extends Number> double sum(T[] numbers) {28 double total→ 0.0 = 0;29 for (T num : numbers) {All 6 passes — pass 1 is the card above pass total1 0.0 2 0.0 3 0.0 4 0.0 5 0.0 6 0.0 total ← 1.0
pass 1 of 2628double total = 0;29for (T num1 : numbers) {30 total→ 1.0 += num.doubleValue();31}26 passes — pass 1 is the card above pass numtotal1 1 0.0 → 1.0 2 2 1.0 → 3.0 3 3 3.0 → 6.0 4 4 6.0 → 10.0 5 5 10.0 → 15.0 6 1 0.0 → 1.0 7 2 1.0 → 3.0 8 3 3.0 → 6.0 9 4 6.0 → 10.0 ⋯ 15 more passes ⋯ 25 4 6.0 → 10.0 26 5 10.0 → 15.0 return total;
31 }32 return total15.0;33}System.out.println(" Sum ints: " + NumberOps.sum(ints));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));output Sum ints: 15.0return total;
31 }32 return total15.0;33}System.out.println(" Sum ints: " + NumberOps.sum(ints));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum ints: 15.0return total;
31 }32 return total7.5;33}System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum doubles: 7.5return total;
31 }32 return total7.5;33}System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum doubles: 7.5public static <T extends Number> double average(T[] numbers)
pass 1 of 235public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length5;40}return total;
31 }32 return total15.0;33}System.out.println(" Average: " + NumberOps.average(ints));
47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Average: 3.0public static <T extends Number> double average(T[] numbers)
pass 2 of 235public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length5;40}return total;
31 }32 return total15.0;33}System.out.println(" Average: " + NumberOps.average(ints));
47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));4950System.out.println("\nFind maximum:");output Average: 3.0 Find maximum: Find maximum:max ← 1
pass 1 of 352class Finder {53 public static <T extends Comparable<T>> T findMax(T[] array) {54 if (array.length == 0) {55 return null;56 }57 58 T max→ 1 = array[0]1;59 for (T item : array) {All 3 passes — pass 1 is the card above pass array[0]max1 1 1 2 apple apple 3 apple apple for (T item : array)
pass 1 of 1358T max = array[0];59for (T item1 : array) {60 if (item.compareTo(max) > 0) {13 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 6 apple 7 zebra 8 banana 9 cherry ⋯ 2 more passes ⋯ 12 banana 13 cherry max ← 2
pass 1 of 659for (T item : array) {60 if (item.compareTo(max1) > 0) {61 max→ 2 = item2;62 }All 6 passes — pass 1 is the card above pass itemmax1 2 1 → 2 2 3 2 → 3 3 4 3 → 4 4 5 4 → 5 5 zebra apple → zebra 6 zebra apple → zebra return max;
63 }64 return max5;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));return max;
63 }64 return maxzebra;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));output Max string: zebrareturn max;
63 }64 return maxzebra;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));7273System.out.println("\nSort array:");7475class Sorter {76 public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i = 0; i < array.length - 1; i++) {78 for (int j = i + 1; j < array.length; j++) {79 if (array[i].compareTo(array[j]) > 0) {80 T temp = array[i];81 array[i] = array[j];82 array[j] = temp;83 }84 }85 }86 }87}8889Integer[] nums = {5, 2, 8, 1, 9};90System.out.println(" Before: " + Arrays.toString(nums));91Sorter.sort(nums);output Max string: zebra Sort array: Sort array: Before: [5, 2, 8, 1, 9] Before: [5, 2, 8, 1, 9]public static <T extends Comparable<T>> void sort(T[] array)
75class Sorter {76 public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i = 0; i < array.length - 1; i++) {for (int i = 0; i < array.length - 1; i++)
pass 1 of 476public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i0 = 0; i < array.length5 - 1; i++) {78 for (int j = i + 1; j < array.length; j++) {All 4 passes — pass 1 is the card above pass i1 0 2 1 3 2 4 3 for (int j = i + 1; j < array.length; j++)
pass 1 of 1077for (int i = 0; i < array.length - 1; i++) {78 for (int j1 = i0 + 1; j < array.length5; j++) {79 if (array[i].compareTo(array[j]) > 0) {All 10 passes — pass 1 is the card above pass ji1 1 0 2 2 0 3 3 0 4 4 0 5 2 1 6 3 1 7 4 1 8 3 2 9 4 2 10 4 3 temp ← 5, array[i] ← 2, array[j] ← 5
pass 1 of 478for (int j = i + 1; j < array.length; j++) {79 if (array[i]5.compareTo(array[j]2) > 0) {80 T temp→ 5 = array[i]5;81 array[i]→ 2 = array[j]2;82 array[j]→ 5 = temp5;83 }All 4 passes — pass 1 is the card above pass ijtemparray[i]array[j]1 0 1 5 5 → 2 2 → 5 2 0 3 2 2 → 1 1 → 2 3 1 3 5 5 → 2 2 → 5 4 2 3 8 8 → 5 5 → 8 System.out.println(" After: " + Arrays.toString(nums));
91Sorter.sort(nums);92System.out.println(" After: " + Arrays.toString(nums));9394System.out.println("\nClamp value:");output After: [1, 2, 5, 8, 9] After: [1, 2, 5, 8, 9] Clamp value: Clamp value:public static <T extends Comparable<T>> T clamp( T…
pass 1 of 596class RangeOps {97 public static <T extends Comparable<T>> T clamp(98 T value5, T min0, T max10) {99 if (value.compareTo(min) < 0) {100 return min;101 }102 if (value.compareTo(max) > 0) {103 return max;104 }105 return value5;106 }All 5 passes — pass 1 is the card above pass value1 5 2 15 3 15 4 -5 5 -5 System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));if (value.compareTo(max) > 0)
pass 1 of 2101}102if (value.compareTo(max10) > 0) {103 return max10;104}System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(15, 0, 10): 10if (value.compareTo(max) > 0)
pass 2 of 2101}102if (value.compareTo(max10) > 0) {103 return max10;104}System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(15, 0, 10): 10if (value.compareTo(min) < 0)
pass 1 of 298 T value, T min, T max) {99if (value.compareTo(min0) < 0) {100 return min0;101}System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10))…
110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(-5, 0, 10): 0if (value.compareTo(min) < 0)
pass 2 of 298 T value, T min, T max) {99if (value.compareTo(min0) < 0) {100 return min0;101}System.out.println(" Count > " + countThreshold + ": " +
110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));112113System.out.println("\nCount greater:");114115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T threshold) {118 int count = 0;119 for (T item : array) {120 if (item.compareTo(threshold) > 0) {121 count++;122 }123 }124 return count;125 }126}127128int countThreshold = 5;129System.out.println(" Count > " + countThreshold5 + ": " +130 Counter.countGreater(ints, countThreshold5));131System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));output clamp(-5, 0, 10): 0 Count greater: Count greater:count ← 0
pass 1 of 2115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T threshold5) {118 int count→ 0 = 0;119 for (T item : array) {for (T item : array)
pass 1 of 9118int count = 0;119for (T item1 : array) {120 if (item.compareTo(threshold) > 0) {All 9 passes — pass 1 is the card above pass itemthresholdcount1 1 — — 2 2 — — 3 3 — — 4 4 — — 5 5 — — 6 apple — — 7 zebra c 0 → 1 8 banana — — 9 cherry c 1 → 2 return count;
123 }124 return count0;125}System.out.println(" Count > " + countThreshold + ": " +
128 int countThreshold = 5;129 System.out.println(" Count > " + countThreshold5 + ": " +130 Counter.countGreater(ints, countThreshold5));131 System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));132}output Count > 5: 0count ← 0
pass 2 of 2115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T thresholdc) {118 int count→ 0 = 0;119 for (T item : array) {count ← 1
pass 1 of 2119for (T item : array) {120 if (item.compareTo(thresholdc) > 0) {121 count→ 1++;122 }count ← 2
pass 2 of 2119for (T item : array) {120 if (item.compareTo(thresholdc) > 0) {121 count→ 2++;122 }return count;
123 }124 return count2;125}System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"…
130 Counter.countGreater(ints, countThreshold));131 System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));132}output Count > 'c': 2
public static void main(String[] args)
12public static void main(String[] args) {13 System.out.println("Bounded generic methods:\n");14 15 System.out.println(" max(5, 10): " + max(5, 10));16 System.out.println(" max('a', 'z'): " + max('a', 'z'));outputBounded generic methods: Bounded generic methods:public static <T extends Comparable<T>> T max(T a, T b)
pass 1 of 43public class Bounds {4 public static <T extends Comparable<T>> T max(T a5, T b10) {5 return a.compareTo(b10) > 0 ? a5 : b;6 }All 4 passes — pass 1 is the card above pass ab1 5 10 2 5 10 3 a z 4 a z System.out.println(" max(5, 10): " + max(5, 10));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));output max(5, 10): 10System.out.println(" max(5, 10): " + max(5, 10));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max(5, 10): 10System.out.println(" max('a', 'z'): " + max('a', 'z'));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max('a', 'z'): zSystem.out.println(" max('a', 'z'): " + max('a', 'z'));
15System.out.println(" max(5, 10): " + max(5, 10));16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output max('a', 'z'): zpublic static <T extends Comparable<T>> T min(T a, T b)
pass 1 of 28public static <T extends Comparable<T>> T min(T aapple, T bbanana) {9 return a.compareTo(bbanana) < 0 ? aapple : b;10}System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "ba…
16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));output min("apple", "banana"): applepublic static <T extends Comparable<T>> T min(T a, T b)
pass 2 of 28public static <T extends Comparable<T>> T min(T aapple, T bbanana) {9 return a.compareTo(bbanana) < 0 ? aapple : b;10}System.out.println(" Sum ints: " + NumberOps.sum(ints));
16System.out.println(" max('a', 'z'): " + max('a', 'z'));17System.out.println(" min(\"apple\", \"banana\"): " + min("apple", "banana"));1819// <T extends Type> constrains T to be Type or subclass20// Allows calling Type's methods on T21// Common with Comparable, Number, Serializable22// Can combine multiple bounds with &2324System.out.println("\nSum numbers:");2526class NumberOps {27 public static <T extends Number> double sum(T[] numbers) {28 double total = 0;29 for (T num : numbers) {30 total += num.doubleValue();31 }32 return total;33 }34 35 public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length;40 }41}4243Integer[] ints = {1, 2, 3, 4, 5};44Double[] doubles = {1.5, 2.5, 3.5};4546System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));output min("apple", "banana"): apple Sum numbers: Sum numbers:total ← 0.0
pass 1 of 626class NumberOps {27 public static <T extends Number> double sum(T[] numbers) {28 double total→ 0.0 = 0;29 for (T num : numbers) {All 6 passes — pass 1 is the card above pass total1 0.0 2 0.0 3 0.0 4 0.0 5 0.0 6 0.0 total ← 1.0
pass 1 of 2628double total = 0;29for (T num1 : numbers) {30 total→ 1.0 += num.doubleValue();31}26 passes — pass 1 is the card above pass numtotal1 1 0.0 → 1.0 2 2 1.0 → 3.0 3 3 3.0 → 6.0 4 4 6.0 → 10.0 5 5 10.0 → 15.0 6 1 0.0 → 1.0 7 2 1.0 → 3.0 8 3 3.0 → 6.0 9 4 6.0 → 10.0 ⋯ 15 more passes ⋯ 25 4 6.0 → 10.0 26 5 10.0 → 15.0 return total;
31 }32 return total15.0;33}System.out.println(" Sum ints: " + NumberOps.sum(ints));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));output Sum ints: 15.0return total;
31 }32 return total15.0;33}System.out.println(" Sum ints: " + NumberOps.sum(ints));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum ints: 15.0return total;
31 }32 return total7.5;33}System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum doubles: 7.5return total;
31 }32 return total7.5;33}System.out.println(" Sum doubles: " + NumberOps.sum(doubles));
46System.out.println(" Sum ints: " + NumberOps.sum(ints));47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Sum doubles: 7.5public static <T extends Number> double average(T[] numbers)
pass 1 of 235public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length5;40}return total;
31 }32 return total15.0;33}System.out.println(" Average: " + NumberOps.average(ints));
47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));output Average: 3.0public static <T extends Number> double average(T[] numbers)
pass 2 of 235public static <T extends Number> double average(T[] numbers) {36 if (numbers.length == 0) {37 return 0;38 }39 return sum(numbers) / numbers.length5;40}return total;
31 }32 return total15.0;33}System.out.println(" Average: " + NumberOps.average(ints));
47System.out.println(" Sum doubles: " + NumberOps.sum(doubles));48System.out.println(" Average: " + NumberOps.average(ints));4950System.out.println("\nFind maximum:");output Average: 3.0 Find maximum: Find maximum:max ← 1
pass 1 of 352class Finder {53 public static <T extends Comparable<T>> T findMax(T[] array) {54 if (array.length == 0) {55 return null;56 }57 58 T max→ 1 = array[0]1;59 for (T item : array) {All 3 passes — pass 1 is the card above pass array[0]max1 1 1 2 apple apple 3 apple apple for (T item : array)
pass 1 of 1358T max = array[0];59for (T item1 : array) {60 if (item.compareTo(max) > 0) {13 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 6 apple 7 zebra 8 banana 9 cherry ⋯ 2 more passes ⋯ 12 banana 13 cherry max ← 2
pass 1 of 659for (T item : array) {60 if (item.compareTo(max1) > 0) {61 max→ 2 = item2;62 }All 6 passes — pass 1 is the card above pass itemmax1 2 1 → 2 2 3 2 → 3 3 4 3 → 4 4 5 4 → 5 5 zebra apple → zebra 6 zebra apple → zebra return max;
63 }64 return max5;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));return max;
63 }64 return maxzebra;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));output Max string: zebrareturn max;
63 }64 return maxzebra;65}System.out.println(" Max string: " + Finder.findMax(words));
70String[] words = {"apple", "zebra", "banana", "cherry"};71System.out.println(" Max string: " + Finder.findMax(words));7273System.out.println("\nSort array:");7475class Sorter {76 public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i = 0; i < array.length - 1; i++) {78 for (int j = i + 1; j < array.length; j++) {79 if (array[i].compareTo(array[j]) > 0) {80 T temp = array[i];81 array[i] = array[j];82 array[j] = temp;83 }84 }85 }86 }87}8889Integer[] nums = {5, 2, 8, 1, 9};90System.out.println(" Before: " + Arrays.toString(nums));91Sorter.sort(nums);output Max string: zebra Sort array: Sort array: Before: [5, 2, 8, 1, 9] Before: [5, 2, 8, 1, 9]public static <T extends Comparable<T>> void sort(T[] array)
75class Sorter {76 public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i = 0; i < array.length - 1; i++) {for (int i = 0; i < array.length - 1; i++)
pass 1 of 476public static <T extends Comparable<T>> void sort(T[] array) {77 for (int i0 = 0; i < array.length5 - 1; i++) {78 for (int j = i + 1; j < array.length; j++) {All 4 passes — pass 1 is the card above pass i1 0 2 1 3 2 4 3 for (int j = i + 1; j < array.length; j++)
pass 1 of 1077for (int i = 0; i < array.length - 1; i++) {78 for (int j1 = i0 + 1; j < array.length5; j++) {79 if (array[i].compareTo(array[j]) > 0) {All 10 passes — pass 1 is the card above pass ji1 1 0 2 2 0 3 3 0 4 4 0 5 2 1 6 3 1 7 4 1 8 3 2 9 4 2 10 4 3 temp ← 5, array[i] ← 2, array[j] ← 5
pass 1 of 478for (int j = i + 1; j < array.length; j++) {79 if (array[i]5.compareTo(array[j]2) > 0) {80 T temp→ 5 = array[i]5;81 array[i]→ 2 = array[j]2;82 array[j]→ 5 = temp5;83 }All 4 passes — pass 1 is the card above pass ijtemparray[i]array[j]1 0 1 5 5 → 2 2 → 5 2 0 3 2 2 → 1 1 → 2 3 1 3 5 5 → 2 2 → 5 4 2 3 8 8 → 5 5 → 8 System.out.println(" After: " + Arrays.toString(nums));
91Sorter.sort(nums);92System.out.println(" After: " + Arrays.toString(nums));9394System.out.println("\nClamp value:");output After: [1, 2, 5, 8, 9] After: [1, 2, 5, 8, 9] Clamp value: Clamp value:public static <T extends Comparable<T>> T clamp( T…
pass 1 of 596class RangeOps {97 public static <T extends Comparable<T>> T clamp(98 T value5, T min0, T max10) {99 if (value.compareTo(min) < 0) {100 return min;101 }102 if (value.compareTo(max) > 0) {103 return max;104 }105 return value5;106 }All 5 passes — pass 1 is the card above pass value1 5 2 15 3 15 4 -5 5 -5 System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));if (value.compareTo(max) > 0)
pass 1 of 2101}102if (value.compareTo(max10) > 0) {103 return max10;104}System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(15, 0, 10): 10if (value.compareTo(max) > 0)
pass 2 of 2101}102if (value.compareTo(max10) > 0) {103 return max10;104}System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10))…
109System.out.println(" clamp(5, 0, 10): " + RangeOps.clamp(5, 0, 10));110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(15, 0, 10): 10if (value.compareTo(min) < 0)
pass 1 of 298 T value, T min, T max) {99if (value.compareTo(min0) < 0) {100 return min0;101}System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10))…
110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));output clamp(-5, 0, 10): 0if (value.compareTo(min) < 0)
pass 2 of 298 T value, T min, T max) {99if (value.compareTo(min0) < 0) {100 return min0;101}System.out.println(" Count > " + countThreshold + ": " +
110System.out.println(" clamp(15, 0, 10): " + RangeOps.clamp(15, 0, 10));111System.out.println(" clamp(-5, 0, 10): " + RangeOps.clamp(-5, 0, 10));112113System.out.println("\nCount greater:");114115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T threshold) {118 int count = 0;119 for (T item : array) {120 if (item.compareTo(threshold) > 0) {121 count++;122 }123 }124 return count;125 }126}127128int countThreshold = 8;129System.out.println(" Count > " + countThreshold8 + ": " +130 Counter.countGreater(ints, countThreshold8));131System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));output clamp(-5, 0, 10): 0 Count greater: Count greater:count ← 0
pass 1 of 2115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T threshold8) {118 int count→ 0 = 0;119 for (T item : array) {for (T item : array)
pass 1 of 9118int count = 0;119for (T item1 : array) {120 if (item.compareTo(threshold) > 0) {All 9 passes — pass 1 is the card above pass itemthresholdcount1 1 — — 2 2 — — 3 3 — — 4 4 — — 5 5 — — 6 apple — — 7 zebra c 0 → 1 8 banana — — 9 cherry c 1 → 2 return count;
123 }124 return count0;125}System.out.println(" Count > " + countThreshold + ": " +
128 int countThreshold = 8;129 System.out.println(" Count > " + countThreshold8 + ": " +130 Counter.countGreater(ints, countThreshold8));131 System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));132}output Count > 8: 0count ← 0
pass 2 of 2115class Counter {116 public static <T extends Comparable<T>> int countGreater(117 T[] array, T thresholdc) {118 int count→ 0 = 0;119 for (T item : array) {count ← 1
pass 1 of 2119for (T item : array) {120 if (item.compareTo(thresholdc) > 0) {121 count→ 1++;122 }count ← 2
pass 2 of 2119for (T item : array) {120 if (item.compareTo(thresholdc) > 0) {121 count→ 2++;122 }return count;
123 }124 return count2;125}System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"…
130 Counter.countGreater(ints, countThreshold));131 System.out.println(" Count > 'c': " + Counter.countGreater(words, "c"));132}output Count > 'c': 2
<T extends Comparable<T>> - T must be comparable to itself.
Static generic methods
Static methods can be generic even in non-generic classes.
import java.util.*;
public class Static {
static class CollectionUtils {
public static <T> List<T> newArrayList() {
return new ArrayList<>();
}
public static <K, V> Map<K, V> newHashMap() {
return new LinkedHashMap<>();
}
public static <T> Set<T> newHashSet() {
return new LinkedHashSet<>();
}
}
public static void main(String[] args) {
System.out.println("Static generic methods:\n");
List<String> list = CollectionUtils.newArrayList();
list.add("a");
list.add("b");
Map<String, Integer> map = CollectionUtils.newHashMap();
map.put("one", 1);
map.put("two", 2);
System.out.println(" List: " + list);
System.out.println(" Map: " + map);
// Static methods can be generic
// Don't need generic class
// Type parameters independent of class
// Common in utility classes
System.out.println("\nCreate from varargs:");
class ListFactory {
@SafeVarargs
public static <T> List<T> of(T... items) {
List<T> list = new ArrayList<>();
for (T item : items) {
list.add(item);
}
return list;
}
}
List<Integer> nums = ListFactory.of(1, 2, 3, 4, 5);
List<String> words = ListFactory.of("a", "b", "c");
System.out.println(" Numbers: " + nums);
System.out.println(" Words: " + words);
System.out.println("\nCopy collections:");
class Copier {
public static <T> void copy(
Collection<T> dest,
Collection<T> src) {
dest.clear();
dest.addAll(src);
}
public static <T> List<T> copyToList(Collection<T> src) {
return new ArrayList<>(src);
}
}
Set<String> source = new LinkedHashSet<>(Arrays.asList("x", "y", "z"));
List<String> dest = new ArrayList<>();
Copier.copy(dest, source);
System.out.println(" Copied: " + dest);
System.out.println("\nReverse:");
class Reverser {
public static <T> List<T> reverse(List<T> list) {
List<T> result = new ArrayList<>();
for (int i = list.size() - 1; i >= 0; i--) {
result.add(list.get(i));
}
return result;
}
}
List<Integer> original = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> reversed = Reverser.reverse(original);
System.out.println(" Original: " + original);
System.out.println(" Reversed: " + reversed);
System.out.println("\nFilter:");
interface Predicate<T> {
boolean test(T item);
}
class Filter {
public static <T> List<T> filter(
Collection<T> collection,
Predicate<T> predicate) {
List<T> result = new ArrayList<>();
for (T item : collection) {
if (predicate.test(item)) {
result.add(item);
}
}
return result;
}
}
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int divisor = 2;
List<Integer> evens = Filter.filter(numbers, n -> n % divisor == 0);
System.out.println(" Divisible by " + divisor + ": " + evens);
System.out.println("\nTransform:");
interface Function<T, R> {
R apply(T item);
}
class Transformer {
public static <T, R> List<R> map(
Collection<T> collection,
Function<T, R> mapper) {
List<R> result = new ArrayList<>();
for (T item : collection) {
result.add(mapper.apply(item));
}
return result;
}
}
List<String> strings = Arrays.asList("1", "2", "3");
List<Integer> parsed = Transformer.map(strings, Integer::parseInt);
System.out.println(" Strings: " + strings);
System.out.println(" Parsed: " + parsed);
}
}
public static void main(String[] args)
18public static void main(String[] args) {19 System.out.println("Static generic methods:\n");outputStatic generic methods: Static generic methods:System.out.println(" List: " + list);
29System.out.println(" List: " + list[a, b]);30System.out.println(" Map: " + map{one=1, two=2});3132// Static methods can be generic33// Don't need generic class34// Type parameters independent of class35// Common in utility classes3637System.out.println("\nCreate from varargs:");output List: [a, b] List: [a, b] Map: {one=1, two=2} Map: {one=1, two=2} Create from varargs: Create from varargs:list ← []
pass 1 of 239class ListFactory {40 @SafeVarargs41 public static <T> List<T> of(T... items) {42 List<T> list→ [] = new ArrayList<>();43 for (T item : items) {for (T item : items)
pass 1 of 842List<T> list = new ArrayList<>();43for (T item1 : items) {44 list.add(item1);45}All 8 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 6 a 7 b 8 c return list;
45 }46 return list[1, 2, 3, 4, 5];47}list ← []
pass 2 of 239class ListFactory {40 @SafeVarargs41 public static <T> List<T> of(T... items) {42 List<T> list→ [] = new ArrayList<>();43 for (T item : items) {return list;
45 }46 return list[a, b, c];47}System.out.println(" Numbers: " + nums);
53System.out.println(" Numbers: " + nums[1, 2, 3, 4, 5]);54System.out.println(" Words: " + words[a, b, c]);5556System.out.println("\nCopy collections:");output Numbers: [1, 2, 3, 4, 5] Numbers: [1, 2, 3, 4, 5] Words: [a, b, c] Words: [a, b, c] Copy collections: Copy collections:public static <T> void copy( Collection<T> dest, …
58class Copier {59 public static <T> void copy(60 Collection<T> dest[],61 Collection<T> src[x, y, z]) {62 dest.clear();63 dest.addAll(src[x, y, z]);64 }System.out.println(" Copied: " + dest);
74Copier.copy(dest, source);75System.out.println(" Copied: " + dest[x, y, z]);7677System.out.println("\nReverse:");7879class Reverser {80 public static <T> List<T> reverse(List<T> list) {81 List<T> result = new ArrayList<>();82 for (int i = list.size() - 1; i >= 0; i--) {83 result.add(list.get(i));84 }85 return result;86 }87}8889List<Integer> original = Arrays.asList(1, 2, 3, 4, 5);90List<Integer> reversed = Reverser.reverse(original[1, 2, 3, 4, 5]);output Copied: [x, y, z] Copied: [x, y, z] Reverse: Reverse:result ← []
79class Reverser {80 public static <T> List<T> reverse(List<T> list[1, 2, 3, 4, 5]) {81 List<T> result→ [] = new ArrayList<>();82 for (int i = list.size() - 1; i >= 0; i--) {for (int i = list.size() - 1; i >= 0; i--)
pass 1 of 581List<T> result = new ArrayList<>();82for (int i4 = list.size() - 1; i >= 0; i--) {83 result.add(list.get(i4));84}All 5 passes — pass 1 is the card above pass i1 4 2 3 3 2 4 1 5 0 return result;
84 }85 return result[5, 4, 3, 2, 1];86}reversed ← [5, 4, 3, 2, 1], divisor ← 2
89List<Integer> original = Arrays.asList(1, 2, 3, 4, 5);90List<Integer> reversed→ [5, 4, 3, 2, 1] = Reverser.reverse(original[1, 2, 3, 4, 5]);9192System.out.println(" Original: " + original[1, 2, 3, 4, 5]);93System.out.println(" Reversed: " + reversed[5, 4, 3, 2, 1]);9495System.out.println("\nFilter:");9697interface Predicate<T> {98 boolean test(T item);99}100101class Filter {102 public static <T> List<T> filter(103 Collection<T> collection,104 Predicate<T> predicate) {105 List<T> result = new ArrayList<>();106 for (T item : collection) {107 if (predicate.test(item)) {108 result.add(item);109 }110 }111 return result;112 }113}114115List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);116int divisor→ 2 = 2;117List<Integer> evens = Filter.filter(numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], n -> n % divisor == 0);output Original: [1, 2, 3, 4, 5] Reversed: [5, 4, 3, 2, 1] Filter:result ← []
101class Filter {102 public static <T> List<T> filter(103 Collection<T> collection[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],104 Predicate<T> predicate⟨Static lambda A⟩) {105 List<T> result→ [] = new ArrayList<>();106 for (T item : collection) {for (T item : collection)
pass 1 of 10105List<T> result = new ArrayList<>();106for (T item1 : collection[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) {107 if (predicate.test(item)) {All 10 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 if (predicate.test(item))
pass 1 of 5106for (T item : collection) {107 if (predicate.test(item2)) {108 result.add(item2);109 }All 5 passes — pass 1 is the card above pass item1 2 2 4 3 6 4 8 5 10 return result;
110 }111 return result[2, 4, 6, 8, 10];112}evens ← [2, 4, 6, 8, 10]
116int divisor = 2;117List<Integer> evens→ [2, 4, 6, 8, 10] = Filter.filter(numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], n -> n % divisor == 0);118119System.out.println(" Divisible by " + divisor2 + ": " + evens[2, 4, 6, 8, 10]);120121System.out.println("\nTransform:");122123interface Function<T, R> {124 R apply(T item);125}126127class Transformer {128 public static <T, R> List<R> map(129 Collection<T> collection,130 Function<T, R> mapper) {131 List<R> result = new ArrayList<>();132 for (T item : collection) {133 result.add(mapper.apply(item));134 }135 return result;136 }137}138139List<String> strings = Arrays.asList("1", "2", "3");140List<Integer> parsed = Transformer.map(strings[1, 2, 3], Integer::parseInt);output Divisible by 2: [2, 4, 6, 8, 10] Transform:result ← []
127class Transformer {128 public static <T, R> List<R> map(129 Collection<T> collection[1, 2, 3],130 Function<T, R> mapper⟨Static lambda B⟩) {131 List<R> result→ [] = new ArrayList<>();132 for (T item : collection) {for (T item : collection)
pass 1 of 3131List<R> result = new ArrayList<>();132for (T item1 : collection[1, 2, 3]) {133 result.add(mapper.apply(item1));134}All 3 passes — pass 1 is the card above pass item1 1 2 2 3 3 return result;
134 }135 return result[1, 2, 3];136}parsed ← [1, 2, 3]
139 List<String> strings = Arrays.asList("1", "2", "3");140 List<Integer> parsed→ [1, 2, 3] = Transformer.map(strings[1, 2, 3], Integer::parseInt);141 142 System.out.println(" Strings: " + strings[1, 2, 3]);143 System.out.println(" Parsed: " + parsed[1, 2, 3]);144}output Strings: [1, 2, 3] Parsed: [1, 2, 3]
public static <T> T identity(T val) - no instance needed.
Type inference
Compiler infers type from arguments.
import java.util.*;
public class Inference {
public static <T> T identity(T value) {
return value;
}
public static <K, V> Map<K, V> createMap(K key, V value) {
Map<K, V> map = new HashMap<>();
map.put(key, value);
return map;
}
public static void main(String[] args) {
System.out.println("Type inference:\n");
// Explicit type argument
String s1 = Inference.<String>identity("hello");
// Inferred type argument (preferred)
String s2 = identity("hello");
System.out.println(" Explicit: " + s1);
System.out.println(" Inferred: " + s2);
// Java can infer type parameters from arguments
// Explicit: ClassName.<Type>method(arg)
// Inferred: ClassName.method(arg) - preferred
// Inference works with return type context
System.out.println("\nInferred from arguments:");
class Pair<K, V> {
K key;
V value;
Pair(K key, V value) {
this.key = key;
this.value = value;
}
public String toString() {
return "(" + key + ", " + value + ")";
}
}
class PairFactory {
public static <K, V> Pair<K, V> make(K key, V value) {
return new Pair<>(key, value);
}
}
// Type inferred from arguments
Pair<String, Integer> p1 = PairFactory.make("age", 30);
Pair<Integer, String> p2 = PairFactory.make(1, "first");
System.out.println(" Pair 1: " + p1);
System.out.println(" Pair 2: " + p2);
System.out.println("\nDiamond operator:");
// Before Java 7 - redundant
Map<String, List<Integer>> old =
new HashMap<String, List<Integer>>();
// Java 7+ - inferred
Map<String, List<Integer>> modern = new HashMap<>();
modern.put("nums", Arrays.asList(1, 2, 3));
System.out.println(" Map: " + modern);
System.out.println("\nInferred return type:");
class Builder {
public static <T> List<T> build(T... items) {
List<T> list = new ArrayList<>();
for (T item : items) {
list.add(item);
}
return list;
}
}
List<String> words = Builder.build("a", "b", "c");
List<Integer> nums = Builder.build(1, 2, 3);
System.out.println(" Words: " + words);
System.out.println(" Numbers: " + nums);
System.out.println("\nComplex inference:");
class Wrapper<T> {
T value;
Wrapper(T value) {
this.value = value;
}
public String toString() {
return "Wrapper(" + value + ")";
}
}
class WrapperFactory {
public static <T> Wrapper<T> wrap(T value) {
return new Wrapper<>(value);
}
public static <T> List<Wrapper<T>> wrapAll(List<T> values) {
List<Wrapper<T>> result = new ArrayList<>();
for (T value : values) {
result.add(wrap(value));
}
return result;
}
}
List<Integer> numbers = Arrays.asList(1, 2, 3);
List<Wrapper<Integer>> wrapped = WrapperFactory.wrapAll(numbers);
System.out.println(" Wrapped: " + wrapped);
System.out.println("\nTarget type:");
class Utils {
public static <T> List<T> emptyList() {
return new ArrayList<>();
}
}
// Type inferred from variable declaration
List<String> empty1 = Utils.emptyList();
List<Integer> empty2 = Utils.emptyList();
System.out.println(" Empty string list: " + empty1);
System.out.println(" Empty int list: " + empty2);
System.out.println("\nMethod chaining:");
class FluentBuilder<T> {
private List<T> items = new ArrayList<>();
public static <T> FluentBuilder<T> create() {
return new FluentBuilder<>();
}
public FluentBuilder<T> add(T item) {
items.add(item);
return this;
}
public List<T> build() {
return items;
}
}
List<String> result = FluentBuilder.<String>create() // Explicit
.add("a")
.add("b")
.add("c")
.build();
List<Integer> result2 = FluentBuilder.<Integer>create() // Also explicit - chains need hint
.add(1)
.add(2)
.add(3)
.build();
System.out.println(" Result 1: " + result);
System.out.println(" Result 2: " + result2);
}
}
public static void main(String[] args)
14public static void main(String[] args) {15 System.out.println("Type inference:\n");outputType inference: Type inference:public static <T> T identity(T value)
pass 1 of 23public class Inference {4 public static <T> T identity(T valuehello) {5 return valuehello;6 }public static <T> T identity(T value)
pass 2 of 23public class Inference {4 public static <T> T identity(T valuehello) {5 return valuehello;6 }System.out.println(" Explicit: " + s1);
23System.out.println(" Explicit: " + s1hello);24System.out.println(" Inferred: " + s2hello);2526// Java can infer type parameters from arguments27// Explicit: ClassName.<Type>method(arg)28// Inferred: ClassName.method(arg) - preferred29// Inference works with return type context3031System.out.println("\nInferred from arguments:");output Explicit: hello Explicit: hello Inferred: hello Inferred: hello Inferred from arguments: Inferred from arguments:public static <K, V> Pair<K, V> make(K key, V value)
pass 1 of 247class PairFactory {48 public static <K, V> Pair<K, V> make(K keyage, V value30) {49 return new Pair<>(key, value);50 }this.key ← age, this.value ← 30
pass 1 of 237Pair(K keyage, V value30) {38 this.key→ age = keyage;39 this.value→ 30 = value30;40}public static <K, V> Pair<K, V> make(K key, V value)
pass 2 of 247class PairFactory {48 public static <K, V> Pair<K, V> make(K key1, V valuefirst) {49 return new Pair<>(key, value);50 }this.key ← 1, this.value ← first
pass 2 of 237Pair(K key1, V valuefirst) {38 this.key→ 1 = key1;39 this.value→ first = valuefirst;40}System.out.println(" Pair 1: " + p1);
57System.out.println(" Pair 1: " + p1(age, 30));58System.out.println(" Pair 2: " + p2(1, first));5960System.out.println("\nDiamond operator:");6162// Before Java 7 - redundant63Map<String, List<Integer>> old = 64 new HashMap<String, List<Integer>>();6566// Java 7+ - inferred67Map<String, List<Integer>> modern = new HashMap<>();6869modern.put("nums", Arrays.asList(1, 2, 3));70System.out.println(" Map: " + modern{nums=[1, 2, 3]});7172System.out.println("\nInferred return type:");output Pair 1: (age, 30) Pair 1: (age, 30) Pair 2: (1, first) Pair 2: (1, first) Diamond operator: Diamond operator: Map: {nums=[1, 2, 3]} Map: {nums=[1, 2, 3]} Inferred return type: Inferred return type:list ← []
pass 1 of 274class Builder {75 public static <T> List<T> build(T... items) {76 List<T> list→ [] = new ArrayList<>();77 for (T item : items) {for (T item : items)
pass 1 of 676List<T> list = new ArrayList<>();77for (T itema : items) {78 list.add(itema);79}All 6 passes — pass 1 is the card above pass item1 a 2 b 3 c 4 1 5 2 6 3 return list;
79 }80 return list[a, b, c];81}list ← []
pass 2 of 274class Builder {75 public static <T> List<T> build(T... items) {76 List<T> list→ [] = new ArrayList<>();77 for (T item : items) {return list;
79 }80 return list[1, 2, 3];81}System.out.println(" Words: " + words);
87System.out.println(" Words: " + words[a, b, c]);88System.out.println(" Numbers: " + nums[1, 2, 3]);8990System.out.println("\nComplex inference:");output Words: [a, b, c] Words: [a, b, c] Numbers: [1, 2, 3] Numbers: [1, 2, 3] Complex inference: Complex inference:result ← []
109public static <T> List<Wrapper<T>> wrapAll(List<T> values[1, 2, 3]) {110 List<Wrapper<T>> result→ [] = new ArrayList<>();111 for (T value : values) {for (T value : values)
pass 1 of 3110List<Wrapper<T>> result = new ArrayList<>();111for (T value1 : values[1, 2, 3]) {112 result.add(wrap(value1));113}All 3 passes — pass 1 is the card above pass value1 1 2 2 3 3 public static <T> Wrapper<T> wrap(T value)
pass 1 of 3104class WrapperFactory {105 public static <T> Wrapper<T> wrap(T value1) {106 return new Wrapper<>(value);107 }All 3 passes — pass 1 is the card above pass value1 1 2 2 3 3 this.value ← 1
pass 1 of 395Wrapper(T value1) {96 this.value→ 1 = value1;97}All 3 passes — pass 1 is the card above pass valuethis.value1 1 1 2 2 2 3 3 3 result.add(wrap(value));
111for (T value : values) {112 result.add(wrap(value1));113}result.add(wrap(value));
111for (T value : values) {112 result.add(wrap(value2));113}result.add(wrap(value));
111for (T value : values) {112 result.add(wrap(value3));113}return result;
113 }114 return result[Wrapper(1), Wrapper(2), Wrapper(3)];115}System.out.println(" Wrapped: " + wrapped);
121System.out.println(" Wrapped: " + wrapped[Wrapper(1), Wrapper(2), Wrapper(3)]);122123System.out.println("\nTarget type:");output Wrapped: [Wrapper(1), Wrapper(2), Wrapper(3)] Wrapped: [Wrapper(1), Wrapper(2), Wrapper(3)] Target type: Target type:System.out.println(" Empty string list: " + empty1);
135System.out.println(" Empty string list: " + empty1[]);136System.out.println(" Empty int list: " + empty2[]);137138System.out.println("\nMethod chaining:");output Empty string list: [] Empty string list: [] Empty int list: [] Empty int list: [] Method chaining: Method chaining:public FluentBuilder<T> add(T item)
pass 1 of 6147public FluentBuilder<T> add(T itema) {148 items.add(itema);149 return this;150}All 6 passes — pass 1 is the card above pass itemitems1 a — 2 b — 3 c [a, b, c] 4 1 — 5 2 — 6 3 [1, 2, 3] public List<T> build()
pass 1 of 2152public List<T> build() {153 return items[a, b, c];154}List<Integer> result2 = FluentBuilder.<Integer>create() // Also expli…
163List<Integer> result2 = FluentBuilder.<Integer>create() // Also explicit - chains need hint164 .add(1)165 .add(2)166 .add(3)167 .build();public List<T> build()
pass 2 of 2152public List<T> build() {153 return items[1, 2, 3];154}result2 ← [1, 2, 3]
163 List<Integer> result2→ [1, 2, 3] = FluentBuilder.<Integer>create() // Also explicit - chains need hint164 .add(1)165 .add(2)166 .add(3)167 .build();168 169 System.out.println(" Result 1: " + result[a, b, c]);170 System.out.println(" Result 2: " + result2[1, 2, 3]);171}output Result 1: [a, b, c] Result 2: [1, 2, 3]
Box.create("text") - compiler knows T is String. No explicit <String>.
Generic constructors
Constructors can have their own type parameters.
import java.util.*;
public class Constructors {
static class Box<T> {
private T content;
// Generic constructor - U independent of T
<U> Box(U initialValue, Converter<U, T> converter) {
this.content = converter.convert(initialValue);
}
public T get() {
return content;
}
}
interface Converter<F, T> {
T convert(F from);
}
public static void main(String[] args) {
System.out.println("Generic constructors:\n");
// Create Box<Integer> from String
String rawBoxValue = "42";
Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);
System.out.println(" Box content: " + box.get());
// Constructors can have their own type parameters
// Type parameters independent of class type parameters
// Useful for type conversion during construction
// Generic constructors enable flexible initialization
System.out.println("\nCollection initialization:");
class Container<T> {
private List<T> items;
// Non-generic constructor
Container() {
this.items = new ArrayList<>();
}
// Generic constructor
<U> Container(Collection<U> source, Converter<U, T> converter) {
this.items = new ArrayList<>();
for (U item : source) {
items.add(converter.convert(item));
}
}
public List<T> getItems() {
return items;
}
}
List<String> strings = Arrays.asList("1", "2", "3", "4", "5");
Container<Integer> numbers = new Container<>(strings, Integer::parseInt);
System.out.println(" Numbers: " + numbers.getItems());
System.out.println("\nBuilder pattern:");
class Person {
private String name;
private int age;
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + " (" + age + ")";
}
}
interface Factory<T> {
T create(Map<String, Object> props);
}
class Builder<T> {
private Map<String, Object> properties = new LinkedHashMap<>();
<U> Builder<T> set(String key, U value) {
properties.put(key, value);
return this;
}
T build(Factory<T> factory) {
return factory.create(properties);
}
}
Person person = new Builder<Person>()
.set("name", "Alice")
.set("age", 30)
.build(props -> new Person(
(String) props.get("name"),
(Integer) props.get("age")
));
System.out.println(" Person: " + person);
System.out.println("\nCached initialization:");
interface KeyConverter<K> {
String convert(K key);
}
class Cache<T> {
private Map<String, T> cache = new LinkedHashMap<>();
<K> Cache(Map<K, T> initial, KeyConverter<K> converter) {
for (Map.Entry<K, T> entry : initial.entrySet()) {
String key = converter.convert(entry.getKey());
cache.put(key, entry.getValue());
}
}
public T get(String key) {
return cache.get(key);
}
public Set<String> keys() {
return cache.keySet();
}
}
Map<Integer, String> data = new LinkedHashMap<>();
data.put(1, "one");
data.put(2, "two");
data.put(3, "three");
Cache<String> cache = new Cache<>(data, Object::toString);
System.out.println(" Keys: " + cache.keys());
System.out.println(" Value for '1': " + cache.get("1"));
System.out.println("\nMulti-source constructor:");
class Aggregator<T> {
private List<T> all = new ArrayList<>();
@SafeVarargs
<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {
for (Collection<U> source : sources) {
for (U item : source) {
all.add(converter.convert(item));
}
}
}
public List<T> getAll() {
return all;
}
}
List<String> source1 = Arrays.asList("1", "2", "3");
List<String> source2 = Arrays.asList("4", "5", "6");
Aggregator<Integer> agg = new Aggregator<>(
Integer::parseInt,
source1,
source2
);
System.out.println(" Aggregated: " + agg.getAll());
System.out.println("\nWrapper constructor:");
interface Parser<F, T> {
T parse(F from);
}
class Wrapper<T> {
private T value;
Wrapper(T value) {
this.value = value;
}
<U> Wrapper(U rawValue, Parser<U, T> parser) {
this.value = parser.parse(rawValue);
}
public T getValue() {
return value;
}
}
Wrapper<Integer> w1 = new Wrapper<>(42);
Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);
System.out.println(" Wrapper 1: " + w1.getValue());
System.out.println(" Wrapper 2: " + w2.getValue());
}
}
import java.util.*;
public class Constructors {
static class Box<T> {
private T content;
// Generic constructor - U independent of T
<U> Box(U initialValue, Converter<U, T> converter) {
this.content = converter.convert(initialValue);
}
public T get() {
return content;
}
}
interface Converter<F, T> {
T convert(F from);
}
public static void main(String[] args) {
System.out.println("Generic constructors:\n");
// Create Box<Integer> from String
String rawBoxValue = "7";
Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);
System.out.println(" Box content: " + box.get());
// Constructors can have their own type parameters
// Type parameters independent of class type parameters
// Useful for type conversion during construction
// Generic constructors enable flexible initialization
System.out.println("\nCollection initialization:");
class Container<T> {
private List<T> items;
// Non-generic constructor
Container() {
this.items = new ArrayList<>();
}
// Generic constructor
<U> Container(Collection<U> source, Converter<U, T> converter) {
this.items = new ArrayList<>();
for (U item : source) {
items.add(converter.convert(item));
}
}
public List<T> getItems() {
return items;
}
}
List<String> strings = Arrays.asList("1", "2", "3", "4", "5");
Container<Integer> numbers = new Container<>(strings, Integer::parseInt);
System.out.println(" Numbers: " + numbers.getItems());
System.out.println("\nBuilder pattern:");
class Person {
private String name;
private int age;
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + " (" + age + ")";
}
}
interface Factory<T> {
T create(Map<String, Object> props);
}
class Builder<T> {
private Map<String, Object> properties = new LinkedHashMap<>();
<U> Builder<T> set(String key, U value) {
properties.put(key, value);
return this;
}
T build(Factory<T> factory) {
return factory.create(properties);
}
}
Person person = new Builder<Person>()
.set("name", "Alice")
.set("age", 30)
.build(props -> new Person(
(String) props.get("name"),
(Integer) props.get("age")
));
System.out.println(" Person: " + person);
System.out.println("\nCached initialization:");
interface KeyConverter<K> {
String convert(K key);
}
class Cache<T> {
private Map<String, T> cache = new LinkedHashMap<>();
<K> Cache(Map<K, T> initial, KeyConverter<K> converter) {
for (Map.Entry<K, T> entry : initial.entrySet()) {
String key = converter.convert(entry.getKey());
cache.put(key, entry.getValue());
}
}
public T get(String key) {
return cache.get(key);
}
public Set<String> keys() {
return cache.keySet();
}
}
Map<Integer, String> data = new LinkedHashMap<>();
data.put(1, "one");
data.put(2, "two");
data.put(3, "three");
Cache<String> cache = new Cache<>(data, Object::toString);
System.out.println(" Keys: " + cache.keys());
System.out.println(" Value for '1': " + cache.get("1"));
System.out.println("\nMulti-source constructor:");
class Aggregator<T> {
private List<T> all = new ArrayList<>();
@SafeVarargs
<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {
for (Collection<U> source : sources) {
for (U item : source) {
all.add(converter.convert(item));
}
}
}
public List<T> getAll() {
return all;
}
}
List<String> source1 = Arrays.asList("1", "2", "3");
List<String> source2 = Arrays.asList("4", "5", "6");
Aggregator<Integer> agg = new Aggregator<>(
Integer::parseInt,
source1,
source2
);
System.out.println(" Aggregated: " + agg.getAll());
System.out.println("\nWrapper constructor:");
interface Parser<F, T> {
T parse(F from);
}
class Wrapper<T> {
private T value;
Wrapper(T value) {
this.value = value;
}
<U> Wrapper(U rawValue, Parser<U, T> parser) {
this.value = parser.parse(rawValue);
}
public T getValue() {
return value;
}
}
Wrapper<Integer> w1 = new Wrapper<>(42);
Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);
System.out.println(" Wrapper 1: " + w1.getValue());
System.out.println(" Wrapper 2: " + w2.getValue());
}
}
import java.util.*;
public class Constructors {
static class Box<T> {
private T content;
// Generic constructor - U independent of T
<U> Box(U initialValue, Converter<U, T> converter) {
this.content = converter.convert(initialValue);
}
public T get() {
return content;
}
}
interface Converter<F, T> {
T convert(F from);
}
public static void main(String[] args) {
System.out.println("Generic constructors:\n");
// Create Box<Integer> from String
String rawBoxValue = "123";
Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);
System.out.println(" Box content: " + box.get());
// Constructors can have their own type parameters
// Type parameters independent of class type parameters
// Useful for type conversion during construction
// Generic constructors enable flexible initialization
System.out.println("\nCollection initialization:");
class Container<T> {
private List<T> items;
// Non-generic constructor
Container() {
this.items = new ArrayList<>();
}
// Generic constructor
<U> Container(Collection<U> source, Converter<U, T> converter) {
this.items = new ArrayList<>();
for (U item : source) {
items.add(converter.convert(item));
}
}
public List<T> getItems() {
return items;
}
}
List<String> strings = Arrays.asList("1", "2", "3", "4", "5");
Container<Integer> numbers = new Container<>(strings, Integer::parseInt);
System.out.println(" Numbers: " + numbers.getItems());
System.out.println("\nBuilder pattern:");
class Person {
private String name;
private int age;
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + " (" + age + ")";
}
}
interface Factory<T> {
T create(Map<String, Object> props);
}
class Builder<T> {
private Map<String, Object> properties = new LinkedHashMap<>();
<U> Builder<T> set(String key, U value) {
properties.put(key, value);
return this;
}
T build(Factory<T> factory) {
return factory.create(properties);
}
}
Person person = new Builder<Person>()
.set("name", "Alice")
.set("age", 30)
.build(props -> new Person(
(String) props.get("name"),
(Integer) props.get("age")
));
System.out.println(" Person: " + person);
System.out.println("\nCached initialization:");
interface KeyConverter<K> {
String convert(K key);
}
class Cache<T> {
private Map<String, T> cache = new LinkedHashMap<>();
<K> Cache(Map<K, T> initial, KeyConverter<K> converter) {
for (Map.Entry<K, T> entry : initial.entrySet()) {
String key = converter.convert(entry.getKey());
cache.put(key, entry.getValue());
}
}
public T get(String key) {
return cache.get(key);
}
public Set<String> keys() {
return cache.keySet();
}
}
Map<Integer, String> data = new LinkedHashMap<>();
data.put(1, "one");
data.put(2, "two");
data.put(3, "three");
Cache<String> cache = new Cache<>(data, Object::toString);
System.out.println(" Keys: " + cache.keys());
System.out.println(" Value for '1': " + cache.get("1"));
System.out.println("\nMulti-source constructor:");
class Aggregator<T> {
private List<T> all = new ArrayList<>();
@SafeVarargs
<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {
for (Collection<U> source : sources) {
for (U item : source) {
all.add(converter.convert(item));
}
}
}
public List<T> getAll() {
return all;
}
}
List<String> source1 = Arrays.asList("1", "2", "3");
List<String> source2 = Arrays.asList("4", "5", "6");
Aggregator<Integer> agg = new Aggregator<>(
Integer::parseInt,
source1,
source2
);
System.out.println(" Aggregated: " + agg.getAll());
System.out.println("\nWrapper constructor:");
interface Parser<F, T> {
T parse(F from);
}
class Wrapper<T> {
private T value;
Wrapper(T value) {
this.value = value;
}
<U> Wrapper(U rawValue, Parser<U, T> parser) {
this.value = parser.parse(rawValue);
}
public T getValue() {
return value;
}
}
Wrapper<Integer> w1 = new Wrapper<>(42);
Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);
System.out.println(" Wrapper 1: " + w1.getValue());
System.out.println(" Wrapper 2: " + w2.getValue());
}
}
public static void main(String[] args)
21public static void main(String[] args) {22 System.out.println("Generic constructors:\n");outputGeneric constructors: Generic constructors:this.content ← 42
7// Generic constructor - U independent of T8<U> Box(U initialValue42, Converter<U, T> converter⟨Constructors lambda A⟩) {9 this.content→ 42 = converter.convert(initialValue42);10}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());public T get()
pass 1 of 212public T get() {13 return content42;14}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());output Box content: 42public T get()
pass 2 of 212public T get() {13 return content42;14}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());2829// Constructors can have their own type parameters30// Type parameters independent of class type parameters31// Useful for type conversion during construction32// Generic constructors enable flexible initialization3334System.out.println("\nCollection initialization:");output Box content: 42 Collection initialization: Collection initialization:this.items ← []
44// Generic constructor45<U> Container(Collection<U> source[1, 2, 3, 4, 5], Converter<U, T> converter⟨Constructors lambda B⟩) {46 this.items→ [] = new ArrayList<>();47 for (U item : source) {for (U item : source)
pass 1 of 546this.items = new ArrayList<>();47for (U item1 : source[1, 2, 3, 4, 5]) {48 items.add(converter.convert(item1));49}All 5 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());public List<T> getItems()
pass 1 of 252public List<T> getItems() {53 return items[1, 2, 3, 4, 5];54}System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());output Numbers: [1, 2, 3, 4, 5]public List<T> getItems()
pass 2 of 252public List<T> getItems() {53 return items[1, 2, 3, 4, 5];54}System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());6162System.out.println("\nBuilder pattern:");6364class Person {65 private String name;66 private int age;67 68 private Person(String name, int age) {69 this.name = name;70 this.age = age;71 }72 73 public String toString() {74 return name + " (" + age + ")";75 }76}7778interface Factory<T> {79 T create(Map<String, Object> props);80}8182class Builder<T> {83 private Map<String, Object> properties = new LinkedHashMap<>();8485 <U> Builder<T> set(String key, U value) {86 properties.put(key, value);87 return this;88 }8990 T build(Factory<T> factory) {91 return factory.create(properties);92 }93}9495Person person = new Builder<Person>()96 .set("name", "Alice")97 .set("age", 30)98 .build(props -> new Person(99 (String) props.get("name"),100 (Integer) props.get("age")101 ));output Numbers: [1, 2, 3, 4, 5] Builder pattern: Builder pattern:<U> Builder<T> set(String key, U value)
pass 1 of 285<U> Builder<T> set(String keyname, U valueAlice) {86 properties.put(keyname, valueAlice);87 return this;88}<U> Builder<T> set(String key, U value)
pass 2 of 285<U> Builder<T> set(String keyage, U value30) {86 properties.put(keyage, value30);87 return this;88}T build(Factory<T> factory)
90T build(Factory<T> factory⟨Constructors lambda C⟩) {91 return factory.create(properties{name=Alice, age=30});92}this.name ← Alice, this.age ← 30
68private Person(String nameAlice, int age30) {69 this.name→ Alice = nameAlice;70 this.age→ 30 = age30;71}System.out.println(" Person: " + person);
103System.out.println(" Person: " + personAlice (30));104105System.out.println("\nCached initialization:");output Person: Alice (30) Cached initialization:<K> Cache(Map<K, T> initial, KeyConverter<K> converter)
114<K> Cache(Map<K, T> initial{1=one, 2=two, 3=three}, KeyConverter<K> converter⟨Constructors lambda D⟩) {115 for (Map.Entry<K, T> entry : initial.entrySet()) {key ← 1
pass 1 of 3114<K> Cache(Map<K, T> initial, KeyConverter<K> converter) {115 for (Map.Entry<K, T> entry1=one : initial.entrySet()) {116 String key→ 1 = converter.convert(entry.getKey());117 cache.put(key1, entry.getValue());118 }All 3 passes — pass 1 is the card above pass entrykey1 1=one 1 2 2=two 2 3 3=three 3 System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Keys: [1, 2, 3]System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Keys: [1, 2, 3]public T get(String key)
pass 1 of 2121public T get(String key1) {122 return cache.get(key1);123}System.out.println(" Value for '1': " + cache.get("1"));
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Value for '1': onepublic T get(String key)
pass 2 of 2121public T get(String key1) {122 return cache.get(key1);123}source2 ← [4, 5, 6]
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));139140System.out.println("\nMulti-source constructor:");141142class Aggregator<T> {143 private List<T> all = new ArrayList<>();144 145 @SafeVarargs146 <U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source : sources) {148 for (U item : source) {149 all.add(converter.convert(item));150 }151 }152 }153 154 public List<T> getAll() {155 return all;156 }157}158159List<String> source1 = Arrays.asList("1", "2", "3");160List<String> source2→ [4, 5, 6] = Arrays.asList("4", "5", "6");161162Aggregator<Integer> agg = new Aggregator<>(163 Integer::parseInt, 164 source1, 165 source2166);output Value for '1': one Multi-source constructor: Multi-source constructor:@SafeVarargs <U> Aggregator(Converter<U, T> converter, Col…
145@SafeVarargs146<U> Aggregator(Converter<U, T> converter⟨Constructors lambda E⟩, Collection<U>... sources) {147 for (Collection<U> source : sources) {for (Collection<U> source : sources)
pass 1 of 2146<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source[1, 2, 3] : sources) {148 for (U item : source) {for (U item : source)
pass 1 of 6147for (Collection<U> source : sources) {148 for (U item1 : source[1, 2, 3]) {149 all.add(converter.convert(item1));150 }All 6 passes — pass 1 is the card above pass itemsource1 1 [1, 2, 3] 2 2 [1, 2, 3] 3 3 [1, 2, 3] 4 4 [4, 5, 6] 5 5 [4, 5, 6] 6 6 [4, 5, 6] for (Collection<U> source : sources)
pass 2 of 2146<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source[4, 5, 6] : sources) {148 for (U item : source) {agg ← ⟨Constructors$1Aggregator F⟩
162Aggregator<Integer> agg→ ⟨Constructors$1Aggregator F⟩ = new Aggregator<>(163 Integer::parseInt, 164 source1, 165 source2166);167168System.out.println(" Aggregated: " + agg.getAll());public List<T> getAll()
154public List<T> getAll() {155 return all[1, 2, 3, 4, 5, 6];156}System.out.println(" Aggregated: " + agg.getAll());
168System.out.println(" Aggregated: " + agg.getAll());169170System.out.println("\nWrapper constructor:");output Aggregated: [1, 2, 3, 4, 5, 6] Wrapper constructor:this.value ← 42
179Wrapper(T value42) {180 this.value→ 42 = value42;181}Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);
192Wrapper<Integer> w1 = new Wrapper<>(42);193Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);this.value ← 123
183<U> Wrapper(U rawValue123, Parser<U, T> parser⟨Constructors lambda G⟩) {184 this.value→ 123 = parser.parse(rawValue123);185}w2 ← ⟨Constructors$1Wrapper H⟩
192Wrapper<Integer> w1 = new Wrapper<>(42);193Wrapper<Integer> w2→ ⟨Constructors$1Wrapper H⟩ = new Wrapper<>("123", Integer::parseInt);194195System.out.println(" Wrapper 1: " + w1.getValue());196System.out.println(" Wrapper 2: " + w2.getValue());public T getValue()
pass 1 of 2187public T getValue() {188 return value42;189}System.out.println(" Wrapper 1: " + w1.getValue());
195 System.out.println(" Wrapper 1: " + w1.getValue());196 System.out.println(" Wrapper 2: " + w2.getValue());197}output Wrapper 1: 42public T getValue()
pass 2 of 2187public T getValue() {188 return value123;189}System.out.println(" Wrapper 2: " + w2.getValue());
195 System.out.println(" Wrapper 1: " + w1.getValue());196 System.out.println(" Wrapper 2: " + w2.getValue());197}output Wrapper 2: 123
public static void main(String[] args)
21public static void main(String[] args) {22 System.out.println("Generic constructors:\n");outputGeneric constructors: Generic constructors:this.content ← 7
7// Generic constructor - U independent of T8<U> Box(U initialValue7, Converter<U, T> converter⟨Constructors lambda A⟩) {9 this.content→ 7 = converter.convert(initialValue7);10}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());public T get()
pass 1 of 212public T get() {13 return content7;14}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());output Box content: 7public T get()
pass 2 of 212public T get() {13 return content7;14}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());2829// Constructors can have their own type parameters30// Type parameters independent of class type parameters31// Useful for type conversion during construction32// Generic constructors enable flexible initialization3334System.out.println("\nCollection initialization:");output Box content: 7 Collection initialization: Collection initialization:this.items ← []
44// Generic constructor45<U> Container(Collection<U> source[1, 2, 3, 4, 5], Converter<U, T> converter⟨Constructors lambda B⟩) {46 this.items→ [] = new ArrayList<>();47 for (U item : source) {for (U item : source)
pass 1 of 546this.items = new ArrayList<>();47for (U item1 : source[1, 2, 3, 4, 5]) {48 items.add(converter.convert(item1));49}All 5 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());public List<T> getItems()
pass 1 of 252public List<T> getItems() {53 return items[1, 2, 3, 4, 5];54}System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());output Numbers: [1, 2, 3, 4, 5]public List<T> getItems()
pass 2 of 252public List<T> getItems() {53 return items[1, 2, 3, 4, 5];54}System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());6162System.out.println("\nBuilder pattern:");6364class Person {65 private String name;66 private int age;67 68 private Person(String name, int age) {69 this.name = name;70 this.age = age;71 }72 73 public String toString() {74 return name + " (" + age + ")";75 }76}7778interface Factory<T> {79 T create(Map<String, Object> props);80}8182class Builder<T> {83 private Map<String, Object> properties = new LinkedHashMap<>();8485 <U> Builder<T> set(String key, U value) {86 properties.put(key, value);87 return this;88 }8990 T build(Factory<T> factory) {91 return factory.create(properties);92 }93}9495Person person = new Builder<Person>()96 .set("name", "Alice")97 .set("age", 30)98 .build(props -> new Person(99 (String) props.get("name"),100 (Integer) props.get("age")101 ));output Numbers: [1, 2, 3, 4, 5] Builder pattern: Builder pattern:<U> Builder<T> set(String key, U value)
pass 1 of 285<U> Builder<T> set(String keyname, U valueAlice) {86 properties.put(keyname, valueAlice);87 return this;88}<U> Builder<T> set(String key, U value)
pass 2 of 285<U> Builder<T> set(String keyage, U value30) {86 properties.put(keyage, value30);87 return this;88}T build(Factory<T> factory)
90T build(Factory<T> factory⟨Constructors lambda C⟩) {91 return factory.create(properties{name=Alice, age=30});92}this.name ← Alice, this.age ← 30
68private Person(String nameAlice, int age30) {69 this.name→ Alice = nameAlice;70 this.age→ 30 = age30;71}System.out.println(" Person: " + person);
103System.out.println(" Person: " + personAlice (30));104105System.out.println("\nCached initialization:");output Person: Alice (30) Cached initialization:<K> Cache(Map<K, T> initial, KeyConverter<K> converter)
114<K> Cache(Map<K, T> initial{1=one, 2=two, 3=three}, KeyConverter<K> converter⟨Constructors lambda D⟩) {115 for (Map.Entry<K, T> entry : initial.entrySet()) {key ← 1
pass 1 of 3114<K> Cache(Map<K, T> initial, KeyConverter<K> converter) {115 for (Map.Entry<K, T> entry1=one : initial.entrySet()) {116 String key→ 1 = converter.convert(entry.getKey());117 cache.put(key1, entry.getValue());118 }All 3 passes — pass 1 is the card above pass entrykey1 1=one 1 2 2=two 2 3 3=three 3 System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Keys: [1, 2, 3]System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Keys: [1, 2, 3]public T get(String key)
pass 1 of 2121public T get(String key1) {122 return cache.get(key1);123}System.out.println(" Value for '1': " + cache.get("1"));
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Value for '1': onepublic T get(String key)
pass 2 of 2121public T get(String key1) {122 return cache.get(key1);123}source2 ← [4, 5, 6]
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));139140System.out.println("\nMulti-source constructor:");141142class Aggregator<T> {143 private List<T> all = new ArrayList<>();144 145 @SafeVarargs146 <U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source : sources) {148 for (U item : source) {149 all.add(converter.convert(item));150 }151 }152 }153 154 public List<T> getAll() {155 return all;156 }157}158159List<String> source1 = Arrays.asList("1", "2", "3");160List<String> source2→ [4, 5, 6] = Arrays.asList("4", "5", "6");161162Aggregator<Integer> agg = new Aggregator<>(163 Integer::parseInt, 164 source1, 165 source2166);output Value for '1': one Multi-source constructor: Multi-source constructor:@SafeVarargs <U> Aggregator(Converter<U, T> converter, Col…
145@SafeVarargs146<U> Aggregator(Converter<U, T> converter⟨Constructors lambda E⟩, Collection<U>... sources) {147 for (Collection<U> source : sources) {for (Collection<U> source : sources)
pass 1 of 2146<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source[1, 2, 3] : sources) {148 for (U item : source) {for (U item : source)
pass 1 of 6147for (Collection<U> source : sources) {148 for (U item1 : source[1, 2, 3]) {149 all.add(converter.convert(item1));150 }All 6 passes — pass 1 is the card above pass itemsource1 1 [1, 2, 3] 2 2 [1, 2, 3] 3 3 [1, 2, 3] 4 4 [4, 5, 6] 5 5 [4, 5, 6] 6 6 [4, 5, 6] for (Collection<U> source : sources)
pass 2 of 2146<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source[4, 5, 6] : sources) {148 for (U item : source) {agg ← ⟨Constructors$1Aggregator F⟩
162Aggregator<Integer> agg→ ⟨Constructors$1Aggregator F⟩ = new Aggregator<>(163 Integer::parseInt, 164 source1, 165 source2166);167168System.out.println(" Aggregated: " + agg.getAll());public List<T> getAll()
154public List<T> getAll() {155 return all[1, 2, 3, 4, 5, 6];156}System.out.println(" Aggregated: " + agg.getAll());
168System.out.println(" Aggregated: " + agg.getAll());169170System.out.println("\nWrapper constructor:");output Aggregated: [1, 2, 3, 4, 5, 6] Wrapper constructor:this.value ← 42
179Wrapper(T value42) {180 this.value→ 42 = value42;181}Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);
192Wrapper<Integer> w1 = new Wrapper<>(42);193Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);this.value ← 123
183<U> Wrapper(U rawValue123, Parser<U, T> parser⟨Constructors lambda G⟩) {184 this.value→ 123 = parser.parse(rawValue123);185}w2 ← ⟨Constructors$1Wrapper H⟩
192Wrapper<Integer> w1 = new Wrapper<>(42);193Wrapper<Integer> w2→ ⟨Constructors$1Wrapper H⟩ = new Wrapper<>("123", Integer::parseInt);194195System.out.println(" Wrapper 1: " + w1.getValue());196System.out.println(" Wrapper 2: " + w2.getValue());public T getValue()
pass 1 of 2187public T getValue() {188 return value42;189}System.out.println(" Wrapper 1: " + w1.getValue());
195 System.out.println(" Wrapper 1: " + w1.getValue());196 System.out.println(" Wrapper 2: " + w2.getValue());197}output Wrapper 1: 42public T getValue()
pass 2 of 2187public T getValue() {188 return value123;189}System.out.println(" Wrapper 2: " + w2.getValue());
195 System.out.println(" Wrapper 1: " + w1.getValue());196 System.out.println(" Wrapper 2: " + w2.getValue());197}output Wrapper 2: 123
public static void main(String[] args)
21public static void main(String[] args) {22 System.out.println("Generic constructors:\n");outputGeneric constructors: Generic constructors:this.content ← 123
7// Generic constructor - U independent of T8<U> Box(U initialValue123, Converter<U, T> converter⟨Constructors lambda A⟩) {9 this.content→ 123 = converter.convert(initialValue123);10}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());public T get()
pass 1 of 212public T get() {13 return content123;14}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());output Box content: 123public T get()
pass 2 of 212public T get() {13 return content123;14}System.out.println(" Box content: " + box.get());
26Box<Integer> box = new Box<>(rawBoxValue, Integer::parseInt);27System.out.println(" Box content: " + box.get());2829// Constructors can have their own type parameters30// Type parameters independent of class type parameters31// Useful for type conversion during construction32// Generic constructors enable flexible initialization3334System.out.println("\nCollection initialization:");output Box content: 123 Collection initialization: Collection initialization:this.items ← []
44// Generic constructor45<U> Container(Collection<U> source[1, 2, 3, 4, 5], Converter<U, T> converter⟨Constructors lambda B⟩) {46 this.items→ [] = new ArrayList<>();47 for (U item : source) {for (U item : source)
pass 1 of 546this.items = new ArrayList<>();47for (U item1 : source[1, 2, 3, 4, 5]) {48 items.add(converter.convert(item1));49}All 5 passes — pass 1 is the card above pass item1 1 2 2 3 3 4 4 5 5 System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());public List<T> getItems()
pass 1 of 252public List<T> getItems() {53 return items[1, 2, 3, 4, 5];54}System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());output Numbers: [1, 2, 3, 4, 5]public List<T> getItems()
pass 2 of 252public List<T> getItems() {53 return items[1, 2, 3, 4, 5];54}System.out.println(" Numbers: " + numbers.getItems());
60System.out.println(" Numbers: " + numbers.getItems());6162System.out.println("\nBuilder pattern:");6364class Person {65 private String name;66 private int age;67 68 private Person(String name, int age) {69 this.name = name;70 this.age = age;71 }72 73 public String toString() {74 return name + " (" + age + ")";75 }76}7778interface Factory<T> {79 T create(Map<String, Object> props);80}8182class Builder<T> {83 private Map<String, Object> properties = new LinkedHashMap<>();8485 <U> Builder<T> set(String key, U value) {86 properties.put(key, value);87 return this;88 }8990 T build(Factory<T> factory) {91 return factory.create(properties);92 }93}9495Person person = new Builder<Person>()96 .set("name", "Alice")97 .set("age", 30)98 .build(props -> new Person(99 (String) props.get("name"),100 (Integer) props.get("age")101 ));output Numbers: [1, 2, 3, 4, 5] Builder pattern: Builder pattern:<U> Builder<T> set(String key, U value)
pass 1 of 285<U> Builder<T> set(String keyname, U valueAlice) {86 properties.put(keyname, valueAlice);87 return this;88}<U> Builder<T> set(String key, U value)
pass 2 of 285<U> Builder<T> set(String keyage, U value30) {86 properties.put(keyage, value30);87 return this;88}T build(Factory<T> factory)
90T build(Factory<T> factory⟨Constructors lambda C⟩) {91 return factory.create(properties{name=Alice, age=30});92}this.name ← Alice, this.age ← 30
68private Person(String nameAlice, int age30) {69 this.name→ Alice = nameAlice;70 this.age→ 30 = age30;71}System.out.println(" Person: " + person);
103System.out.println(" Person: " + personAlice (30));104105System.out.println("\nCached initialization:");output Person: Alice (30) Cached initialization:<K> Cache(Map<K, T> initial, KeyConverter<K> converter)
114<K> Cache(Map<K, T> initial{1=one, 2=two, 3=three}, KeyConverter<K> converter⟨Constructors lambda D⟩) {115 for (Map.Entry<K, T> entry : initial.entrySet()) {key ← 1
pass 1 of 3114<K> Cache(Map<K, T> initial, KeyConverter<K> converter) {115 for (Map.Entry<K, T> entry1=one : initial.entrySet()) {116 String key→ 1 = converter.convert(entry.getKey());117 cache.put(key1, entry.getValue());118 }All 3 passes — pass 1 is the card above pass entrykey1 1=one 1 2 2=two 2 3 3=three 3 System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Keys: [1, 2, 3]System.out.println(" Keys: " + cache.keys());
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Keys: [1, 2, 3]public T get(String key)
pass 1 of 2121public T get(String key1) {122 return cache.get(key1);123}System.out.println(" Value for '1': " + cache.get("1"));
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));output Value for '1': onepublic T get(String key)
pass 2 of 2121public T get(String key1) {122 return cache.get(key1);123}source2 ← [4, 5, 6]
137System.out.println(" Keys: " + cache.keys());138System.out.println(" Value for '1': " + cache.get("1"));139140System.out.println("\nMulti-source constructor:");141142class Aggregator<T> {143 private List<T> all = new ArrayList<>();144 145 @SafeVarargs146 <U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source : sources) {148 for (U item : source) {149 all.add(converter.convert(item));150 }151 }152 }153 154 public List<T> getAll() {155 return all;156 }157}158159List<String> source1 = Arrays.asList("1", "2", "3");160List<String> source2→ [4, 5, 6] = Arrays.asList("4", "5", "6");161162Aggregator<Integer> agg = new Aggregator<>(163 Integer::parseInt, 164 source1, 165 source2166);output Value for '1': one Multi-source constructor: Multi-source constructor:@SafeVarargs <U> Aggregator(Converter<U, T> converter, Col…
145@SafeVarargs146<U> Aggregator(Converter<U, T> converter⟨Constructors lambda E⟩, Collection<U>... sources) {147 for (Collection<U> source : sources) {for (Collection<U> source : sources)
pass 1 of 2146<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source[1, 2, 3] : sources) {148 for (U item : source) {for (U item : source)
pass 1 of 6147for (Collection<U> source : sources) {148 for (U item1 : source[1, 2, 3]) {149 all.add(converter.convert(item1));150 }All 6 passes — pass 1 is the card above pass itemsource1 1 [1, 2, 3] 2 2 [1, 2, 3] 3 3 [1, 2, 3] 4 4 [4, 5, 6] 5 5 [4, 5, 6] 6 6 [4, 5, 6] for (Collection<U> source : sources)
pass 2 of 2146<U> Aggregator(Converter<U, T> converter, Collection<U>... sources) {147 for (Collection<U> source[4, 5, 6] : sources) {148 for (U item : source) {agg ← ⟨Constructors$1Aggregator F⟩
162Aggregator<Integer> agg→ ⟨Constructors$1Aggregator F⟩ = new Aggregator<>(163 Integer::parseInt, 164 source1, 165 source2166);167168System.out.println(" Aggregated: " + agg.getAll());public List<T> getAll()
154public List<T> getAll() {155 return all[1, 2, 3, 4, 5, 6];156}System.out.println(" Aggregated: " + agg.getAll());
168System.out.println(" Aggregated: " + agg.getAll());169170System.out.println("\nWrapper constructor:");output Aggregated: [1, 2, 3, 4, 5, 6] Wrapper constructor:this.value ← 42
179Wrapper(T value42) {180 this.value→ 42 = value42;181}Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);
192Wrapper<Integer> w1 = new Wrapper<>(42);193Wrapper<Integer> w2 = new Wrapper<>("123", Integer::parseInt);this.value ← 123
183<U> Wrapper(U rawValue123, Parser<U, T> parser⟨Constructors lambda G⟩) {184 this.value→ 123 = parser.parse(rawValue123);185}w2 ← ⟨Constructors$1Wrapper H⟩
192Wrapper<Integer> w1 = new Wrapper<>(42);193Wrapper<Integer> w2→ ⟨Constructors$1Wrapper H⟩ = new Wrapper<>("123", Integer::parseInt);194195System.out.println(" Wrapper 1: " + w1.getValue());196System.out.println(" Wrapper 2: " + w2.getValue());public T getValue()
pass 1 of 2187public T getValue() {188 return value42;189}System.out.println(" Wrapper 1: " + w1.getValue());
195 System.out.println(" Wrapper 1: " + w1.getValue());196 System.out.println(" Wrapper 2: " + w2.getValue());197}output Wrapper 1: 42public T getValue()
pass 2 of 2187public T getValue() {188 return value123;189}System.out.println(" Wrapper 2: " + w2.getValue());
195 System.out.println(" Wrapper 1: " + w1.getValue());196 System.out.println(" Wrapper 2: " + w2.getValue());197}output Wrapper 2: 123
<U> MyClass(U value) - U separate from class type parameter.
Exercise: Practical.java
Build utility methods using generic methods