From ba989a0896638039334602e66dceb7963b77aea2 Mon Sep 17 00:00:00 2001 From: mkyong Date: Mon, 14 Nov 2022 16:53:45 +0800 Subject: [PATCH 1/4] java 18 --- java-18/pom.xml | 38 ++++++++++++++++ .../main/java/com/mkyong/java18/HelloApp.java | 9 ++++ .../java/com/mkyong/java18/jep418/JEP418.java | 23 ++++++++++ .../java/com/mkyong/java18/jep420/JEP420.java | 21 +++++++++ .../com/mkyong/java18/jep420/JEP420_2.java | 25 +++++++++++ .../java/com/mkyong/java18/jep421/JEP421.java | 43 +++++++++++++++++++ java-18/src/main/resources/test.html | 5 +++ 7 files changed, 164 insertions(+) create mode 100644 java-18/pom.xml create mode 100644 java-18/src/main/java/com/mkyong/java18/HelloApp.java create mode 100644 java-18/src/main/java/com/mkyong/java18/jep418/JEP418.java create mode 100644 java-18/src/main/java/com/mkyong/java18/jep420/JEP420.java create mode 100644 java-18/src/main/java/com/mkyong/java18/jep420/JEP420_2.java create mode 100644 java-18/src/main/java/com/mkyong/java18/jep421/JEP421.java create mode 100644 java-18/src/main/resources/test.html diff --git a/java-18/pom.xml b/java-18/pom.xml new file mode 100644 index 0000000..9f4a0ed --- /dev/null +++ b/java-18/pom.xml @@ -0,0 +1,38 @@ + + 4.0.0 + com.mkyong + java18 + 1.0 + + java-18 + https://mkyong.com + + + UTF-8 + 18 + 18 + 18 + + + + + + + java18 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 18 + 18 + --enable-preview + + + + + diff --git a/java-18/src/main/java/com/mkyong/java18/HelloApp.java b/java-18/src/main/java/com/mkyong/java18/HelloApp.java new file mode 100644 index 0000000..0cdd0c5 --- /dev/null +++ b/java-18/src/main/java/com/mkyong/java18/HelloApp.java @@ -0,0 +1,9 @@ +package com.mkyong.java18; + +public class HelloApp { + + public static void main(String[] args) { + System.out.println("Hello Java 17"); + } + +} \ No newline at end of file diff --git a/java-18/src/main/java/com/mkyong/java18/jep418/JEP418.java b/java-18/src/main/java/com/mkyong/java18/jep418/JEP418.java new file mode 100644 index 0000000..cc9173d --- /dev/null +++ b/java-18/src/main/java/com/mkyong/java18/jep418/JEP418.java @@ -0,0 +1,23 @@ +package com.mkyong.java18.jep418; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.net.spi.InetAddressResolver; +import java.net.spi.InetAddressResolverProvider; + +public class JEP418 { + + public static void main(String[] args) throws UnknownHostException { + + // Returns a set of ip address, ipv4 and ipv6. + InetAddress[] machines = InetAddress.getAllByName("google.com"); + for (InetAddress address : machines) { + System.out.println(address.getHostAddress()); + } + + // Returns first address in its set of addresses. + InetAddress ip = InetAddress.getByName("google.com"); + System.out.println(ip.getHostAddress()); + + } +} diff --git a/java-18/src/main/java/com/mkyong/java18/jep420/JEP420.java b/java-18/src/main/java/com/mkyong/java18/jep420/JEP420.java new file mode 100644 index 0000000..a3604a1 --- /dev/null +++ b/java-18/src/main/java/com/mkyong/java18/jep420/JEP420.java @@ -0,0 +1,21 @@ +package com.mkyong.java18.jep420; + +public class JEP420 { + + public static void main(String[] args) { + + } + + // java: this case label is dominated by a preceding case label + /*static void error (Object o){ + switch (o) { + case CharSequence cs -> System.out.println("A sequence of length " + cs.length()); + case String s -> // Error - pattern is dominated by previous pattern + System.out.println("A string: " + s); + default -> { + break; + } + } + }*/ + +} diff --git a/java-18/src/main/java/com/mkyong/java18/jep420/JEP420_2.java b/java-18/src/main/java/com/mkyong/java18/jep420/JEP420_2.java new file mode 100644 index 0000000..67095ac --- /dev/null +++ b/java-18/src/main/java/com/mkyong/java18/jep420/JEP420_2.java @@ -0,0 +1,25 @@ +package com.mkyong.java18.jep420; + +public class JEP420_2 { + + // java: the switch expression does not cover all possible input values + // error + /*static int coverage(Object o) { + return switch (o) { // Error - not exhaustive + case String s -> s.length(); + case Integer i -> i; + }; + }*/ + + static int coverage(Object o) { + return switch (o) { + case String s -> s.length(); + case Integer i -> i; + default -> 0; + }; + } + + public static void main(String[] args) { + System.out.println("Hello JEP 420"); + } +} diff --git a/java-18/src/main/java/com/mkyong/java18/jep421/JEP421.java b/java-18/src/main/java/com/mkyong/java18/jep421/JEP421.java new file mode 100644 index 0000000..ddc1ca3 --- /dev/null +++ b/java-18/src/main/java/com/mkyong/java18/jep421/JEP421.java @@ -0,0 +1,43 @@ +package com.mkyong.java18.jep421; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +public class JEP421 { + + public static void main(String[] args) throws IOException { + + String file1 = "/Home/mkyong/file1"; + String file2 = "/Home/mkyong/file1"; + + FileInputStream input = null; + FileOutputStream output = null; + try { + input = new FileInputStream(file1); + output = new FileOutputStream(file2); + + // copy files from file1 to file 2 + + output.close(); + output = null; + input.close(); + input = null; + } finally { + if (output != null) output.close(); + if (input != null) input.close(); + } + + /*try (FileInputStream input = new FileInputStream(file1); + FileOutputStream output = new FileOutputStream(file2)) { + // + }*/ + + + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + } +} diff --git a/java-18/src/main/resources/test.html b/java-18/src/main/resources/test.html new file mode 100644 index 0000000..67ef16d --- /dev/null +++ b/java-18/src/main/resources/test.html @@ -0,0 +1,5 @@ + + +

