From 67e42ca6e0dad4553ed7a8952472411f591edb18 Mon Sep 17 00:00:00 2001 From: David Delabassee Date: Mon, 20 Jan 2025 12:33:52 +0100 Subject: [PATCH 1/7] Java 24 Initial snippets --- java24/Gatherers_A1.snippet | 15 ++++++ java24/Gatherers_A2.snippet | 9 ++++ java24/Gatherers_A3.snippet | 19 +++++++ java24/Gatherers_B1.snippet | 21 ++++++++ java24/Gatherers_B10.snippet | 28 ++++++++++ java24/Gatherers_B11.snippet | 17 ++++++ java24/Gatherers_B12.snippet | 25 +++++++++ java24/Gatherers_B13.snippet | 23 +++++++++ java24/Gatherers_B14.snippet | 32 ++++++++++++ java24/Gatherers_B15.snippet | 21 ++++++++ java24/Gatherers_B16.snippet | 25 +++++++++ java24/Gatherers_B17.snippet | 29 +++++++++++ java24/Gatherers_B18.snippet | 28 ++++++++++ java24/Gatherers_B2.snippet | 21 ++++++++ java24/Gatherers_B3.snippet | 20 ++++++++ java24/Gatherers_B4.snippet | 20 ++++++++ java24/Gatherers_B5.snippet | 16 ++++++ java24/Gatherers_B6.snippet | 23 +++++++++ java24/Gatherers_B7.snippet | 24 +++++++++ java24/Gatherers_B8.snippet | 48 +++++++++++++++++ java24/Gatherers_B9.snippet | 25 +++++++++ java24/Gatherers_D1.snippet | 66 ++++++++++++++++++++++++ java24/Gatherers_D2.snippet | 71 ++++++++++++++++++++++++++ java24/Gatherers_D3.snippet | 22 ++++++++ java24/Gatherers_D4.snippet | 25 +++++++++ java24/StatementsBeforeSuper_1.snippet | 34 ++++++++++++ 26 files changed, 707 insertions(+) create mode 100644 java24/Gatherers_A1.snippet create mode 100644 java24/Gatherers_A2.snippet create mode 100644 java24/Gatherers_A3.snippet create mode 100644 java24/Gatherers_B1.snippet create mode 100644 java24/Gatherers_B10.snippet create mode 100644 java24/Gatherers_B11.snippet create mode 100644 java24/Gatherers_B12.snippet create mode 100644 java24/Gatherers_B13.snippet create mode 100644 java24/Gatherers_B14.snippet create mode 100644 java24/Gatherers_B15.snippet create mode 100644 java24/Gatherers_B16.snippet create mode 100644 java24/Gatherers_B17.snippet create mode 100644 java24/Gatherers_B18.snippet create mode 100644 java24/Gatherers_B2.snippet create mode 100644 java24/Gatherers_B3.snippet create mode 100644 java24/Gatherers_B4.snippet create mode 100644 java24/Gatherers_B5.snippet create mode 100644 java24/Gatherers_B6.snippet create mode 100644 java24/Gatherers_B7.snippet create mode 100644 java24/Gatherers_B8.snippet create mode 100644 java24/Gatherers_B9.snippet create mode 100644 java24/Gatherers_D1.snippet create mode 100644 java24/Gatherers_D2.snippet create mode 100644 java24/Gatherers_D3.snippet create mode 100644 java24/Gatherers_D4.snippet create mode 100644 java24/StatementsBeforeSuper_1.snippet diff --git a/java24/Gatherers_A1.snippet b/java24/Gatherers_A1.snippet new file mode 100644 index 0000000..de50f28 --- /dev/null +++ b/java24/Gatherers_A1.snippet @@ -0,0 +1,15 @@ +// Filtering Gatherer +var strings = List.of("one", "two", "three", "four", "five"); +Gatherer filtering = + Gatherer.of( + (_, element, downstream) -> { + if (element.length() > 3) { + return downstream.push(element); + } else { + return !downstream.isRejecting(); + } + }); +var result = strings.stream() + .gather(filtering) + .toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_A2.snippet b/java24/Gatherers_A2.snippet new file mode 100644 index 0000000..eea5534 --- /dev/null +++ b/java24/Gatherers_A2.snippet @@ -0,0 +1,9 @@ +// Mapping Gatherer +var strings = List.of("one", "two", "three", "four", "five"); +Gatherer mapping = + Gatherer.of( + (_, element, downstream) -> downstream.push(element.length())); +var result = strings.stream() + .gather(mapping) + .toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_A3.snippet b/java24/Gatherers_A3.snippet new file mode 100644 index 0000000..f6863fb --- /dev/null +++ b/java24/Gatherers_A3.snippet @@ -0,0 +1,19 @@ +// Flatmapping Gatherer +var strings = List.of("one", "two", "three", "four", "five"); +Gatherer flatMapping = + Gatherer.of( + (_, element, downstream) -> { + var chars = element.toCharArray(); + int index = 0; + boolean isRejecting = false; + do { + isRejecting = !downstream.push(Character.toString(chars[index])); + index++; + } while (index < chars.length && !isRejecting); + return !isRejecting; + }); +var result = strings.stream() + .gather(flatMapping) + .distinct() + .toList(); +System.out.println("result = " + result); \ No newline at end of file diff --git a/java24/Gatherers_B1.snippet b/java24/Gatherers_B1.snippet new file mode 100644 index 0000000..18a9305 --- /dev/null +++ b/java24/Gatherers_B1.snippet @@ -0,0 +1,21 @@ +// Map Filter Gatherer +static Gatherer mapFilter( + Function mapper, + Predicate filter) { + + return Gatherer.of( + (_, element, downstream) -> { + R mappedElement = mapper.apply(element); + if (filter.test(mappedElement)) { + return downstream.push(mappedElement); + } + return true; + } + ); +} + +var stream = Stream.of("one", "two", "three", "four", "five"); +var result = stream + .gather(mapFilter(String::length, length -> length > 3)) + .toList(); +System.out.println("result = " + result); \ No newline at end of file diff --git a/java24/Gatherers_B10.snippet b/java24/Gatherers_B10.snippet new file mode 100644 index 0000000..35e761f --- /dev/null +++ b/java24/Gatherers_B10.snippet @@ -0,0 +1,28 @@ +// Sort Distinct Parallel Gatherer +static Gatherer sortDistinctWithComparator(Comparator comparator) { + + return Gatherer.of( + () -> new TreeSet(comparator), + (list, element, _) -> { + list.add(element); + return true; + }, + (set1, set2) -> { + set1.addAll(set2); + return set1; + }, + (list, downstream) -> { + list.stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +static > Gatherer sortDistinct() { + return sortDistinctWithComparator(Comparator.naturalOrder()); +} + +var stream = Stream.of(3, 2, 4, 5, 3, 1, 2, 5, 4); +var result = stream.parallel().gather(sortDistinct()).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B11.snippet b/java24/Gatherers_B11.snippet new file mode 100644 index 0000000..cce269e --- /dev/null +++ b/java24/Gatherers_B11.snippet @@ -0,0 +1,17 @@ +// Distinct Ignore Case Gatherer +static Gatherer distinctIgnoreCase() { + + return Gatherer.ofSequential( + () -> new HashSet(), + (set, element, downstream) -> { + if (set.add(element.toLowerCase())) { + return downstream.push(element); + } + return true; + } + ); +} + +var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); +var result = stream.gather(distinctIgnoreCase()).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B12.snippet b/java24/Gatherers_B12.snippet new file mode 100644 index 0000000..37d3a6f --- /dev/null +++ b/java24/Gatherers_B12.snippet @@ -0,0 +1,25 @@ +// Distinct Ignore Case Gatherer +static Gatherer distinctIgnoreCase() { + + return Gatherer.of( + () -> new HashMap(), + (map, element, _) -> { + map.putIfAbsent(element.toLowerCase(), element); + return true; + }, + (map1, map2) -> { + map2.putAll(map1); + return map2; + }, + (map, downstream) -> { + map.values().stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); +var result = stream.gather(distinctIgnoreCase()).toList(); +System.out.println("result = " + result); + diff --git a/java24/Gatherers_B13.snippet b/java24/Gatherers_B13.snippet new file mode 100644 index 0000000..a360caf --- /dev/null +++ b/java24/Gatherers_B13.snippet @@ -0,0 +1,23 @@ +// Distinct Ignore Case With Comparator Gatherer +static Gatherer distinctIgnoreCase() { + + return Gatherer.ofSequential( + () -> new HashMap(), + (map, element, _) -> { + map.merge( + element.toLowerCase(), + element, + (e1, e2) -> e1.compareTo(e2) < 0 ? e1 : e2); + return true; + }, + (map, downstream) -> { + map.values().stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); +var result = stream.gather(distinctIgnoreCase()).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B14.snippet b/java24/Gatherers_B14.snippet new file mode 100644 index 0000000..495fb95 --- /dev/null +++ b/java24/Gatherers_B14.snippet @@ -0,0 +1,32 @@ +// Distinct Ignore Case With Comparator Parallel Gatherer +static Gatherer distinctIgnoreCase() { + + return Gatherer.of( + () -> new HashMap(), + (map, element, _) -> { + map.merge( + element.toLowerCase(), + element, + (e1, e2) -> e1.compareTo(e2) < 0 ? e1 : e2); + return true; + }, + (map1, map2) -> { + map2.forEach((key, value) -> + map1.merge( + key, + value, + (e1, e2) -> e1.compareTo(e2) < 0 ? e1 : e2)); + return map1; + }, + (map, downstream) -> { + map.values().stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); +var result = stream.parallel().gather(distinctIgnoreCase()).toList(); +System.out.println("result = " + result); + diff --git a/java24/Gatherers_B15.snippet b/java24/Gatherers_B15.snippet new file mode 100644 index 0000000..1591f01 --- /dev/null +++ b/java24/Gatherers_B15.snippet @@ -0,0 +1,21 @@ +// Custom Equal Gatherer +static Gatherer customEqual(Function equalMapper) { + + return Gatherer.ofSequential( + () -> new HashMap(), + (map, element, _) -> { + var key = equalMapper.apply(element); + map.putIfAbsent(key, element); + return true; + }, + (map, downstream) -> { + map.values().stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); +var result = stream.gather(customEqual(String::toLowerCase)).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B16.snippet b/java24/Gatherers_B16.snippet new file mode 100644 index 0000000..246c5b2 --- /dev/null +++ b/java24/Gatherers_B16.snippet @@ -0,0 +1,25 @@ +// Custom Equal Parallel Gatherer +static Gatherer customEqual(Function equalMapper) { + + return Gatherer.of( + () -> new HashMap(), + (map, element, _) -> { + var key = equalMapper.apply(element); + map.putIfAbsent(key, element); + return true; + }, + (map1, map2) -> { + map2.forEach(map1::putIfAbsent); + return map1; + }, + (map, downstream) -> { + map.values().stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); +var result = stream.parallel().gather(customEqual(String::toLowerCase)).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B17.snippet b/java24/Gatherers_B17.snippet new file mode 100644 index 0000000..c58b416 --- /dev/null +++ b/java24/Gatherers_B17.snippet @@ -0,0 +1,29 @@ +// Custom Equal Collecting Gatherer +static Gatherer customEqualCollecting( + Function equalMapper, + Collector collector) { + + return Gatherer.ofSequential( + () -> new HashMap>(), + (map, element, _) -> { + var key = equalMapper.apply(element); + map.computeIfAbsent(key, _ -> new ArrayList<>()).add(element); + return true; + }, + (map, downstream) -> { + map.values().stream() + .takeWhile(_ -> !downstream.isRejecting()) + .map(values -> values.stream().collect(collector)) + .forEach(downstream::push); + } + ); +} + + +var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo", "Three", "three"); +var result = + stream + .gather( + customEqualCollecting(String::toLowerCase, Collectors.toList())) + .toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B18.snippet b/java24/Gatherers_B18.snippet new file mode 100644 index 0000000..7d847be --- /dev/null +++ b/java24/Gatherers_B18.snippet @@ -0,0 +1,28 @@ +// Custom Equal Collecting Parallel Gatherer +static Gatherer customEqualCollecting( + Function equalMapper, + Collector collector) { + +return Gatherer.of( + () -> new HashMap>(), + (map, element, _) -> { + var key = equalMapper.apply(element); + map.computeIfAbsent(key, _ -> new ArrayList<>()).add(element); + return true; + }, + (map1, map2) -> { + map2.forEach((key, value) -> map1.merge(key, value, (v1, v2) -> { v1.addAll(v2); return v1; })); + return map1; + }, + (map, downstream) -> { + map.values().stream() + .takeWhile(_ -> !downstream.isRejecting()) + .map(values -> values.stream().collect(collector)) + .forEach(downstream::push); + } + ); +} + +var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo", "Three", "three"); +var result = stream.gather(customEqualCollecting(String::toLowerCase, Collectors.toList())).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B2.snippet b/java24/Gatherers_B2.snippet new file mode 100644 index 0000000..24b65c4 --- /dev/null +++ b/java24/Gatherers_B2.snippet @@ -0,0 +1,21 @@ +// Map Filter Parallel Gatherer +static Gatherer mapFilter( + Function mapper, + Predicate filter) { + + return Gatherer.of( + (_, element, downstream) -> { + R mappedElement = mapper.apply(element); + if (filter.test(mappedElement)) { + return downstream.push(mappedElement); + } + return true; + } + ); +} + +var stream = Stream.of("one", "two", "three", "four", "five"); +var result = stream.parallel() + .gather(mapFilter(String::length, length -> length > 3)) + .toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B3.snippet b/java24/Gatherers_B3.snippet new file mode 100644 index 0000000..cc08ed3 --- /dev/null +++ b/java24/Gatherers_B3.snippet @@ -0,0 +1,20 @@ +// Limit Gatherer +static Gatherer limit(long limit) { + return Gatherer.ofSequential( + () -> new Object() { + long counter = 0L; + }, + (counter, element, downstream) -> { + if (counter.counter >= limit) { + return false; + } else { + counter.counter++; + return downstream.push(element); + } + } + ); +} + +var stream = Stream.of(1, 2, 3, 4, 5); +var result = stream.gather(limit(3L)).toList(); +System.out.println("result = " + result); \ No newline at end of file diff --git a/java24/Gatherers_B4.snippet b/java24/Gatherers_B4.snippet new file mode 100644 index 0000000..858d592 --- /dev/null +++ b/java24/Gatherers_B4.snippet @@ -0,0 +1,20 @@ +// Limit Parallel Gatherer +static Gatherer limit(long limit) { + return Gatherer.ofSequential( + () -> new Object() { + long counter = 0L; + }, + (counter, element, downstream) -> { + if (counter.counter >= limit) { + return false; + } else { + counter.counter++; + return downstream.push(element); + } + } + ); +} + +var stream = Stream.of(1, 2, 3, 4, 5); +var result = stream.parallel().gather(limit(3L)).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B5.snippet b/java24/Gatherers_B5.snippet new file mode 100644 index 0000000..0559313 --- /dev/null +++ b/java24/Gatherers_B5.snippet @@ -0,0 +1,16 @@ +// Distinct Gatherer +static Gatherer distinct() { + return Gatherer.ofSequential( + () -> new HashSet(), + (set, element, downstream) -> { + if (set.add(element)) { + return downstream.push(element); + } + return true; + } + ); +} + +var stream = Stream.of(1, 1, 2, 2, 2, 3, 4, 4, 4, 5); +var result = stream.gather(distinct()).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B6.snippet b/java24/Gatherers_B6.snippet new file mode 100644 index 0000000..be2adc5 --- /dev/null +++ b/java24/Gatherers_B6.snippet @@ -0,0 +1,23 @@ +// Distinct Parallel Gatherer +static Gatherer distinct() { + return Gatherer.of( + () -> new HashSet(), + (set, element, _) -> { + set.add(element); + return true; + }, + (set1, set2) -> { + set1.addAll(set2); + return set1; + }, + (set, downstream) -> { + set.stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +var stream = Stream.of(1, 1, 2, 2, 2, 3, 4, 4, 4, 5); +var result = stream.parallel().gather(distinct()).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B7.snippet b/java24/Gatherers_B7.snippet new file mode 100644 index 0000000..d8b68c1 --- /dev/null +++ b/java24/Gatherers_B7.snippet @@ -0,0 +1,24 @@ +// Sort Gatherer +static Gatherer sortWithComparator(Comparator comparator) { + return Gatherer.ofSequential( + () -> new ArrayList(), + (list, element, _) -> { + list.add(element); + return true; + }, + (list, downstream) -> { + list.sort(comparator); + list.stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +static > Gatherer sort() { + return sortWithComparator(Comparator.naturalOrder()); +} + +var stream = Stream.of(3, 2, 4, 5, 3, 1, 2, 5, 4); +var result = stream.gather(sort()).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B8.snippet b/java24/Gatherers_B8.snippet new file mode 100644 index 0000000..51e101b --- /dev/null +++ b/java24/Gatherers_B8.snippet @@ -0,0 +1,48 @@ +// Sort Parallel Gatherer +static Gatherer sortWithComparator(Comparator comparator) { + + return Gatherer.of( + () -> new ArrayList(), + (list, element, _) -> { + list.add(element); + return true; + }, + (list1, list2) -> { + list1.sort(comparator); + list2.sort(comparator); + int initialCapacity = list1.size() + list2.size(); + var list3 = new ArrayList(initialCapacity); + for (int index1 = 0, index2 = 0, index3 = 0; index3 < initialCapacity; index3++) { + if (index1 < list1.size() && index2 < list2.size()) { + if (comparator.compare(list1.get(index1), list2.get(index2)) < 0) { + list3.add(list1.get(index1)); + index1++; + } else { + list3.add(list2.get(index2)); + index2++; + } + } else if (index1 < list1.size()) { + list3.add(list1.get(index1)); + index1++; + } else if (index2 < list2.size()) { + list3.add(list2.get(index2)); + index2++; + } + } + return list3; + }, + (list, downstream) -> { + list.stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +static > Gatherer sort() { + return sortWithComparator(Comparator.naturalOrder()); +} + +var stream = Stream.of(3, 2, 4, 5, 3, 1, 2, 5, 4); +var result = stream.parallel().gather(sort()).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_B9.snippet b/java24/Gatherers_B9.snippet new file mode 100644 index 0000000..96f3e55 --- /dev/null +++ b/java24/Gatherers_B9.snippet @@ -0,0 +1,25 @@ +// Sort Distinct Gatherer +static Gatherer sortDistinctWithComparator(Comparator comparator) { + + return Gatherer.ofSequential( + () -> new TreeSet(comparator), + (list, element, _) -> { + list.add(element); + return true; + }, + (list, downstream) -> { + list.stream() + .takeWhile(_ -> !downstream.isRejecting()) + .forEach(downstream::push); + } + ); +} + +static > Gatherer sortDistinct() { + return sortDistinctWithComparator(Comparator.naturalOrder()); +} + + +var stream = Stream.of(3, 2, 4, 5, 3, 1, 2, 5, 4); +var result = stream.gather(sortDistinct()).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_D1.snippet b/java24/Gatherers_D1.snippet new file mode 100644 index 0000000..7105d1d --- /dev/null +++ b/java24/Gatherers_D1.snippet @@ -0,0 +1,66 @@ +// Zipping Gatherer +static Gatherer zip( + Iterable iterable) { + + class State { + private final Iterator iterator; + private boolean nextIsElement = true; + private boolean hasNextElement = false; + private T element; + + State(Iterator iterator) { + this.iterator = iterator; + } + + boolean hasNext() { + if (nextIsElement) { + return hasNextElement; + } else { + return iterator.hasNext(); + } + } + + T next() { + if (nextIsElement) { + nextIsElement = false; + hasNextElement = false; + return element; + } else { + nextIsElement = true; + return iterator.next(); + } + } + + public void addElement(T element) { + this.element = element; + this.hasNextElement = true; + } + } + + return Gatherer.ofSequential( + () -> new State(iterable.iterator()), + (state, element, downstream) -> { + state.addElement(element); + if (state.hasNext()) { + boolean isRejecting = !downstream.push(state.next()); + if (isRejecting) { + return false; + } + } + if (state.hasNext()) { + boolean isRejecting = !downstream.push(state.next()); + if (isRejecting) { + return false; + } + } + return true; + } + ); +} + +var evens = List.of(0, 2, 4, 6, 8); +var odds = List.of(1, 3, 5); + +var result = evens.stream().gather(zip(odds::iterator)).toList(); +System.out.println("result = " + result); + diff --git a/java24/Gatherers_D2.snippet b/java24/Gatherers_D2.snippet new file mode 100644 index 0000000..5efcddd --- /dev/null +++ b/java24/Gatherers_D2.snippet @@ -0,0 +1,71 @@ +// Zipping With Default Value Gatherer +static Gatherer zip( + Iterable iterable, + T defaultValue) { + + class State { + private final Iterator iterator; + private boolean nextIsElement = true; + private boolean hasNextElement = false; + private T element; + + State(Iterator iterator) { + this.iterator = iterator; + } + + boolean hasNext() { + if (nextIsElement) { + return hasNextElement; + } else { + return true; + } + } + + T next() { + if (nextIsElement) { + nextIsElement = false; + hasNextElement = false; + return element; + } else { + nextIsElement = true; + if (iterator.hasNext()) { + return iterator.next(); + } else { + hasNextElement = false; + return defaultValue; + } + } + } + + public void addElement(T element) { + this.element = element; + this.hasNextElement = true; + } + } + + return Gatherer.ofSequential( + () -> new State(iterable.iterator()), + (state, element, downstream) -> { + state.addElement(element); + if (state.hasNext()) { + boolean isRejecting = !downstream.push(state.next()); + if (isRejecting) { + return false; + } + } + if (state.hasNext()) { + boolean isRejecting = !downstream.push(state.next()); + if (isRejecting) { + return false; + } + } + return true; + } + ); +} + +var evens = List.of("0", "2", "4", "6", "8"); +var odds = List.of("1", "3", "5"); + +var result = evens.stream().gather(zip(odds::iterator, "NO_VALUE")).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_D3.snippet b/java24/Gatherers_D3.snippet new file mode 100644 index 0000000..24ffe6f --- /dev/null +++ b/java24/Gatherers_D3.snippet @@ -0,0 +1,22 @@ +// Combining Gatherer +static Gatherer zip( + Iterable iterable, + BiFunction combiner) { + + return Gatherer.ofSequential( + iterable::iterator, + (iterator, element, downstream) -> { + if (iterator.hasNext()) { + var result = combiner.apply(element, iterator.next()); + return downstream.push(result); + } + return false; + } + ); +} + +var strings = List.of("one", "two", "three"); +var ints = List.of(1, 2, 3, 4, 5); + +var result = ints.stream().gather(zip(strings, (i, s) -> i + " -> " + s)).toList(); +System.out.println("result = " + result); diff --git a/java24/Gatherers_D4.snippet b/java24/Gatherers_D4.snippet new file mode 100644 index 0000000..c58e499 --- /dev/null +++ b/java24/Gatherers_D4.snippet @@ -0,0 +1,25 @@ +// Combining With Default Value Gatherer +static Gatherer zip( + Iterable iterable, + BiFunction combiner, + R defaultValue) { + + return Gatherer.ofSequential( + iterable::iterator, + (iterator, element, downstream) -> { + if (iterator.hasNext()) { + var result = combiner.apply(element, iterator.next()); + return downstream.push(result); + } else { + var result = combiner.apply(element, defaultValue); + return downstream.push(result); + } + } + ); +} + +var strings = List.of("one", "two", "three"); +var ints = List.of(1, 2, 3, 4, 5); + +var result = ints.stream().gather(zip(strings, (i, s) -> i + " -> " + s, "NO_VALUE")).toList(); +System.out.println("result = " + result); diff --git a/java24/StatementsBeforeSuper_1.snippet b/java24/StatementsBeforeSuper_1.snippet new file mode 100644 index 0000000..4d2a6ba --- /dev/null +++ b/java24/StatementsBeforeSuper_1.snippet @@ -0,0 +1,34 @@ +// Statement before super +static class Shape { + private String name; + public Shape(String name) { + if (name == null) { + throw new IllegalArgumentException("User should not be null"); + } + super(); + this.name = name; + } + public String name() { + return name; + } +} + +static class Square extends Shape { + private int edge; + public Square(int edge) { + if (edge <= 0) { + throw new IllegalArgumentException("Edge should be greater than 0"); + } + super("Square"); + this.edge = edge; + } + public int edge() { + return edge; + } + public String toString() { + return "Square[" + edge + "]"; + } +} + +Square square = new Square(100); +System.out.println("square = " + square); \ No newline at end of file From de3fe1ae435e8a4701b7046379dbb7e138efa113 Mon Sep 17 00:00:00 2001 From: David Delabassee Date: Mon, 20 Jan 2025 18:08:27 +0100 Subject: [PATCH 2/7] fix parallel --- java24/Gatherers_B12.snippet | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java24/Gatherers_B12.snippet b/java24/Gatherers_B12.snippet index 37d3a6f..a9e849a 100644 --- a/java24/Gatherers_B12.snippet +++ b/java24/Gatherers_B12.snippet @@ -1,4 +1,4 @@ -// Distinct Ignore Case Gatherer +// Distinct Ignore Case Parallel Gatherer static Gatherer distinctIgnoreCase() { return Gatherer.of( @@ -20,6 +20,6 @@ static Gatherer distinctIgnoreCase() { } var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); -var result = stream.gather(distinctIgnoreCase()).toList(); +var result = stream.parallel.gather(distinctIgnoreCase()).toList(); System.out.println("result = " + result); From 191f2b69458a3354f0fe96f3247f8cb837ceb343 Mon Sep 17 00:00:00 2001 From: David Delabassee Date: Mon, 20 Jan 2025 18:14:01 +0100 Subject: [PATCH 3/7] typo --- java24/Gatherers_B12.snippet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java24/Gatherers_B12.snippet b/java24/Gatherers_B12.snippet index a9e849a..76f2a83 100644 --- a/java24/Gatherers_B12.snippet +++ b/java24/Gatherers_B12.snippet @@ -20,6 +20,6 @@ static Gatherer distinctIgnoreCase() { } var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); -var result = stream.parallel.gather(distinctIgnoreCase()).toList(); +var result = stream.parallel().gather(distinctIgnoreCase()).toList(); System.out.println("result = " + result); From a8070ab6e9906c5baf65fc0a0dd7ce834a27b0b9 Mon Sep 17 00:00:00 2001 From: David Delabassee Date: Thu, 13 Mar 2025 12:46:59 +0100 Subject: [PATCH 4/7] minor cleanup --- java21/HelloWorld.snippet | 5 +++-- java21/Misc2.snippet | 2 +- java21/Misc3.snippet | 2 +- java21/PatternMathcing.snippet | 2 +- java21/Record_1.snippet | 2 +- java21/Record_2.snippet | 2 +- java21/Stream_2.snippet | 2 +- java21/Stream_3.snippet | 2 +- java21/Switch_1.snippet | 2 +- java21/Switch_2.snippet | 1 + java21/Textblock_1.snippet | 2 +- java21/Textblock_2.snippet | 2 +- java21/Textblock_3.snippet | 1 + java22/Gatherers_1.snippet | 2 +- java22/Gatherers_5.snippet | 2 +- java22/Gatherers_6.snippet | 2 +- java22/StatementsBeforeSuper_1.snippet | 2 +- java22/String_template_1.snippet | 1 - java22/String_template_2.snippet | 1 - java22/String_template_3.snippet | 1 - java22/String_template_4.snippet | 1 - java22/String_template_5.snippet | 1 - java22/Switch_on_Sealled_Types_1.snippet | 1 - java22/Switch_on_Sealled_Types_2.snippet | 1 - java22/Switch_on_Sealled_Types_3.snippet | 2 +- java22/Switch_on_Sealled_Types_4.snippet | 2 +- java22/Switch_on_Sealled_Types_5.snippet | 2 +- java22/Unamed_Pattern_4.snippet | 2 +- java24/Gatherers_A3.snippet | 2 +- java24/Gatherers_B1.snippet | 2 +- java24/Gatherers_B12.snippet | 1 - java24/Gatherers_B3.snippet | 2 +- java24/Gatherers_D1.snippet | 1 - java24/StatementsBeforeSuper_1.snippet | 2 +- 34 files changed, 27 insertions(+), 33 deletions(-) diff --git a/java21/HelloWorld.snippet b/java21/HelloWorld.snippet index 7e02fe1..6e9fd5a 100644 --- a/java21/HelloWorld.snippet +++ b/java21/HelloWorld.snippet @@ -1,2 +1,3 @@ -var name = "Duke"; -System.out.println("👋 Hello, " + name); +var version = Runtime.version().major(); +println("👋 Hello, Java " + version); + diff --git a/java21/Misc2.snippet b/java21/Misc2.snippet index 1735ff6..715a600 100644 --- a/java21/Misc2.snippet +++ b/java21/Misc2.snippet @@ -4,4 +4,4 @@ numbers.add("one"); numbers.add("two"); numbers.add("three"); numbers.remove("two"); -System.out.println(numbers); \ No newline at end of file +System.out.println(numbers); diff --git a/java21/Misc3.snippet b/java21/Misc3.snippet index 83bbe5a..5be33d7 100644 --- a/java21/Misc3.snippet +++ b/java21/Misc3.snippet @@ -7,4 +7,4 @@ Function handleNullThenLength = handleNull.andThen(length); for (String string : strings) { System.out.println(string + " -> length = " + handleNullThenLength.apply(string)); -} \ No newline at end of file +} diff --git a/java21/PatternMathcing.snippet b/java21/PatternMathcing.snippet index d48955d..e03f2b4 100644 --- a/java21/PatternMathcing.snippet +++ b/java21/PatternMathcing.snippet @@ -12,4 +12,4 @@ Point p3 = new Point(0, 0); System.out.println("p1 equals object? " + p1.equals(new Object())); System.out.println("p1 equals p2? " + p1.equals(p2)); System.out.println("p1 equals p3? " + p1.equals(p3)); -System.out.println("p2 equals p3? " + p2.equals(p3)); \ No newline at end of file +System.out.println("p2 equals p3? " + p2.equals(p3)); diff --git a/java21/Record_1.snippet b/java21/Record_1.snippet index 3b8cc0d..c869334 100644 --- a/java21/Record_1.snippet +++ b/java21/Record_1.snippet @@ -1,4 +1,4 @@ // Simple record record Player(String last, String first, int level) {} var jane = new Player("Doe", "Jane", 42); -System.out.println(jane); \ No newline at end of file +System.out.println(jane); diff --git a/java21/Record_2.snippet b/java21/Record_2.snippet index c69a5ff..0ccd244 100644 --- a/java21/Record_2.snippet +++ b/java21/Record_2.snippet @@ -9,4 +9,4 @@ record City(String name, Population population) { } var paris = City.of("Paris", 2_161); -System.out.println(paris); \ No newline at end of file +System.out.println(paris); diff --git a/java21/Stream_2.snippet b/java21/Stream_2.snippet index 782886e..8a39084 100644 --- a/java21/Stream_2.snippet +++ b/java21/Stream_2.snippet @@ -2,4 +2,4 @@ Stream stream = Stream.of("Shenzhen", "Brussels", "Taipei", "Buenos Aire List cities = stream.sorted().collect(Collectors.toList()); -System.out.println(cities); \ No newline at end of file +System.out.println(cities); diff --git a/java21/Stream_3.snippet b/java21/Stream_3.snippet index 2e461c1..efa872e 100644 --- a/java21/Stream_3.snippet +++ b/java21/Stream_3.snippet @@ -8,4 +8,4 @@ var cities = """ Stream lines = cities.lines(); -System.out.println(lines.toList()); \ No newline at end of file +System.out.println(lines.toList()); diff --git a/java21/Switch_1.snippet b/java21/Switch_1.snippet index 68c210f..8aecbee 100644 --- a/java21/Switch_1.snippet +++ b/java21/Switch_1.snippet @@ -9,4 +9,4 @@ int numLetters = switch (day) { case WEDNESDAY -> 9; }; -System.out.println(numLetters); \ No newline at end of file +System.out.println(numLetters); diff --git a/java21/Switch_2.snippet b/java21/Switch_2.snippet index 84f9c09..243070e 100644 --- a/java21/Switch_2.snippet +++ b/java21/Switch_2.snippet @@ -20,3 +20,4 @@ switch(Day.MONDAY) { } System.out.println(numberOfChar); + diff --git a/java21/Textblock_1.snippet b/java21/Textblock_1.snippet index 4097981..df7a48c 100644 --- a/java21/Textblock_1.snippet +++ b/java21/Textblock_1.snippet @@ -1,4 +1,4 @@ var message = """ {"name" : "%s", "language" : "Java"} """; -System.out.println(message.formatted("Duke")); \ No newline at end of file +System.out.println(message.formatted("Duke")); diff --git a/java21/Textblock_2.snippet b/java21/Textblock_2.snippet index ce25746..facc1e6 100644 --- a/java21/Textblock_2.snippet +++ b/java21/Textblock_2.snippet @@ -9,4 +9,4 @@ var cities = """ Stream lines = cities.lines(); -System.out.println(lines.toList()); \ No newline at end of file +System.out.println(lines.toList()); diff --git a/java21/Textblock_3.snippet b/java21/Textblock_3.snippet index 100288b..841d7d7 100644 --- a/java21/Textblock_3.snippet +++ b/java21/Textblock_3.snippet @@ -8,3 +8,4 @@ String cities = """ """; cities.lines().map(line -> "|" + line + "|").forEach(System.out::println); + diff --git a/java22/Gatherers_1.snippet b/java22/Gatherers_1.snippet index 79d3bd0..d176eb2 100644 --- a/java22/Gatherers_1.snippet +++ b/java22/Gatherers_1.snippet @@ -5,4 +5,4 @@ Gatherer> fixedWindow = var result = strings.stream() .gather(fixedWindow) .toList(); -System.out.println("result = " + result); \ No newline at end of file +System.out.println("result = " + result); diff --git a/java22/Gatherers_5.snippet b/java22/Gatherers_5.snippet index b951651..8df9bb5 100644 --- a/java22/Gatherers_5.snippet +++ b/java22/Gatherers_5.snippet @@ -9,4 +9,4 @@ Gatherer slideThenSum = var result = strings.stream() .gather(slideThenSum) .toList(); -System.out.println("result = " + result); \ No newline at end of file +System.out.println("result = " + result); diff --git a/java22/Gatherers_6.snippet b/java22/Gatherers_6.snippet index 93e0593..7055790 100644 --- a/java22/Gatherers_6.snippet +++ b/java22/Gatherers_6.snippet @@ -15,4 +15,4 @@ Gatherer smoothOnASlidingWindow = var result = strings.stream() .gather(smoothOnASlidingWindow) .toList(); -System.out.println("result = " + result); \ No newline at end of file +System.out.println("result = " + result); diff --git a/java22/StatementsBeforeSuper_1.snippet b/java22/StatementsBeforeSuper_1.snippet index 40d03f7..91e1678 100644 --- a/java22/StatementsBeforeSuper_1.snippet +++ b/java22/StatementsBeforeSuper_1.snippet @@ -31,4 +31,4 @@ static class Square extends Shape { } Square square = new Square(100); -System.out.println("square = " + square); \ No newline at end of file +System.out.println("square = " + square); diff --git a/java22/String_template_1.snippet b/java22/String_template_1.snippet index 543353a..aa74d02 100644 --- a/java22/String_template_1.snippet +++ b/java22/String_template_1.snippet @@ -12,4 +12,3 @@ var objects = objects.stream() .map(Point::toJson) .forEach(System.out::println); - diff --git a/java22/String_template_2.snippet b/java22/String_template_2.snippet index 87a25ed..89de523 100644 --- a/java22/String_template_2.snippet +++ b/java22/String_template_2.snippet @@ -21,4 +21,3 @@ var objects = new Point(1, 1), new Circle(new Point(1, 2), 3)); objects.forEach(element -> System.out.println(jsonOf(element))); - diff --git a/java22/String_template_3.snippet b/java22/String_template_3.snippet index 659e07f..c63f784 100644 --- a/java22/String_template_3.snippet +++ b/java22/String_template_3.snippet @@ -20,4 +20,3 @@ var products = List.of( products.stream() .map(product -> format(product)) .forEach(System.out::println); - diff --git a/java22/String_template_4.snippet b/java22/String_template_4.snippet index e95e7be..db7224d 100644 --- a/java22/String_template_4.snippet +++ b/java22/String_template_4.snippet @@ -29,4 +29,3 @@ var rentals = List.of( rentals.stream() .map(rental -> format(rental)) .forEach(System.out::println); - diff --git a/java22/String_template_5.snippet b/java22/String_template_5.snippet index 277bb68..922a2aa 100644 --- a/java22/String_template_5.snippet +++ b/java22/String_template_5.snippet @@ -19,4 +19,3 @@ var result1 = SIMPLE_PRINT."\{strings.get(0)}"; System.out.println("Result 1 = " + result1); var result2 = SIMPLE_PRINT."\{strings.get(0)} \{strings.get(1)}"; System.out.println("Result 2 = " + result2); - diff --git a/java22/Switch_on_Sealled_Types_1.snippet b/java22/Switch_on_Sealled_Types_1.snippet index 4ebe09e..1248584 100644 --- a/java22/Switch_on_Sealled_Types_1.snippet +++ b/java22/Switch_on_Sealled_Types_1.snippet @@ -46,4 +46,3 @@ var shapes = List.of(s0, s1, s2, s3, r0, r1, r2, r3, r4, c1, c2); shapes.stream() .map(toString) .forEach(System.out::println); - diff --git a/java22/Switch_on_Sealled_Types_2.snippet b/java22/Switch_on_Sealled_Types_2.snippet index 5edb966..3c9c453 100644 --- a/java22/Switch_on_Sealled_Types_2.snippet +++ b/java22/Switch_on_Sealled_Types_2.snippet @@ -47,4 +47,3 @@ var shapes = List.of(s0, s1, s2, s3, r0, r1, r2, r3, r4, c1, c2); shapes.stream() .map(toString) .forEach(System.out::println); - diff --git a/java22/Switch_on_Sealled_Types_3.snippet b/java22/Switch_on_Sealled_Types_3.snippet index 72719ec..b108f53 100644 --- a/java22/Switch_on_Sealled_Types_3.snippet +++ b/java22/Switch_on_Sealled_Types_3.snippet @@ -45,4 +45,4 @@ Circle c2 = new Circle(new Point(2d, 3d), 2d); var shapes = List.of(s0, s1, s2, s3, r0, r1, r2, r3, r4, c1, c2); shapes.stream() .map(toString) - .forEach(System.out::println); \ No newline at end of file + .forEach(System.out::println); diff --git a/java22/Switch_on_Sealled_Types_4.snippet b/java22/Switch_on_Sealled_Types_4.snippet index b004a72..c1a86d7 100644 --- a/java22/Switch_on_Sealled_Types_4.snippet +++ b/java22/Switch_on_Sealled_Types_4.snippet @@ -43,4 +43,4 @@ Circle c2 = new Circle(new Point(2d, 3d), 2d); var shapes = List.of(s0, s1, s2, s3, r0, r1, r2, r3, r4, c1, c2); shapes.stream() .map(toString) - .forEach(System.out::println); \ No newline at end of file + .forEach(System.out::println); diff --git a/java22/Switch_on_Sealled_Types_5.snippet b/java22/Switch_on_Sealled_Types_5.snippet index ebffca4..780e909 100644 --- a/java22/Switch_on_Sealled_Types_5.snippet +++ b/java22/Switch_on_Sealled_Types_5.snippet @@ -52,4 +52,4 @@ Circle c2 = new Circle(new Point(2d, 3d), 2d); var shapes = List.of(s0, s1, s2, s3, r0, r1, r2, r3, r4, c1, c2); shapes.stream() .map(toString) - .forEach(System.out::println); \ No newline at end of file + .forEach(System.out::println); diff --git a/java22/Unamed_Pattern_4.snippet b/java22/Unamed_Pattern_4.snippet index aa84f84..a4fd991 100644 --- a/java22/Unamed_Pattern_4.snippet +++ b/java22/Unamed_Pattern_4.snippet @@ -46,4 +46,4 @@ System.out.println("Are the following natural integers?"); operations.forEach(operation -> { System.out.println(operation + ( naturalNumber(operation) ? " = " + resolve(operation): " -> result is not a natural integer")); -}); \ No newline at end of file +}); diff --git a/java24/Gatherers_A3.snippet b/java24/Gatherers_A3.snippet index f6863fb..75beaef 100644 --- a/java24/Gatherers_A3.snippet +++ b/java24/Gatherers_A3.snippet @@ -16,4 +16,4 @@ var result = strings.stream() .gather(flatMapping) .distinct() .toList(); -System.out.println("result = " + result); \ No newline at end of file +System.out.println("result = " + result); diff --git a/java24/Gatherers_B1.snippet b/java24/Gatherers_B1.snippet index 18a9305..f4271df 100644 --- a/java24/Gatherers_B1.snippet +++ b/java24/Gatherers_B1.snippet @@ -18,4 +18,4 @@ var stream = Stream.of("one", "two", "three", "four", "five"); var result = stream .gather(mapFilter(String::length, length -> length > 3)) .toList(); -System.out.println("result = " + result); \ No newline at end of file +System.out.println("result = " + result); diff --git a/java24/Gatherers_B12.snippet b/java24/Gatherers_B12.snippet index 76f2a83..f8f0e7f 100644 --- a/java24/Gatherers_B12.snippet +++ b/java24/Gatherers_B12.snippet @@ -22,4 +22,3 @@ static Gatherer distinctIgnoreCase() { var stream = Stream.of("one", "One", "ONE", "Two", "two", "tWo"); var result = stream.parallel().gather(distinctIgnoreCase()).toList(); System.out.println("result = " + result); - diff --git a/java24/Gatherers_B3.snippet b/java24/Gatherers_B3.snippet index cc08ed3..ab1c3f6 100644 --- a/java24/Gatherers_B3.snippet +++ b/java24/Gatherers_B3.snippet @@ -17,4 +17,4 @@ static Gatherer limit(long limit) { var stream = Stream.of(1, 2, 3, 4, 5); var result = stream.gather(limit(3L)).toList(); -System.out.println("result = " + result); \ No newline at end of file +System.out.println("result = " + result); diff --git a/java24/Gatherers_D1.snippet b/java24/Gatherers_D1.snippet index 7105d1d..d1fc6b9 100644 --- a/java24/Gatherers_D1.snippet +++ b/java24/Gatherers_D1.snippet @@ -63,4 +63,3 @@ var odds = List.of(1, 3, 5); var result = evens.stream().gather(zip(odds::iterator)).toList(); System.out.println("result = " + result); - diff --git a/java24/StatementsBeforeSuper_1.snippet b/java24/StatementsBeforeSuper_1.snippet index 4d2a6ba..21dcf15 100644 --- a/java24/StatementsBeforeSuper_1.snippet +++ b/java24/StatementsBeforeSuper_1.snippet @@ -31,4 +31,4 @@ static class Square extends Shape { } Square square = new Square(100); -System.out.println("square = " + square); \ No newline at end of file +System.out.println("square = " + square); From c6c1cbdbd78af2868b04d05ffd5295edbcc5b158 Mon Sep 17 00:00:00 2001 From: David Delabassee Date: Thu, 13 Mar 2025 12:47:48 +0100 Subject: [PATCH 5/7] minor cleanup --- java21/HelloWorld.snippet | 1 - 1 file changed, 1 deletion(-) diff --git a/java21/HelloWorld.snippet b/java21/HelloWorld.snippet index 6e9fd5a..bacb11a 100644 --- a/java21/HelloWorld.snippet +++ b/java21/HelloWorld.snippet @@ -1,3 +1,2 @@ var version = Runtime.version().major(); println("👋 Hello, Java " + version); - From 908db8c09747a07807612375085281d8731ee838 Mon Sep 17 00:00:00 2001 From: David Delabassee Date: Tue, 25 Mar 2025 20:51:17 +0100 Subject: [PATCH 6/7] removing deprecated method usage --- java21/HelloWorld.snippet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java21/HelloWorld.snippet b/java21/HelloWorld.snippet index bacb11a..537e9a3 100644 --- a/java21/HelloWorld.snippet +++ b/java21/HelloWorld.snippet @@ -1,2 +1,2 @@ -var version = Runtime.version().major(); +var version = Runtime.version().feature(); println("👋 Hello, Java " + version); From c6577f1b88c258fa399b50e21e33a5fed3495b59 Mon Sep 17 00:00:00 2001 From: David Delabassee Date: Fri, 4 Jul 2025 18:19:37 +0200 Subject: [PATCH 7/7] Inital commit of JDK 25 snippets --- java25/FlexibleConstructorBodies_1.snippet | 67 +++++ java25/PrimitiveTypePatterns_1.snippet | 284 +++++++++++++++++++++ java25/ScopedValues_1.snippet | 27 ++ java25/StableValues_1.snippet | 168 ++++++++++++ 4 files changed, 546 insertions(+) create mode 100644 java25/FlexibleConstructorBodies_1.snippet create mode 100644 java25/PrimitiveTypePatterns_1.snippet create mode 100644 java25/ScopedValues_1.snippet create mode 100644 java25/StableValues_1.snippet diff --git a/java25/FlexibleConstructorBodies_1.snippet b/java25/FlexibleConstructorBodies_1.snippet new file mode 100644 index 0000000..d07c3e3 --- /dev/null +++ b/java25/FlexibleConstructorBodies_1.snippet @@ -0,0 +1,67 @@ +// Flexible Constructor Bodies +// Null Final Field +class A { + A() { + a(); + } + + void a() { + IO.println("This is A"); + } +} + +class B extends A { + private final String message ; + + B(String message) { + this.message = message; + } + + void a() { + IO.println(message); + } +} + +var a = new A(); +var b = new B("This is B"); + + + +// Snippet 2 +// Title: Flexible Constructor Body + +class Shape { + private String name; + public Shape(String name) { + IO.println("Trying to create a shape: " + name); + if (name == null) { + throw new IllegalArgumentException("Name should not be null"); + } + super(); + this.name = name; + } + public String name() { + return name; + } +} + +class Square extends Shape { + private int edge; + public Square(int edge) { + if (edge <= 0) { + throw new IllegalArgumentException("Edge should be greater than 0"); + } + super("Square"); + this.edge = edge; + } + public int edge() { + return edge; + } + public String toString() { + return "Square[" + edge + "]"; + } +} + +var square = new Square(100); +IO.println("square = " + square); +var invalidSquare = new Square(-100); \ No newline at end of file diff --git a/java25/PrimitiveTypePatterns_1.snippet b/java25/PrimitiveTypePatterns_1.snippet new file mode 100644 index 0000000..09822c7 --- /dev/null +++ b/java25/PrimitiveTypePatterns_1.snippet @@ -0,0 +1,284 @@ +// Primitive Type Patterns +// Primitive Pattern Matching for InstanceOf +record JsonDouble(double d) {} +record JsonFloat(float f) {} +record JsonLong(long i) {} +record JsonInt(int i) {} + +void analyze(Object o) { + if (o instanceof JsonDouble(double d)) { + IO.println("o is wrapping a double " + d); + } else if (o instanceof JsonLong(long l)) { + IO.println("o is wrapping a long " + l); + } else if (o instanceof JsonInt(int i)) { + IO.println("o is wrapping an int " + i); + } else { + IO.println("Unrecognized wrapper " + o); + } +} + +var jsonDouble = new JsonDouble(Math.PI); +analyze(jsonDouble); +var jsonFloat = new JsonFloat((float)Math.PI); +analyze(jsonFloat); +var jsonLong = new JsonLong(314L); +analyze(jsonLong); +var jsonInt = new JsonInt(31); +analyze(jsonInt); + + +// Snippet 2 +// Title: Primitive Pattern Matching for Switch +sealed interface JsonNumber permits + JsonDouble, JsonFloat, JsonLong, JsonInt {} +record JsonDouble(double d) implements JsonNumber {} +record JsonFloat(float f) implements JsonNumber {} +record JsonLong(long i) implements JsonNumber {} +record JsonInt(int i) implements JsonNumber {} + +void analyze(JsonNumber jsonNumber) { + switch(jsonNumber) { + case JsonDouble(double d) -> IO.println("Double: " + d); + case JsonFloat(float f) -> IO.println("Float: " + f); + case JsonLong(long l) -> IO.println("Long: " + l); + case JsonInt(int i) -> IO.println("Int: " + i); + } +} + +JsonNumber jsonNumber = new JsonDouble(Math.PI); +analyze(jsonNumber); +jsonNumber = new JsonFloat((float)Math.PI); +analyze(jsonNumber); +jsonNumber = new JsonLong(314L); +analyze(jsonNumber); +jsonNumber = new JsonInt(31); +analyze(jsonNumber); + + +// Snippet 3 +// Title: Narrowing Integer Number Primitive Pattern +sealed interface JsonNumber + permits JsonLong, JsonInt, JsonChar, JsonByte {} +record JsonLong(long l) implements JsonNumber {} +record JsonInt(int i) implements JsonNumber {} +record JsonChar(char i) implements JsonNumber {} +record JsonByte(byte i) implements JsonNumber {} + +JsonNumber narrow(long number) { + return switch (number) { + case byte b -> new JsonByte(b); + case char c -> new JsonChar(c); + case int i -> new JsonInt(i); + case long l -> new JsonLong(l); + }; +} + +IO.println("Narrowing to byte " + narrow(10L)); +IO.println("Narrowing to char " + narrow(200L)); +IO.println("Narrowing to int " + narrow(0x80000)); +IO.println("Not narrowing " + narrow(0x80000000L)); + + +// Snippet 4 +// Title: Narrowing Floating Point Number Primitive Pattern +sealed interface JsonNumber + permits JsonDouble, JsonFloat {} +record JsonDouble(double d) implements JsonNumber {} +record JsonFloat(float f) implements JsonNumber {} + +JsonNumber narrow(double number) { + return switch (number) { + case float f -> new JsonFloat(f); + case double d -> new JsonDouble(d); + }; +} + +IO.println("Narrowing to float " + narrow(3.0d)); +IO.println("Not Narrowing " + narrow(3.14d)); +IO.println("Not Narrowing " + narrow(Math.PI)); + + +// Snippet 5 +// Title: Integer Number to Floating Point Number Primitive Pattern +sealed interface JsonNumber + permits JsonDouble, JsonFloat, JsonInt {} +record JsonDouble(double d) implements JsonNumber {} +record JsonFloat(float f) implements JsonNumber {} +record JsonInt(int i) implements JsonNumber {} + +JsonNumber narrow(int number) { + return switch (number) { + case float f -> new JsonFloat(f); + case double d -> new JsonDouble(d); + }; +} + +IO.println("Int to float: " + narrow(10)); +IO.println("Int to double: " + narrow(0x1000001)); + + +// Snippet 6 +// Title: Floating Point Number to Integer Number Primitive Pattern +sealed interface JsonNumber + permits JsonDouble, JsonFloat, JsonInt, JsonByte {} +record JsonDouble(double d) implements JsonNumber {} +record JsonFloat(float f) implements JsonNumber {} +record JsonInt(int i) implements JsonNumber {} +record JsonByte(byte b) implements JsonNumber {} + +JsonNumber narrow(float number) { + return switch (number) { + case byte b -> new JsonByte(b); + case int i -> new JsonInt(i); + case float f -> new JsonFloat(f); + }; +} + +IO.println("Float to byte: " + narrow(10f)); +IO.println("Float to int: " + narrow(1_000f)); +IO.println("Cant convert: " + narrow(3.14f)); + + +// Snippet 7 +// Title: Double Number to Integer Number Primitive Pattern +sealed interface JsonNumber + permits JsonDouble, JsonLong, JsonInt, JsonByte {} +record JsonDouble(double d) implements JsonNumber {} +record JsonLong(long l) implements JsonNumber {} +record JsonInt(int i) implements JsonNumber {} +record JsonByte(byte b) implements JsonNumber {} + +JsonNumber narrow(double number) { + return switch (number) { + case byte b -> new JsonByte(b); + case int i -> new JsonInt(i); + case long l -> new JsonLong(l); + case double d -> new JsonDouble(d); + }; +} + +IO.println("Double to byte: " + narrow(10d)); +IO.println("Double to int: " + narrow(1_000d)); +IO.println("Double to long: " + narrow(8_000_000_000d)); +IO.println("Cant convert: " + narrow(3.14d)); + + +// Snippet 8 +// Title: Boolean Primitive Pattern +sealed interface JsonBoolean + permits JsonTrue, JsonFalse {} +record JsonTrue() implements JsonBoolean {} +record JsonFalse() implements JsonBoolean {} + +JsonBoolean box(boolean value) { + return switch (value) { + case true -> new JsonTrue(); + case false -> new JsonFalse(); + }; +} + +IO.println("Boxing true: " + box(true)); +IO.println("Boxing false: " + box(false)); + + +// Snippet 9 +// Title: Double Primitive Pattern +sealed interface JsonDouble + permits JsonZero, JsonNegative, JsonPositive {} +record JsonZero() implements JsonDouble {} +record JsonPositive() implements JsonDouble {} +record JsonNegative() implements JsonDouble {} + +JsonDouble box(double value) { + return switch (value) { + case 0d -> new JsonZero(); + case double v when v > 0d -> new JsonPositive(); + case double v -> new JsonNegative(); + }; +} + +IO.println("Boxing 0d: " + box(0d)); +IO.println("Boxing 10d: " + box(10d)); +IO.println("Boxing -10d: " + box(-10d)); + + + + +// Snippet 10 +// Title: JSON Analysis +sealed interface JsonValue { + Pattern pattern = Pattern.compile(""" + ^\\s*\\{\\s*"(?\\w*)"\\s*:\\s*"(?\\w*)"\\s*,\\s*"(?\\w*)"\\s*:\\s*(?\\d*.\\d*)\\s*}\\s*$"""); + + static JsonValue of(String json) { + var matcher = pattern.matcher(json); + if (!matcher.matches()) { + throw new IllegalArgumentException("invalid json"); + } + var map = new HashMap(); + var k1 = matcher.group("k1"); + var v1 = matcher.group("v1"); + var jsonString = new JsonString(v1); + map.put(k1, jsonString); + var k2 = matcher.group("k2"); + var v2 = matcher.group("v2"); + var jsonNumber = new JsonNumber(Double.parseDouble(v2)); + map.put(k2, jsonNumber); + + return new JsonObject(map); + } + + record JsonString(String s) implements JsonValue {} + record JsonNumber(double d) implements JsonValue {} + record JsonObject(Map map) implements JsonValue {} +} + + +record User(String name, int age) { + public User { + Objects.requireNonNull(name); + if (age < 0 || age > 130) { + throw new IllegalArgumentException("age must be between 0 and 130"); + } + } + + static User of(JsonValue jsonValue) { + if (jsonValue instanceof JsonValue.JsonObject(var map) && + map.get("name") instanceof JsonValue.JsonString(var name) && + map.get("age") instanceof JsonValue.JsonNumber(int age)) { + return new User(name, age); + } else { + if (jsonValue instanceof JsonValue.JsonObject(var map) + && !(map.get("age") instanceof JsonValue.JsonNumber(int _))) { + throw new IllegalArgumentException("Invalid age in Json: " + map.get("age")); + } else { + throw new IllegalArgumentException("Invalid JsonValue: " + jsonValue); + } + } + } +} + + +var jsonMary = """ + { + "name": "Mary", + "age": 27 + } + """; + +var jsonJohn = """ + { + "name": "John", + "age": 23.5 + } + """; + +var jsonValue = JsonValue.of(jsonMary); +var mary = User.of(jsonValue); +IO.println(mary); + +jsonValue = JsonValue.of(jsonJohn); +var john = User.of(jsonValue); + + + diff --git a/java25/ScopedValues_1.snippet b/java25/ScopedValues_1.snippet new file mode 100644 index 0000000..42ad079 --- /dev/null +++ b/java25/ScopedValues_1.snippet @@ -0,0 +1,27 @@ +// Scoped Values +// Setting Scoped Values +ScopedValue MESSAGE = ScopedValue.newInstance(); + +void anyMethod() { + if (MESSAGE.isBound()) { + IO.println(" Message = " + MESSAGE.get()); + } else { + IO.println(" Message is not bound"); + } +} + +void rebindingMethod() { + anyMethod(); + ScopedValue.where(MESSAGE, "I am rebound") + .run(() -> anyMethod()); +} + +Runnable task = () -> anyMethod(); +Runnable rebindingTask = () -> rebindingMethod(); +IO.println("Running a method without binding"); +task.run(); +IO.println("Running a method with a binding"); +ScopedValue.where(MESSAGE, "I am bound").run(task); +IO.println("Running a method with a rebinding"); +ScopedValue.where(MESSAGE, "I am bound").run(rebindingTask); + diff --git a/java25/StableValues_1.snippet b/java25/StableValues_1.snippet new file mode 100644 index 0000000..650bccb --- /dev/null +++ b/java25/StableValues_1.snippet @@ -0,0 +1,168 @@ +// Stable Values +// Static Initializers +class ConstantsWithStaticInitializers { + + static String message1 = init1(); + static String message2 = init2(); + + static String init1() { + IO.println("I am initializing message 1"); + return "Message 1"; + } + + static String init2() { + IO.println("I am initializing message 2"); + return "Message 2"; + } + + String message() { + return "I actually don't use these static elements"; + } +} + +var initStaticStuff = new ConstantsWithStaticInitializers(); +IO.println(initStaticStuff.message()); + + +// Snippet 2 +// Title: Enum Initializers +enum ConstantsWithEnum { + MESSAGE_1("Message 1"), MESSAGE2("Message 2"); + + private final String message; + + ConstantsWithEnum(String message) { + this.message = message; + IO.println("I am initializing " + message); + } + + public String message() { + return this.message; + } +} + +IO.println("I am using only " + ConstantsWithEnum.MESSAGE_1.message()); +IO.println("But the other has also been initialized"); + + +// Snippet 3 +// Title: Stable Values with Suppliers +class StableValuesWithSuppliers { + static Supplier MESSAGE_1 = StableValue.supplier(() -> { + IO.println("I am initializing MESSAGE_1"); + return "Message 1"; + }); + static Supplier MESSAGE_2 = StableValue.supplier(() -> { + IO.println("I am initializing MESSAGE_1"); + return "Message 2"; + }); +} + +IO.println("I am using MESSAGE_1 from its supplier " + StableValuesWithSuppliers.MESSAGE_1.get()); +IO.println("I am using MESSAGE_2 from its supplier " + StableValuesWithSuppliers.MESSAGE_2.get()); +IO.println("I am using MESSAGE_1 again: " + StableValuesWithSuppliers.MESSAGE_1.get()); +IO.println("I am using MESSAGE_2 again: " + StableValuesWithSuppliers.MESSAGE_2.get()); + + +// Snippet 4 +// Title: Stable Values with factories +class StableValuesWithFactories { + static StableValue MESSAGE_1 = StableValue.of(); + static StableValue MESSAGE_2 = StableValue.of(); + + static String message1() { + return MESSAGE_1.orElseSet(() -> { + IO.println("I am initializing MESSAGE_1"); + return "Message 1"; + }); + } + + static String message2() { + return MESSAGE_2.orElseSet(() -> { + IO.println("I am initializing MESSAGE_2"); + return "Message 2"; + }); + } +} + +IO.println("I am using only " + StableValuesWithFactories.message1()); +IO.println("Now I am also using " + StableValuesWithFactories.message2()); +IO.println("I am using MESSAGE_1 again: " + StableValuesWithFactories.message1()); +IO.println("I am using MESSAGE_2 again: " + StableValuesWithFactories.message2()); + + +// Snippet 5 +// Title: Stable Values as Lists +class StableValueAsLists { + static List LIST = StableValue.list(10, index -> { + IO.println("Initializing element at index " + index); + return "Element " + index; + }); +} + +IO.println("Size of LIST: " + StableValueAsLists.LIST.size()); +IO.println("Element at index 3 " + StableValueAsLists.LIST.get(3)); +IO.println("Element at index 15 " + StableValueAsLists.LIST.get(15)); +IO.println("The rest is not initialized"); + + +// Snippet 6 +// Title: Stable Values as Maps +class StableValueAsMaps { + static Map MAP = StableValue.map(Set.of(1, 2, 3), key -> { + IO.println("Initializing key value pair for the key " + key); + return "I am bound to key " + key; + }); +} + +IO.println("Size of MAP: " + StableValueAsMaps.MAP.size()); +IO.println("Keys of MAP: " + StableValueAsMaps.MAP.keySet()); +IO.println("Values bound to 2: " + StableValueAsMaps.MAP.get(2)); +IO.println("Values bound to 4: " + StableValueAsMaps.MAP.get(4)); +IO.println("Values bound to 2 again: " + StableValueAsMaps.MAP.get(2)); +IO.println("The rest is not initialized"); + + +// Snippet 7 +// Title: Stable Values as Functions +record User(String name) { + public User { + IO.println("Initializing User for name " + name); + } +} + +class StableValuesAsFunctions { + static Function FUNCTION = StableValue.function( + Set.of("Mary", "James", "Patricia", "Michael"), User::new); +} + +IO.println("Values bound to Mary: " + StableValuesAsFunctions.FUNCTION.apply("Mary")); +IO.println("Values bound to James: " + StableValuesAsFunctions.FUNCTION.apply("James")); +IO.println("The rest is not initialized"); +IO.println("Values bound to Mary again: " + StableValuesAsFunctions.FUNCTION.apply("Mary")); +IO.println("Values bound to Jennifer again: " + StableValuesAsFunctions.FUNCTION.apply("Jennifer")); + + +// Snippet 8 +// Title: Stable Values as IntFunctions +class StableValuesAsIntFunctions { + static IntFunction FACTORIAL = StableValue.intFunction( + 50, number -> { + IO.println("Computing factorial of " + number); + return factorial(number); + }); + + static BigInteger factorial(int n) { + BigInteger result = BigInteger.ONE; + for (int i = 1; i <= n; i++) { + result = result.multiply(BigInteger.valueOf(i)); + } + return result; + } +} + +IO.println("Factorial of 10 = " + StableValuesAsIntFunctions.FACTORIAL.apply(10)); +IO.println("Factorial of 15 = " + StableValuesAsIntFunctions.FACTORIAL.apply(15)); +IO.println("Factorial of 20 = " + StableValuesAsIntFunctions.FACTORIAL.apply(20)); +IO.println("Factorial of 10 = " + StableValuesAsIntFunctions.FACTORIAL.apply(10)); +IO.println("Factorial of 90 = " + StableValuesAsIntFunctions.FACTORIAL.apply(30));