diff --git a/.github/tools/pom.xml b/.github/tools/pom.xml new file mode 100644 index 0000000..4574d9b --- /dev/null +++ b/.github/tools/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + tools + 1.0.0 + dev.playground + + + UTF-8 + 21 + 21 + dev.playground.tools.IndexJson + 5.9.2 + + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + compile + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + compile + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + compile + + + + + + + maven-jar-plugin + 3.0.2 + + + + true + ${mainClass} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${maven.compiler.source} + ${maven.compiler.target} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.1 + + + + diff --git a/.github/tools/src/main/java/dev/playground/tools/IndexJson.java b/.github/tools/src/main/java/dev/playground/tools/IndexJson.java new file mode 100644 index 0000000..7e6d107 --- /dev/null +++ b/.github/tools/src/main/java/dev/playground/tools/IndexJson.java @@ -0,0 +1,43 @@ +package dev.playground.tools; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.stream.Collectors; + +public class IndexJson { + + static final String rawGithubCDNPrefix = "https://raw.githubusercontent.com/java/playground-snippets/main/"; + + public static void main(String[] args) throws IOException { + if (args.length < 1) { + System.err.println("USAGE:\n\t[program] "); + System.exit(1); + } + var strPath = args[0]; + var path = Path.of(strPath); + if (!path.toFile().exists()) { + System.err.printf("Directory %s does not exist!\nUSAGE:\n\t[program] \n", path); + System.exit(1); + } + + String result; + try(var walker = Files.walk(path)) { + result = walker.filter(f -> !Files.isDirectory(f)).map(key -> { + var strKey = key.toString().replace(strPath + "/", ""); + var strValue = rawGithubCDNPrefix + strKey; + + return String.format("\t\"%s\": \"%s\"", strKey, strValue); + }).collect(Collectors.joining(",\n")); + } + var indexJsonContent = String.format("{\n%s\n}", result); + var indexJsonFilePath = Path.of(strPath, "index.json"); + System.out.println(indexJsonFilePath); + Files.deleteIfExists(indexJsonFilePath); + indexJsonFilePath.toFile().createNewFile(); + + Files.writeString(indexJsonFilePath, indexJsonContent); + System.out.println(indexJsonContent); + } +} diff --git a/.github/tools/src/main/resources/README.md b/.github/tools/src/main/resources/README.md new file mode 100644 index 0000000..9d4fa1c --- /dev/null +++ b/.github/tools/src/main/resources/README.md @@ -0,0 +1,4 @@ +# DISCLAIMER + + +[snippets](snippets) is a symlink to a [root folder](../../../../../snippets). diff --git a/.github/tools/src/main/resources/snippets/hello-world.snippet b/.github/tools/src/main/resources/snippets/hello-world.snippet new file mode 100644 index 0000000..d83ace4 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/hello-world.snippet @@ -0,0 +1,3 @@ +var name = "Duke"; + +System.out.println("Hello, " + name); diff --git a/.github/tools/src/main/resources/snippets/index.json b/.github/tools/src/main/resources/snippets/index.json new file mode 100644 index 0000000..dd4439a --- /dev/null +++ b/.github/tools/src/main/resources/snippets/index.json @@ -0,0 +1,20 @@ +{ + "misc/simple-collection.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/misc/simple-collection.snippet", + "misc/func-interface.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/misc/func-interface.snippet", + "misc/functions-chaining.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/misc/functions-chaining.snippet", + "records/composing.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/records/composing.snippet", + "records/simple.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/records/simple.snippet", + "records/method-overriding.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/records/method-overriding.snippet", + "streams/filtering.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/streams/filtering.snippet", + "streams/stream-to-list.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/streams/stream-to-list.snippet", + "streams/text-block-to-stream.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/streams/text-block-to-stream.snippet", + "textblocks/formatting.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/textblocks/formatting.snippet", + "textblocks/simple.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/textblocks/simple.snippet", + "textblocks/record.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/textblocks/record.snippet", + "hello-world.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/hello-world.snippet", + "switch/expression.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/switch/expression.snippet", + "switch/pattern-matching.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/switch/pattern-matching.snippet", + "switch/statement.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/switch/statement.snippet", + "pattern-matching/record.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/pattern-matching/record.snippet", + "pattern-matching/switch.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/pattern-matching/switch.snippet" +} \ No newline at end of file diff --git a/.github/tools/src/main/resources/snippets/misc/func-interface.snippet b/.github/tools/src/main/resources/snippets/misc/func-interface.snippet new file mode 100644 index 0000000..1f8db85 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/misc/func-interface.snippet @@ -0,0 +1,9 @@ +@FunctionalInterface +interface MyFunctionalInterface { + public int incrementByTwo(int a); +} + +MyFunctionalInterface f = (num) -> num + 2; +var result = f.incrementByTwo(40); + +System.out.println(result); diff --git a/.github/tools/src/main/resources/snippets/misc/functions-chaining.snippet b/.github/tools/src/main/resources/snippets/misc/functions-chaining.snippet new file mode 100644 index 0000000..cb53b20 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/misc/functions-chaining.snippet @@ -0,0 +1,9 @@ +var strings = Arrays.asList("one", null, "three", "", "five", "six"); + +Function handleNull = s -> s == null ? "": s; +Function length = s -> s.length(); +Function handleNullThenLength = handleNull.andThen(length); + +for (String string : strings) { + System.out.println(string + " -> length = " + handleNullThenLength.apply(string)); +} diff --git a/.github/tools/src/main/resources/snippets/misc/simple-collection.snippet b/.github/tools/src/main/resources/snippets/misc/simple-collection.snippet new file mode 100644 index 0000000..d3f735f --- /dev/null +++ b/.github/tools/src/main/resources/snippets/misc/simple-collection.snippet @@ -0,0 +1,6 @@ +Collection numbers = new ArrayList<>(); +numbers.add("one"); +numbers.add("two"); +numbers.add("three"); +numbers.remove("two"); +System.out.println(numbers); diff --git a/.github/tools/src/main/resources/snippets/pattern-matching/record.snippet b/.github/tools/src/main/resources/snippets/pattern-matching/record.snippet new file mode 100644 index 0000000..cec18ca --- /dev/null +++ b/.github/tools/src/main/resources/snippets/pattern-matching/record.snippet @@ -0,0 +1,14 @@ +record Point(int x, int y) { + public boolean equals(Object other) { + return other instanceof Point otherPoint && + this.x == otherPoint.x && this.y == otherPoint.y; + } +} + +Point p1 = new Point(0, 0); +Point p2 = new Point(1, 1); +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)); diff --git a/.github/tools/src/main/resources/snippets/pattern-matching/switch.snippet b/.github/tools/src/main/resources/snippets/pattern-matching/switch.snippet new file mode 100644 index 0000000..b6f622b --- /dev/null +++ b/.github/tools/src/main/resources/snippets/pattern-matching/switch.snippet @@ -0,0 +1,23 @@ +record Point(int x, int y) {} + +record Circle(Point center, int radius) { + public Circle { + if (radius < 0) throw new IllegalArgumentException("Radius cant be null"); + } +} + +ToDoubleFunction surface = object -> + switch(object) { + case null -> throw new AssertionError("Object is null"); + case Circle(Point p, int radius) when radius == 0 -> 0d; + case Circle(Point p, int radius) -> Math.PI*radius*radius; + case Object notACircle -> throw new AssertionError("Object is not a circle"); + }; + +Circle c1 = new Circle(new Point(0, 0), 0); +Circle c2 = new Circle(new Point(1, 1), 1); + +System.out.println("Surface of " + c1 + " = " + surface.applyAsDouble(c1)); +System.out.println("Surface of " + c2 + " = " + surface.applyAsDouble(c2)); +surface.applyAsDouble(null); +surface.applyAsDouble("Not a circle!"); diff --git a/.github/tools/src/main/resources/snippets/records/composing.snippet b/.github/tools/src/main/resources/snippets/records/composing.snippet new file mode 100644 index 0000000..15642b5 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/records/composing.snippet @@ -0,0 +1,11 @@ +record Population(int population) {} +record City(String name, Population population) { + // static methods are allowed in records + public static City of(String name, int p) { + var population = new Population(p); + return new City(name, population); + } +} + +var paris = City.of("Paris", 2_161); +System.out.println(paris); diff --git a/.github/tools/src/main/resources/snippets/records/method-overriding.snippet b/.github/tools/src/main/resources/snippets/records/method-overriding.snippet new file mode 100644 index 0000000..0696865 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/records/method-overriding.snippet @@ -0,0 +1,18 @@ +record City(String name) { + + public boolean equals(Object other) { + return other instanceof City(String name) && + this.name.equalsIgnoreCase(name); + } + + public int hashCode() { + return name != null ? name.toUpperCase().hashCode() : 0; + } +} + +var paris1 = new City("Paris"); +var paris2 = new City("paris"); +var paris3 = new City("PARIS"); +System.out.println("1 == 2 ? " + paris1.equals(paris2)); +System.out.println("2 == 3 ? " + paris2.equals(paris3)); +System.out.println("1 == 3 ? " + paris1.equals(paris3)); diff --git a/.github/tools/src/main/resources/snippets/records/simple.snippet b/.github/tools/src/main/resources/snippets/records/simple.snippet new file mode 100644 index 0000000..975e5c2 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/records/simple.snippet @@ -0,0 +1,3 @@ +record Player(String last, String first, int level) {} +var jane = new Player("Doe", "Jane", 42); +System.out.println(jane); diff --git a/.github/tools/src/main/resources/snippets/streams/filtering.snippet b/.github/tools/src/main/resources/snippets/streams/filtering.snippet new file mode 100644 index 0000000..d3226bd --- /dev/null +++ b/.github/tools/src/main/resources/snippets/streams/filtering.snippet @@ -0,0 +1,8 @@ +List cities = + Arrays.asList("Shenzhen", "Brussels", "Taipei", "Buenos Aires", "Sydney", "Bristol"); + +cities.stream() + .filter(s -> s.startsWith("B")) + .map(String::toUpperCase) + .sorted() + .forEach(System.out::println); diff --git a/.github/tools/src/main/resources/snippets/streams/stream-to-list.snippet b/.github/tools/src/main/resources/snippets/streams/stream-to-list.snippet new file mode 100644 index 0000000..8a39084 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/streams/stream-to-list.snippet @@ -0,0 +1,5 @@ +Stream stream = Stream.of("Shenzhen", "Brussels", "Taipei", "Buenos Aires", "Sydney", "Bristol"); + +List cities = stream.sorted().collect(Collectors.toList()); + +System.out.println(cities); diff --git a/.github/tools/src/main/resources/snippets/streams/text-block-to-stream.snippet b/.github/tools/src/main/resources/snippets/streams/text-block-to-stream.snippet new file mode 100644 index 0000000..efa872e --- /dev/null +++ b/.github/tools/src/main/resources/snippets/streams/text-block-to-stream.snippet @@ -0,0 +1,11 @@ +var cities = """ + San Francisco + Casablanca + Antwerp + New Delhi + Osaka +"""; + +Stream lines = cities.lines(); + +System.out.println(lines.toList()); diff --git a/.github/tools/src/main/resources/snippets/switch/expression.snippet b/.github/tools/src/main/resources/snippets/switch/expression.snippet new file mode 100644 index 0000000..13adbe1 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/switch/expression.snippet @@ -0,0 +1,11 @@ +enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; } + +Day day = Day.SUNDAY; +int numLetters = switch (day) { + case MONDAY, FRIDAY, SUNDAY -> 6; + case TUESDAY -> 7; + case THURSDAY, SATURDAY -> 8; + case WEDNESDAY -> 9; +}; + +System.out.println(numLetters); diff --git a/.github/tools/src/main/resources/snippets/switch/pattern-matching.snippet b/.github/tools/src/main/resources/snippets/switch/pattern-matching.snippet new file mode 100644 index 0000000..477d3ac --- /dev/null +++ b/.github/tools/src/main/resources/snippets/switch/pattern-matching.snippet @@ -0,0 +1,6 @@ +var result = switch ("Lorem Ipsum") { + case null -> "Oops"; + case "Foo", "Bar" -> "Great"; + default -> "Ok!"; +}; +System.out.println(result); diff --git a/.github/tools/src/main/resources/snippets/switch/statement.snippet b/.github/tools/src/main/resources/snippets/switch/statement.snippet new file mode 100644 index 0000000..edd3525 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/switch/statement.snippet @@ -0,0 +1,21 @@ +enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; } +var numberOfChar = 0; + +switch(Day.MONDAY) { + case MONDAY: case FRIDAY: case SUNDAY: + numberOfChar = 6; + break; + case TUESDAY: + numberOfChar = 7; + break; + case WEDNESDAY: + numberOfChar = 9; + break; + case THURSDAY: case SATURDAY: + numberOfChar = 8; + break; + default: + throw new IllegalArgumentException(); +} + +System.out.println(numberOfChar); diff --git a/.github/tools/src/main/resources/snippets/textblocks/formatting.snippet b/.github/tools/src/main/resources/snippets/textblocks/formatting.snippet new file mode 100644 index 0000000..df7a48c --- /dev/null +++ b/.github/tools/src/main/resources/snippets/textblocks/formatting.snippet @@ -0,0 +1,4 @@ +var message = """ + {"name" : "%s", "language" : "Java"} +"""; +System.out.println(message.formatted("Duke")); diff --git a/.github/tools/src/main/resources/snippets/textblocks/record.snippet b/.github/tools/src/main/resources/snippets/textblocks/record.snippet new file mode 100644 index 0000000..0b768d3 --- /dev/null +++ b/.github/tools/src/main/resources/snippets/textblocks/record.snippet @@ -0,0 +1,21 @@ +record City(String name, int population) { + + public static City of(String line) { + int indexOfLastSpace = line.lastIndexOf(' '); + var name = line.substring(0, indexOfLastSpace); + var population = Integer.parseInt(line.substring(indexOfLastSpace + 1)); + return new City(name, population); + } +} + +String cities = """ + New York 8343 + London 8982 + Paris 2161 + Bangaluru 8474 + Singapore 5454 + Tokyo 13960 + """; + +var cityList = cities.lines().map(City::of).toList(); +cityList.forEach(System.out::println); diff --git a/.github/tools/src/main/resources/snippets/textblocks/simple.snippet b/.github/tools/src/main/resources/snippets/textblocks/simple.snippet new file mode 100644 index 0000000..0259fed --- /dev/null +++ b/.github/tools/src/main/resources/snippets/textblocks/simple.snippet @@ -0,0 +1,9 @@ +String cities = """ + New York \s + Paris \s + Bangalore \s + Singapore \s + Tokyo \s + """; + +cities.lines().map(line -> "|" + line + "|").forEach(System.out::println); diff --git a/.github/tools/src/test/java/dev/playground/SnippetTest.java b/.github/tools/src/test/java/dev/playground/SnippetTest.java new file mode 100644 index 0000000..0c2b6d6 --- /dev/null +++ b/.github/tools/src/test/java/dev/playground/SnippetTest.java @@ -0,0 +1,106 @@ +package dev.playground; + +import dev.playground.tools.IndexJson; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.Base64; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Executors; + +import static org.junit.jupiter.api.Assertions.*; + +public class SnippetTest { + + static final HttpRequest.Builder builder = HttpRequest.newBuilder() + .version(HttpClient.Version.HTTP_1_1) + .headers("Content-Type", "application/x-www-form-urlencoded"); + + static final HttpClient client = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(300)) + .version(HttpClient.Version.HTTP_1_1) + .executor(Executors.newVirtualThreadPerTaskExecutor()) + .build(); + + static final String bodyTemplate = """ + { + "snippet": "%s", + "option": "na" + } + """; + + static List getData() throws URISyntaxException { + List data; + var mainClassLoader = IndexJson.class.getClassLoader(); + var samplesFolder = Path.of(Objects.requireNonNull(mainClassLoader.getResource("snippets")).toURI()); + try(var files = Files.walk(samplesFolder)) { + data = files.filter(fl -> fl.toString().endsWith(".snippet")).map(f -> { + String snippet; + var snippetPath = f.getParent() + "/" + f.getFileName(); + try { + snippet = new String(Files.readAllBytes(Path.of(snippetPath))); + } catch (IOException e) { + throw new RuntimeException(e); + } + return snippet; + }).toList(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return data; + } + + String executeSnippet(String snippet) throws Exception{ + var publicEndpoint = System.getProperty("execution.endpoint"); + Assumptions.assumeTrue(Objects.nonNull(publicEndpoint)); + var requestBody = bodyTemplate.formatted( + new String(Base64.getEncoder().encode(snippet.getBytes(StandardCharsets.UTF_8)) + )); + var request = builder.uri(new URI(publicEndpoint)) + .POST(HttpRequest.BodyPublishers.ofString(requestBody)) + .build(); + var response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); + var responseBody = new String(response.body()); + var responseDetails = String.format("Headers: %s | Body: %s", response.headers().map(), responseBody); + assertEquals(200, response.statusCode(), responseDetails); + assertTrue(responseBody.contains("VALID"), responseDetails); + + return responseBody; + } + + @Test + public void testCompile() throws Exception { + var snippets = getData(); + snippets.forEach(snippet -> { + try { + System.out.printf("[SnippetTest::testCompile] Running validation test for snippet:\n%s\n", snippet); + executeSnippet(snippet); + Thread.sleep(Duration.ofSeconds(4)); + } catch (Exception e) { + fail(e); + } + }); + } + + @Test + public void testCharset() throws Exception { + var snippet = """ + System.out.println("tu dois faire ça"); + """; + System.out.printf("[SnippetTest::testCharset] Running charset validation test for snippet:\n%s\n", snippet); + var responseBody = executeSnippet(snippet); + assertTrue(responseBody.contains("tu dois faire ça")); + assertFalse(responseBody.contains("tu dois faire ?a")); + } +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f17d9f0 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,28 @@ +name: build and test + +on: + pull_request: + branches: [ main ] + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - name: 'Download JDK' + id: jdk + uses: oracle-actions/setup-java@v1 + with: + website: oracle.com + release: 21 + + - name: 'Check out repository' + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: run tests + shell: bash + working-directory: .github/tools + run: | + mvn test -Dexecution.endpoint=https://i67ddx34g3dcytoxovnbl45u6m.apigateway.us-ashburn-1.oci.customer-oci.com/api/execute + diff --git a/README.md b/README.md index f28b740..d3daf39 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ This repository hosts the samples snippets of the [Java Playground](https://dev.java/playground/). -We don't accept external contributions on this repo. For suggestions and pontential issues, please use [github.com/java/devrel](https://github.com/java/). +We don't accept external contributions to this repo. For suggestions and potential issues, please use [github.com/java/devrel](https://github.com/java/). diff --git a/snippets/hello-world.snippet b/snippets/hello-world.snippet new file mode 100644 index 0000000..d83ace4 --- /dev/null +++ b/snippets/hello-world.snippet @@ -0,0 +1,3 @@ +var name = "Duke"; + +System.out.println("Hello, " + name); diff --git a/snippets/index.json b/snippets/index.json new file mode 100644 index 0000000..376a602 --- /dev/null +++ b/snippets/index.json @@ -0,0 +1,21 @@ +{ + "misc/simple-collection.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/misc/simple-collection.snippet", + "misc/func-interface.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/misc/func-interface.snippet", + "misc/functions-chaining.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/misc/functions-chaining.snippet", + "records/composing.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/records/composing.snippet", + "records/simple.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/records/simple.snippet", + "records/method-overriding.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/records/method-overriding.snippet", + "streams/filtering.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/streams/filtering.snippet", + "streams/stream-to-list.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/streams/stream-to-list.snippet", + "streams/text-block-to-stream.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/streams/text-block-to-stream.snippet", + "textblocks/formatting.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/textblocks/formatting.snippet", + "textblocks/simple.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/textblocks/simple.snippet", + "textblocks/record.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/textblocks/record.snippet", + "hello-world.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/hello-world.snippet", + "switch/expression.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/switch/expression.snippet", + "switch/pattern-matching.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/switch/pattern-matching.snippet", + "switch/statement.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/switch/statement.snippet", + "pattern-matching/record.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/pattern-matching/record.snippet", + "pattern-matching/switch.snippet": "https://raw.githubusercontent.com/java/playground-snippets/main/pattern-matching/switch.snippet", + "index.json": "https://raw.githubusercontent.com/java/playground-snippets/main/index.json" +} \ No newline at end of file diff --git a/snippets/misc/func-interface.snippet b/snippets/misc/func-interface.snippet new file mode 100644 index 0000000..1f8db85 --- /dev/null +++ b/snippets/misc/func-interface.snippet @@ -0,0 +1,9 @@ +@FunctionalInterface +interface MyFunctionalInterface { + public int incrementByTwo(int a); +} + +MyFunctionalInterface f = (num) -> num + 2; +var result = f.incrementByTwo(40); + +System.out.println(result); diff --git a/snippets/misc/functions-chaining.snippet b/snippets/misc/functions-chaining.snippet new file mode 100644 index 0000000..cb53b20 --- /dev/null +++ b/snippets/misc/functions-chaining.snippet @@ -0,0 +1,9 @@ +var strings = Arrays.asList("one", null, "three", "", "five", "six"); + +Function handleNull = s -> s == null ? "": s; +Function length = s -> s.length(); +Function handleNullThenLength = handleNull.andThen(length); + +for (String string : strings) { + System.out.println(string + " -> length = " + handleNullThenLength.apply(string)); +} diff --git a/snippets/misc/simple-collection.snippet b/snippets/misc/simple-collection.snippet new file mode 100644 index 0000000..d3f735f --- /dev/null +++ b/snippets/misc/simple-collection.snippet @@ -0,0 +1,6 @@ +Collection numbers = new ArrayList<>(); +numbers.add("one"); +numbers.add("two"); +numbers.add("three"); +numbers.remove("two"); +System.out.println(numbers); diff --git a/snippets/pattern-matching/record.snippet b/snippets/pattern-matching/record.snippet new file mode 100644 index 0000000..cec18ca --- /dev/null +++ b/snippets/pattern-matching/record.snippet @@ -0,0 +1,14 @@ +record Point(int x, int y) { + public boolean equals(Object other) { + return other instanceof Point otherPoint && + this.x == otherPoint.x && this.y == otherPoint.y; + } +} + +Point p1 = new Point(0, 0); +Point p2 = new Point(1, 1); +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)); diff --git a/snippets/pattern-matching/switch.snippet b/snippets/pattern-matching/switch.snippet new file mode 100644 index 0000000..b6f622b --- /dev/null +++ b/snippets/pattern-matching/switch.snippet @@ -0,0 +1,23 @@ +record Point(int x, int y) {} + +record Circle(Point center, int radius) { + public Circle { + if (radius < 0) throw new IllegalArgumentException("Radius cant be null"); + } +} + +ToDoubleFunction surface = object -> + switch(object) { + case null -> throw new AssertionError("Object is null"); + case Circle(Point p, int radius) when radius == 0 -> 0d; + case Circle(Point p, int radius) -> Math.PI*radius*radius; + case Object notACircle -> throw new AssertionError("Object is not a circle"); + }; + +Circle c1 = new Circle(new Point(0, 0), 0); +Circle c2 = new Circle(new Point(1, 1), 1); + +System.out.println("Surface of " + c1 + " = " + surface.applyAsDouble(c1)); +System.out.println("Surface of " + c2 + " = " + surface.applyAsDouble(c2)); +surface.applyAsDouble(null); +surface.applyAsDouble("Not a circle!"); diff --git a/snippets/records/composing.snippet b/snippets/records/composing.snippet new file mode 100644 index 0000000..15642b5 --- /dev/null +++ b/snippets/records/composing.snippet @@ -0,0 +1,11 @@ +record Population(int population) {} +record City(String name, Population population) { + // static methods are allowed in records + public static City of(String name, int p) { + var population = new Population(p); + return new City(name, population); + } +} + +var paris = City.of("Paris", 2_161); +System.out.println(paris); diff --git a/snippets/records/method-overriding.snippet b/snippets/records/method-overriding.snippet new file mode 100644 index 0000000..0696865 --- /dev/null +++ b/snippets/records/method-overriding.snippet @@ -0,0 +1,18 @@ +record City(String name) { + + public boolean equals(Object other) { + return other instanceof City(String name) && + this.name.equalsIgnoreCase(name); + } + + public int hashCode() { + return name != null ? name.toUpperCase().hashCode() : 0; + } +} + +var paris1 = new City("Paris"); +var paris2 = new City("paris"); +var paris3 = new City("PARIS"); +System.out.println("1 == 2 ? " + paris1.equals(paris2)); +System.out.println("2 == 3 ? " + paris2.equals(paris3)); +System.out.println("1 == 3 ? " + paris1.equals(paris3)); diff --git a/snippets/records/simple.snippet b/snippets/records/simple.snippet new file mode 100644 index 0000000..975e5c2 --- /dev/null +++ b/snippets/records/simple.snippet @@ -0,0 +1,3 @@ +record Player(String last, String first, int level) {} +var jane = new Player("Doe", "Jane", 42); +System.out.println(jane); diff --git a/snippets/streams/filtering.snippet b/snippets/streams/filtering.snippet new file mode 100644 index 0000000..d3226bd --- /dev/null +++ b/snippets/streams/filtering.snippet @@ -0,0 +1,8 @@ +List cities = + Arrays.asList("Shenzhen", "Brussels", "Taipei", "Buenos Aires", "Sydney", "Bristol"); + +cities.stream() + .filter(s -> s.startsWith("B")) + .map(String::toUpperCase) + .sorted() + .forEach(System.out::println); diff --git a/snippets/streams/stream-to-list.snippet b/snippets/streams/stream-to-list.snippet new file mode 100644 index 0000000..8a39084 --- /dev/null +++ b/snippets/streams/stream-to-list.snippet @@ -0,0 +1,5 @@ +Stream stream = Stream.of("Shenzhen", "Brussels", "Taipei", "Buenos Aires", "Sydney", "Bristol"); + +List cities = stream.sorted().collect(Collectors.toList()); + +System.out.println(cities); diff --git a/snippets/streams/text-block-to-stream.snippet b/snippets/streams/text-block-to-stream.snippet new file mode 100644 index 0000000..efa872e --- /dev/null +++ b/snippets/streams/text-block-to-stream.snippet @@ -0,0 +1,11 @@ +var cities = """ + San Francisco + Casablanca + Antwerp + New Delhi + Osaka +"""; + +Stream lines = cities.lines(); + +System.out.println(lines.toList()); diff --git a/snippets/switch/expression.snippet b/snippets/switch/expression.snippet new file mode 100644 index 0000000..13adbe1 --- /dev/null +++ b/snippets/switch/expression.snippet @@ -0,0 +1,11 @@ +enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; } + +Day day = Day.SUNDAY; +int numLetters = switch (day) { + case MONDAY, FRIDAY, SUNDAY -> 6; + case TUESDAY -> 7; + case THURSDAY, SATURDAY -> 8; + case WEDNESDAY -> 9; +}; + +System.out.println(numLetters); diff --git a/snippets/switch/pattern-matching.snippet b/snippets/switch/pattern-matching.snippet new file mode 100644 index 0000000..477d3ac --- /dev/null +++ b/snippets/switch/pattern-matching.snippet @@ -0,0 +1,6 @@ +var result = switch ("Lorem Ipsum") { + case null -> "Oops"; + case "Foo", "Bar" -> "Great"; + default -> "Ok!"; +}; +System.out.println(result); diff --git a/snippets/switch/statement.snippet b/snippets/switch/statement.snippet new file mode 100644 index 0000000..edd3525 --- /dev/null +++ b/snippets/switch/statement.snippet @@ -0,0 +1,21 @@ +enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; } +var numberOfChar = 0; + +switch(Day.MONDAY) { + case MONDAY: case FRIDAY: case SUNDAY: + numberOfChar = 6; + break; + case TUESDAY: + numberOfChar = 7; + break; + case WEDNESDAY: + numberOfChar = 9; + break; + case THURSDAY: case SATURDAY: + numberOfChar = 8; + break; + default: + throw new IllegalArgumentException(); +} + +System.out.println(numberOfChar); diff --git a/snippets/textblocks/formatting.snippet b/snippets/textblocks/formatting.snippet new file mode 100644 index 0000000..df7a48c --- /dev/null +++ b/snippets/textblocks/formatting.snippet @@ -0,0 +1,4 @@ +var message = """ + {"name" : "%s", "language" : "Java"} +"""; +System.out.println(message.formatted("Duke")); diff --git a/snippets/textblocks/record.snippet b/snippets/textblocks/record.snippet new file mode 100644 index 0000000..0b768d3 --- /dev/null +++ b/snippets/textblocks/record.snippet @@ -0,0 +1,21 @@ +record City(String name, int population) { + + public static City of(String line) { + int indexOfLastSpace = line.lastIndexOf(' '); + var name = line.substring(0, indexOfLastSpace); + var population = Integer.parseInt(line.substring(indexOfLastSpace + 1)); + return new City(name, population); + } +} + +String cities = """ + New York 8343 + London 8982 + Paris 2161 + Bangaluru 8474 + Singapore 5454 + Tokyo 13960 + """; + +var cityList = cities.lines().map(City::of).toList(); +cityList.forEach(System.out::println); diff --git a/snippets/textblocks/simple.snippet b/snippets/textblocks/simple.snippet new file mode 100644 index 0000000..0259fed --- /dev/null +++ b/snippets/textblocks/simple.snippet @@ -0,0 +1,9 @@ +String cities = """ + New York \s + Paris \s + Bangalore \s + Singapore \s + Tokyo \s + """; + +cities.lines().map(line -> "|" + line + "|").forEach(System.out::println);