Hello, World

+ + \ No newline at end of file From 49e00875c535efaa7a41fd21bdacd80b7afdbac8 Mon Sep 17 00:00:00 2001 From: mkyong Date: Mon, 14 Nov 2022 16:54:31 +0800 Subject: [PATCH 2/4] update --- java-18/src/main/resources/test.html | 5 ----- java-string/pom.xml | 9 +++++++++ .../mkyong/string/split/StringSplitSpecialBackslash.java | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) delete mode 100644 java-18/src/main/resources/test.html diff --git a/java-18/src/main/resources/test.html b/java-18/src/main/resources/test.html deleted file mode 100644 index 67ef16d..0000000 --- a/java-18/src/main/resources/test.html +++ /dev/null @@ -1,5 +0,0 @@ - - -

Hello, World

- - \ No newline at end of file diff --git a/java-string/pom.xml b/java-string/pom.xml index 250717b..150bf01 100644 --- a/java-string/pom.xml +++ b/java-string/pom.xml @@ -19,6 +19,7 @@ 17 5.8.2 3.12.0 + 1.9 @@ -38,6 +39,14 @@ ${commons-lang3.version} + + + + org.apache.commons + commons-text + ${commons-text.version} + + diff --git a/java-string/src/main/java/com/mkyong/string/split/StringSplitSpecialBackslash.java b/java-string/src/main/java/com/mkyong/string/split/StringSplitSpecialBackslash.java index 6eb9a73..811b361 100644 --- a/java-string/src/main/java/com/mkyong/string/split/StringSplitSpecialBackslash.java +++ b/java-string/src/main/java/com/mkyong/string/split/StringSplitSpecialBackslash.java @@ -9,8 +9,8 @@ public static void main(String[] args) { String dir = "C:\\Users\\mkyong\\projects\\mkyong-tutorials"; // three ways to escape regex special character - //String[] output = dir.split("\\\\"); - //String[] output = dir.split("[\\\\]"); + // String[] output = dir.split("\\\\"); + // String[] output = dir.split("[\\\\]"); String[] output = dir.split(Pattern.quote("\\")); for (String s : output) { From b2390d1760b9c81ff3963773b2b3f28cad8e63fd Mon Sep 17 00:00:00 2001 From: mkyong Date: Mon, 28 Nov 2022 07:55:44 +0800 Subject: [PATCH 3/4] java 19 --- .../main/java/com/mkyong/java18/HelloApp.java | 9 --- java-19/pom.xml | 38 +++++++++++++ .../java/com/mkyong/java19/jep405/JEP405.java | 25 ++++++++ .../com/mkyong/java19/jep405/JEP405_1.java | 23 ++++++++ .../com/mkyong/java19/jep424/JEP424_SORT.java | 57 +++++++++++++++++++ .../mkyong/java19/jep424/JEP424_STRLEN.java | 34 +++++++++++ .../java/com/mkyong/java19/jep425/JEP425.java | 32 +++++++++++ .../java/com/mkyong/java19/jep427/JEP427.java | 31 ++++++++++ .../java/com/mkyong/java19/jep428/JEP428.java | 50 ++++++++++++++++ 9 files changed, 290 insertions(+), 9 deletions(-) delete mode 100644 java-18/src/main/java/com/mkyong/java18/HelloApp.java create mode 100644 java-19/pom.xml create mode 100644 java-19/src/main/java/com/mkyong/java19/jep405/JEP405.java create mode 100644 java-19/src/main/java/com/mkyong/java19/jep405/JEP405_1.java create mode 100644 java-19/src/main/java/com/mkyong/java19/jep424/JEP424_SORT.java create mode 100644 java-19/src/main/java/com/mkyong/java19/jep424/JEP424_STRLEN.java create mode 100644 java-19/src/main/java/com/mkyong/java19/jep425/JEP425.java create mode 100644 java-19/src/main/java/com/mkyong/java19/jep427/JEP427.java create mode 100644 java-19/src/main/java/com/mkyong/java19/jep428/JEP428.java diff --git a/java-18/src/main/java/com/mkyong/java18/HelloApp.java b/java-18/src/main/java/com/mkyong/java18/HelloApp.java deleted file mode 100644 index 0cdd0c5..0000000 --- a/java-18/src/main/java/com/mkyong/java18/HelloApp.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mkyong.java18; - -public class HelloApp { - - public static void main(String[] args) { - System.out.println("Hello Java 17"); - } - -} \ No newline at end of file diff --git a/java-19/pom.xml b/java-19/pom.xml new file mode 100644 index 0000000..3f2c5ce --- /dev/null +++ b/java-19/pom.xml @@ -0,0 +1,38 @@ + + 4.0.0 + com.mkyong + java19 + 1.0 + + java-19 + https://mkyong.com + + + UTF-8 + 19 + 19 + 19 + + + + + + + java19 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 19 + 19 + --enable-preview + + + + + diff --git a/java-19/src/main/java/com/mkyong/java19/jep405/JEP405.java b/java-19/src/main/java/com/mkyong/java19/jep405/JEP405.java new file mode 100644 index 0000000..edc2b29 --- /dev/null +++ b/java-19/src/main/java/com/mkyong/java19/jep405/JEP405.java @@ -0,0 +1,25 @@ +package com.mkyong.java19.jep405; + +public class JEP405 { + + record Point(int x, int y) { + } + + static void printSum(Object o) { + if (o instanceof Point p) { + int x = p.x(); // get x() + int y = p.y(); // get y() + System.out.println(x + y); + } + } + + static void printSumNew(Object o) { + if (o instanceof Point(int x,int y)) { // record pattern + System.out.println(x + y); + } + } + + public static void main(String[] args) { + printSumNew(new Point(10, 20)); // output 30 + } +} \ No newline at end of file diff --git a/java-19/src/main/java/com/mkyong/java19/jep405/JEP405_1.java b/java-19/src/main/java/com/mkyong/java19/jep405/JEP405_1.java new file mode 100644 index 0000000..558ba90 --- /dev/null +++ b/java-19/src/main/java/com/mkyong/java19/jep405/JEP405_1.java @@ -0,0 +1,23 @@ +package com.mkyong.java19.jep405; + +public class JEP405_1 { + + record Point(int x, int y) { + } + + record Total(Point p1, Point p2) { + } + + static void printSum(Object o) { + // record nested pattern + if (o instanceof Total(Point(int x,int y),Point(int x2,int y2))) { + System.out.println(x + y + x2 + y2); + } + } + + public static void main(String[] args) { + + printSum(new Total(new Point(10, 5), new Point(2, 3))); + + } +} diff --git a/java-19/src/main/java/com/mkyong/java19/jep424/JEP424_SORT.java b/java-19/src/main/java/com/mkyong/java19/jep424/JEP424_SORT.java new file mode 100644 index 0000000..56bf31c --- /dev/null +++ b/java-19/src/main/java/com/mkyong/java19/jep424/JEP424_SORT.java @@ -0,0 +1,57 @@ +package com.mkyong.java19.jep424; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; + +import static java.lang.foreign.ValueLayout.*; + +public class JEP424_SORT { + + public static void main(String[] args) throws Throwable { + + // 1. Find foreign function on the C library path + Linker linker = Linker.nativeLinker(); + SymbolLookup stdlib = linker.defaultLookup(); + + // 2. Allocate on-heap memory to store strings + String[] javaStrings = {"d", "z", "b", "c", "a"}; + + // 3. Allocate off-heap memory to store pointers + SegmentAllocator allocator = SegmentAllocator.implicitAllocator(); + MemorySegment offHeap = allocator.allocateArray(ValueLayout.ADDRESS, javaStrings.length); + + // 4. Copy the strings from on-heap to off-heap + for (int i = 0; i < javaStrings.length; i++) { + + // Allocate a string off-heap, then store a pointer to it + MemorySegment cString = allocator.allocateUtf8String(javaStrings[i]); + offHeap.setAtIndex(ValueLayout.ADDRESS, i, cString); + } + + MethodHandle radixSort = linker.downcallHandle( + stdlib.lookup("radixsort").orElseThrow(), + FunctionDescriptor.ofVoid(ADDRESS, JAVA_INT, ADDRESS, JAVA_CHAR)); + + // 5. Sort the off-heap data by calling the foreign function + radixSort.invoke(offHeap, javaStrings.length, MemoryAddress.NULL, '\0'); + + // 6. Copy the (reordered) strings from off-heap to on-heap + for (int i = 0; i < javaStrings.length; i++) { + MemoryAddress cStringPtr = offHeap.getAtIndex(ValueLayout.ADDRESS, i); + javaStrings[i] = cStringPtr.getUtf8String(0); + } + + //print sort result + for (String javaString : javaStrings) { + System.out.println(javaString); + } + + } + +} diff --git a/java-19/src/main/java/com/mkyong/java19/jep424/JEP424_STRLEN.java b/java-19/src/main/java/com/mkyong/java19/jep424/JEP424_STRLEN.java new file mode 100644 index 0000000..652638d --- /dev/null +++ b/java-19/src/main/java/com/mkyong/java19/jep424/JEP424_STRLEN.java @@ -0,0 +1,34 @@ +package com.mkyong.java19.jep424; + +import java.lang.foreign.*; +import java.lang.invoke.MethodHandle; + +import static java.lang.foreign.ValueLayout.ADDRESS; +import static java.lang.foreign.ValueLayout.JAVA_LONG; + +public class JEP424_STRLEN { + + public static void main(String[] args) throws Throwable { + + String input = "Hello World"; + + // 1. Find foreign function on the C library path + SymbolLookup stdlib = Linker.nativeLinker().defaultLookup(); + + // 2. Get a handle to the "strlen" function in the C standard library + MethodHandle methodHandle = Linker.nativeLinker().downcallHandle( + stdlib.lookup("strlen").orElseThrow(), + FunctionDescriptor.of(JAVA_LONG, ADDRESS)); + + // 3. Allocate off-heap memory to store strings + MemorySegment memorySegment = SegmentAllocator + .implicitAllocator().allocateUtf8String(input); + + // 4. Runs the foreign function "strlen" + long length = (long) methodHandle.invoke(memorySegment); + + System.out.println("length = " + length); + + } + +} diff --git a/java-19/src/main/java/com/mkyong/java19/jep425/JEP425.java b/java-19/src/main/java/com/mkyong/java19/jep425/JEP425.java new file mode 100644 index 0000000..070cc20 --- /dev/null +++ b/java-19/src/main/java/com/mkyong/java19/jep425/JEP425.java @@ -0,0 +1,32 @@ +package com.mkyong.java19.jep425; + +import java.time.Duration; +import java.util.concurrent.Executors; +import java.util.stream.IntStream; + +public class JEP425 { + + public static void main(String[] args) { + + try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { + IntStream.range(0, 10_000).forEach(i -> { + executor.submit(() -> { + Thread.sleep(Duration.ofSeconds(1)); + return i; + }); + }); + } // executor.close() is called implicitly, and waits + + /*try (var executor = Executors.newFixedThreadPool(20)) { + IntStream.range(0, 10_000).forEach(i -> { + executor.submit(() -> { + Thread.sleep(Duration.ofSeconds(1)); + return i; + }); + }); + }*/ + + System.out.println("Done"); + + } +} diff --git a/java-19/src/main/java/com/mkyong/java19/jep427/JEP427.java b/java-19/src/main/java/com/mkyong/java19/jep427/JEP427.java new file mode 100644 index 0000000..9d6724a --- /dev/null +++ b/java-19/src/main/java/com/mkyong/java19/jep427/JEP427.java @@ -0,0 +1,31 @@ +package com.mkyong.java19.jep427; + +public class JEP427 { + + public static void main(String[] args) { + + testJava19("mkyong"); + testJava19("mkyongmkyong"); + } + + /* Old guarded pattern + static void test(Object o) { + switch (o) { + case String s && s.length() > 6 -> System.out.println("String's length longer than 10!"); + case String s -> System.out.println("String's length is " + s.length()); + default -> { + } + } + }*/ + + //Guarded patterns are replaced with when clauses in switch blocks. + static void testJava19(Object o) { + switch (o) { + case String s + when s.length() > 10 -> System.out.println("String's length longer than 10!"); + case String s -> System.out.println("String's length is " + s.length()); + default -> {} + } + } + +} diff --git a/java-19/src/main/java/com/mkyong/java19/jep428/JEP428.java b/java-19/src/main/java/com/mkyong/java19/jep428/JEP428.java new file mode 100644 index 0000000..7f771f2 --- /dev/null +++ b/java-19/src/main/java/com/mkyong/java19/jep428/JEP428.java @@ -0,0 +1,50 @@ +package com.mkyong.java19.jep428; + +import java.time.Duration; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +public class JEP428 { + + public static void main(String[] args) throws ExecutionException, InterruptedException { + JEP428 obj = new JEP428(); + obj.handleUnStructureAPI(); + } + + Response handleUnStructureAPI() throws ExecutionException, InterruptedException { + try (var executor = Executors.newFixedThreadPool(10)) { + Future user = executor.submit(this::findUser); + Future order = executor.submit(this::fetchOrder); + String theUser = user.get(); // Join findUser + int theOrder = order.get(); // Join fetchOrder + return new Response(theUser, theOrder); + } + } + + /*Response handleStructureAPI() throws ExecutionException, InterruptedException { + try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { + Future user = scope.fork(this::findUser); + Future order = scope.fork(this::fetchOrder); + + scope.join(); // Join both forks + scope.throwIfFailed(); // ... and propagate errors + + // Here, both forks have succeeded, so compose their results + return new Response(user.resultNow(), order.resultNow()); + } + }*/ + + private String findUser() throws InterruptedException { + Thread.sleep(Duration.ofSeconds(1)); + return "mkyong"; + } + + private Integer fetchOrder() throws InterruptedException { + Thread.sleep(Duration.ofSeconds(1)); + return 1; + } + + record Response(String x, int y) { + } +} From 3e0082dc2305c447759b57a1de412ea5cd934166 Mon Sep 17 00:00:00 2001 From: mkyong Date: Fri, 17 May 2024 17:13:07 +0800 Subject: [PATCH 4/4] update traverse files from a folder --- java-io/pom.xml | 2 +- .../mkyong/io/howto/FileTraverseExample.java | 28 +++++++++++++ .../mkyong/io/howto/FileTraverseExample2.java | 38 ++++++++++++++++++ .../mkyong/io/howto/FileTraverseExample3.java | 40 +++++++++++++++++++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample.java create mode 100644 java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample2.java create mode 100644 java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample3.java diff --git a/java-io/pom.xml b/java-io/pom.xml index f2ca168..cbf8ea1 100644 --- a/java-io/pom.xml +++ b/java-io/pom.xml @@ -16,7 +16,7 @@ UTF-8 17 17 - 17 + 21 5.4.0 diff --git a/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample.java b/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample.java new file mode 100644 index 0000000..3d23fb5 --- /dev/null +++ b/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample.java @@ -0,0 +1,28 @@ +package com.mkyong.io.howto; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + +public class FileTraverseExample { + + public static void main(String[] args) { + + // Specify the directory we want to traverse + String dirPath = "/Users/yongmookkim/projects/test/"; + + // Traverse the directory and process files + try (Stream paths = Files.walk(Paths.get(dirPath))) { + + paths + .filter(Files::isRegularFile) // ensure it is a file + .forEach(System.out::println); // prints the file path + + } catch (IOException e) { + throw new RuntimeException(e); + } + + } +} diff --git a/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample2.java b/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample2.java new file mode 100644 index 0000000..e9a6a83 --- /dev/null +++ b/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample2.java @@ -0,0 +1,38 @@ +package com.mkyong.io.howto; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.stream.Stream; + +public class FileTraverseExample2 { + + public static void main(String[] args) { + + List result; + + // Specify the directory we want to traverse + String dirPath = "/Users/yongmookkim/projects/test/"; + + // Traverse the directory and process files + try (Stream paths = Files.walk(Paths.get(dirPath))) { + + result = paths + .filter(Files::isRegularFile) // ensure it is a file + .map(p -> p.getFileName().toString()) + .toList(); + + } catch (IOException e) { + throw new RuntimeException(e); + } + + System.out.println("Total files: " + result.size()); + for (String name : result) { + System.out.println("FileName: " + name); + } + + + } +} diff --git a/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample3.java b/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample3.java new file mode 100644 index 0000000..1d5c4e7 --- /dev/null +++ b/java-io/src/main/java/com/mkyong/io/howto/FileTraverseExample3.java @@ -0,0 +1,40 @@ +package com.mkyong.io.howto; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.stream.Stream; + +public class FileTraverseExample3 { + + public static void main(String[] args) { + + String dir = "/Users/yongmookkim/projects/test/"; + String findThisFile = "a.txt"; + + try { + + Optional foundFile = findFileByName(Paths.get(dir), findThisFile); + foundFile.ifPresentOrElse( + file -> System.out.println("File found: " + file), + () -> System.out.println("File not found.") + ); + + } catch (IOException e) { + System.err.println("An error occurred while searching for the file: " + e.getMessage()); + } + + } + + public static Optional findFileByName(Path directory, String fileName) throws IOException { + try (Stream stream = Files.walk(directory)) { + return stream + .filter(Files::isRegularFile) + .filter(path -> path.getFileName().toString().equals(fileName)) + .findFirst(); + } + } + +}