diff --git a/.classpath b/.classpath deleted file mode 100644 index e6bcceb..0000000 --- a/.classpath +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.factorypath b/.factorypath deleted file mode 100644 index bd949bb..0000000 --- a/.factorypath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/pom.xml b/pom.xml index 919e238..5af383f 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ org.projectlombok lombok - 1.18.26 + 1.18.32 provided @@ -207,11 +207,12 @@ 21 21 + true org.projectlombok lombok - 1.18.30 + 1.18.32 io.soabase.record-builder @@ -224,6 +225,7 @@ ${jmh.version} + --enable-preview diff --git a/splash.png b/splash.png new file mode 100644 index 0000000..bccfe40 Binary files /dev/null and b/splash.png differ diff --git a/src/main/java/com/howtodoinjava/algorithms/IsomorphicStrings.java b/src/main/java/com/howtodoinjava/algorithms/IsomorphicStrings.java new file mode 100644 index 0000000..491ee0f --- /dev/null +++ b/src/main/java/com/howtodoinjava/algorithms/IsomorphicStrings.java @@ -0,0 +1,34 @@ +package com.howtodoinjava.algorithms; + +public class IsomorphicStrings { + + public boolean areIsomorphic(String s1, String s2) { + if (s1 == null || s2 == null + || s1.length() != s2.length()) { + return false; + } + + int[] arr1 = new int[256]; + int[] arr2 = new int[256]; + + for (int i = 0; i < s1.length(); i++) { + + char c1 = s1.charAt(i); + char c2 = s2.charAt(i); + + if (arr1[c1] != arr2[c2]) { + return false; + } + + arr1[c1] = i + 1; + arr2[c2] = i + 1; + } + return true; + } + + public static void main(String[] args) { + IsomorphicStrings iso = new IsomorphicStrings(); + System.out.println(iso.areIsomorphic("abbcdd", "qwwcrr")); // true + System.out.println(iso.areIsomorphic("aab", "que")); // false + } +} diff --git a/src/main/java/com/howtodoinjava/concurrency/SharedSeedExample.java b/src/main/java/com/howtodoinjava/concurrency/SharedSeedExample.java new file mode 100644 index 0000000..9a28802 --- /dev/null +++ b/src/main/java/com/howtodoinjava/concurrency/SharedSeedExample.java @@ -0,0 +1,55 @@ +package com.howtodoinjava.concurrency; + +import java.security.SecureRandom; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +public class SharedSeedExample { + + private static final int THREAD_COUNT = 5; + private static final int ITERATIONS_PER_THREAD = 10; + private static ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT); + + private static final AtomicInteger sharedCounter = new AtomicInteger(0); + + public static void main(String[] args) { + System.out.println("Using a shared Random instance:"); + java.util.Random sharedRandom = new java.util.Random(); + + for (int i = 0; i < THREAD_COUNT; i++) { + executorService.submit(() -> { + for (int j = 0; j < ITERATIONS_PER_THREAD; j++) { + int randomNumber = sharedRandom.nextInt(); + processRandomNumber(randomNumber); + } + }); + } + + System.out.println("\nUsing a shared SecureRandom instance:"); + SecureRandom sharedSecureRandom = new SecureRandom(); + + for (int i = 0; i < THREAD_COUNT; i++) { + executorService.submit(() -> { + for (int j = 0; j < ITERATIONS_PER_THREAD; j++) { + int randomNumber = sharedSecureRandom.nextInt(); + processRandomNumber(randomNumber); + } + }); + } + shutdownExecutor(executorService); + } + + private static void processRandomNumber(int randomNumber) { + // Simulate some processing of the random number + sharedCounter.incrementAndGet(); + } + + private static void shutdownExecutor(ExecutorService executorService) { + executorService.shutdown(); + while (!executorService.isTerminated()) { + // Wait for all threads to finish + } + System.out.println(STR."The counter value: \{sharedCounter.get()}"); + } +} diff --git a/src/main/java/com/howtodoinjava/concurrency/virtualThreads/ExecutorExample.java b/src/main/java/com/howtodoinjava/concurrency/virtualThreads/ExecutorExample.java new file mode 100644 index 0000000..d52bb86 --- /dev/null +++ b/src/main/java/com/howtodoinjava/concurrency/virtualThreads/ExecutorExample.java @@ -0,0 +1,30 @@ +package com.howtodoinjava.concurrency.virtualThreads; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class ExecutorExample { + + void main(String[] args) throws InterruptedException { + + List numList = Arrays.asList(1, 2, 3, 4, 5); + + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + + numList.forEach(num -> + executor.execute(() -> { + System.out.println(STR."Square of \{num} is :: \{square(num)}"); + }) + ); + + executor.awaitTermination(2, TimeUnit.SECONDS); + executor.shutdown(); + } + + private Integer square(Integer num) { + return num * num; + } +} diff --git a/src/main/java/com/howtodoinjava/core/basic/AllPrimeFactors.java b/src/main/java/com/howtodoinjava/core/basic/AllPrimeFactors.java new file mode 100644 index 0000000..5b1399f --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/basic/AllPrimeFactors.java @@ -0,0 +1,30 @@ +package com.howtodoinjava.core.basic; + +import java.util.ArrayList; +import java.util.List; + +public class AllPrimeFactors { + + public static void main(String[] args) { + System.out.println(primeFactors(90)); + System.out.println(primeFactors(190)); + System.out.println(primeFactors(350)); + } + + public static List primeFactors(int v) { + List factorsList = new ArrayList<>(); + int s = 2; + + while (v > 1) { + // each perfect division give us a prime factor + if (v % s == 0) { + factorsList.add(s); + v = v / s; + } else { + s++; + } + } + + return factorsList; + } +} diff --git a/src/main/java/com/howtodoinjava/core/basic/CharacterEncodingExample.java b/src/main/java/com/howtodoinjava/core/basic/CharacterEncodingExample.java new file mode 100644 index 0000000..dc6e676 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/basic/CharacterEncodingExample.java @@ -0,0 +1,25 @@ +package com.howtodoinjava.core.basic; + +import java.nio.charset.Charset; + +public class CharacterEncodingExample { + + public static void main(String[] args) { + String fileCoding = System.getProperty("file.encoding"); + System.out.println(STR."Default Character Encoding: \{fileCoding}"); + + String filePathEncoding = System.getProperty("sun.jnu.encoding"); + System.out.println(STR."Default File Path Encoding: \{filePathEncoding}"); + + String defaultCharset = Charset.defaultCharset().displayName(); + System.out.println(STR."Default Charset Name: \{defaultCharset}"); + + /*System.setProperty("file.encoding", "UTF-16"); + System.setProperty("sun.jnu.encoding", "UTF-16");*/ + + defaultCharset = System.out.charset().displayName(); + System.out.println(STR."Default Character Encoding: \{defaultCharset}"); + + System.out.println("The façade pattern is a software-design pattern."); + } +} diff --git a/src/main/java/com/howtodoinjava/core/basic/ObjectIdentityString.java b/src/main/java/com/howtodoinjava/core/basic/ObjectIdentityString.java new file mode 100644 index 0000000..593de92 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/basic/ObjectIdentityString.java @@ -0,0 +1,33 @@ +package com.howtodoinjava.core.basic; + +import java.util.Objects; +import lombok.AllArgsConstructor; + +public class ObjectIdentityString { + + public static void main(String[] args) { + Record record = new Record(1L, "record name"); + + System.out.println(record); + + System.out.println(record != null ? Objects.toIdentityString(record) : "null"); + + System.out.println(getIdentityString(record)); + } + + static String getIdentityString(Object object) { + return object.getClass().getName() + "@" + + Integer.toHexString(System.identityHashCode(object)); + } +} + +@AllArgsConstructor +class Record { + long id; + String name; + + @Override + public String toString() { + return STR."Record{id=\{id}, name='\{name}\{'\''}\{'}'}"; + } +} diff --git a/src/main/java/com/howtodoinjava/core/basic/StricfpExample.java b/src/main/java/com/howtodoinjava/core/basic/StricfpExample.java new file mode 100644 index 0000000..6d7ac88 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/basic/StricfpExample.java @@ -0,0 +1,22 @@ +package com.howtodoinjava.core.basic; + +public class StricfpExample { + + public static void main(String[] args) { + runMethod(); + } + + strictfp public static void runMethod() { + double x = 5.899999; + double y = 13.888345; + double z = 14.463534545; + + double m1 = (x * y) * z; // 1185.1596894396725 + double m2 = (x * (y * z)); // 1185.1596894396728 + + System.out.println(m1); + System.out.println(m2); + + System.out.println(m1 == m2); //false + } +} diff --git a/src/main/java/com/howtodoinjava/core/basic/math/MathAbsoluteExamples.java b/src/main/java/com/howtodoinjava/core/basic/math/MathAbsoluteExamples.java new file mode 100644 index 0000000..893e2fe --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/basic/math/MathAbsoluteExamples.java @@ -0,0 +1,28 @@ +package com.howtodoinjava.core.basic.math; + +public class MathAbsoluteExamples { + + public static void main(String[] args) { + + double doubleValue = -10.56; + float floatValue = -7.8f; + int intValue = -15; + long longValue = -123456789L; + + System.out.println(STR."Absolute value of double: \{Math.abs(doubleValue)}"); + System.out.println(STR."Absolute value of float: \{Math.abs(floatValue)}"); + System.out.println(STR."Absolute value of int: \{Math.abs(intValue)}"); + System.out.println(STR."Absolute value of long: \{Math.abs(longValue)}"); + + //Overflow / Underflow Issue + + int intMinValue = Integer.MIN_VALUE; + long longMinValue = Long.MIN_VALUE; + + System.out.println(STR."Absolute value of int: \{Math.abs(intMinValue)}"); + System.out.println(STR."Absolute value of long: \{Math.abs(longMinValue)}"); + + System.out.println(STR."Absolute value of int: \{Math.absExact(intMinValue)}"); + System.out.println(STR."Absolute value of long: \{Math.absExact(longMinValue)}"); + } +} diff --git a/src/main/java/com/howtodoinjava/core/basic/math/MathDivideExact.java b/src/main/java/com/howtodoinjava/core/basic/math/MathDivideExact.java new file mode 100644 index 0000000..7e46c7d --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/basic/math/MathDivideExact.java @@ -0,0 +1,33 @@ +package com.howtodoinjava.core.basic.math; + +import java.util.function.BinaryOperator; + +public class MathDivideExact { + + public static void main(String[] args) { + + int result = 100 / -1; + System.out.println(result); + + System.out.println(Integer.MAX_VALUE); + int x = Integer.MIN_VALUE; + System.out.println(x); + int quotient1 = x/-1; // -2,147,483,648 + System.out.println(quotient1); + + long y = Integer.MIN_VALUE; + long quotient2 = y/-1; // 2,147,483,648 + System.out.println(quotient2); + + int quotientExactFine = Math.divideExact(4, -1); + System.out.println(quotientExactFine); + + int quotientExactEx = Math.divideExact(x, -1); + System.out.println(quotientExactEx); + + BinaryOperator operator = Math::divideExact; + int quotientExactBo = operator.apply(x, -1); + System.out.println(quotientExactBo); + } + +} diff --git a/src/main/java/com/howtodoinjava/core/basic/math/MathFloorDivCeilDiv.java b/src/main/java/com/howtodoinjava/core/basic/math/MathFloorDivCeilDiv.java new file mode 100644 index 0000000..54fa75e --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/basic/math/MathFloorDivCeilDiv.java @@ -0,0 +1,9 @@ +package com.howtodoinjava.core.basic.math; + +public class MathFloorDivCeilDiv { + + public static void main(String[] args) { + + } + +} diff --git a/src/main/java/com/howtodoinjava/core/collections/map/ImmutableMap.java b/src/main/java/com/howtodoinjava/core/collections/map/ImmutableMap.java index 69fcba4..1d0cd5d 100644 --- a/src/main/java/com/howtodoinjava/core/collections/map/ImmutableMap.java +++ b/src/main/java/com/howtodoinjava/core/collections/map/ImmutableMap.java @@ -3,13 +3,65 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.util.Map.entry; +import static java.util.stream.Collectors.*; public class ImmutableMap { + public static void main(String[] args) { + //1 Map immutableMap = Map.of("key1", "value1"); - //throws java.lang.UnsupportedOperationException - immutableMap.put("key2", "value2"); + //immutableMap.put("key2", "value2"); + + //2 + Map map = new HashMap<>(); + map.put("key 1", "value 1"); + map.put("key 2", "value 2"); + map.put("key 3", "value 3"); + + Map imap = Map.copyOf(map); + //modify the original map + map.put("key 4", "value 4"); + + System.out.println(map); // {key 4=value 4, key 3=value 3, key 2=value 2, key 1=value 1} + System.out.println(imap); // {key 3=value 3, key 1=value 1, key 2=value 2} + + imap = Collections.unmodifiableMap(map); + //immutableMap.put("key2", "value2"); + + System.out.println(imap); + + imap = Stream.of( + entry("key 1", "value 1"), + entry("key 2", "value 2"), + entry("key 3", "value 3")) + .collect(toUnmodifiableMap(e->e.getKey(), e->e.getValue())); + + imap.put("key 4", "value 4"); + + System.out.println(imap); + + imap = Map.ofEntries( + entry("key 1", null), + entry("key 2", "value 2"), + entry("key 3", "value 3"), + entry("key 4", "value 4"), + entry("key 5", "value 5"), + entry("key 6", "value 6"), + entry("key 7", "value 7"), + entry("key 8", "value 8"), + entry("key 9", "value 9"), + entry("key 10", "value 10"), + entry("key 11", "value 11"), + entry("key 12", "value 12") + ); + + System.out.println(imap); } } diff --git a/src/main/java/com/howtodoinjava/core/collections/map/InitializeHashMap.java b/src/main/java/com/howtodoinjava/core/collections/map/InitializeHashMap.java new file mode 100644 index 0000000..2f49400 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/collections/map/InitializeHashMap.java @@ -0,0 +1,46 @@ +package com.howtodoinjava.core.collections.map; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class InitializeHashMap { + + public static void main(String[] args) { + + // Empty maps + HashMap map1 = new HashMap<>(); + HashMap map2 = new HashMap<>(10); + HashMap map3 = HashMap.newHashMap(10); + + // Pre-populated maps + HashMap map4 = new HashMap<>( + Map.ofEntries( + Map.entry("key1", "value1"), + Map.entry("key2", "value3")) + ); + + Map map5 = new HashMap<>() {{ + put("key1", "value1"); + put("key2", "value2"); + }}; + + HashMap map6 = new HashMap<>( + Map.of("key1", "value1", "key2", "value3") + ); + + // Immutable maps + Map singleEntryMap = Collections.singletonMap("key", "value"); + Map emptyMap = Collections.emptyMap(); + + //Collecting Stream to Map + //More examples: https://howtodoinjava.com/java8/collect-stream-to-map/ + Stream stream = Stream.of(new String[][] { + { "Hello", "World" }, + { "John", "Doe" }, + }); + Map map7 = stream.collect(Collectors.toMap(pair -> pair[0], pair -> pair[1])); + } +} diff --git a/src/main/java/com/howtodoinjava/core/datatypes/Employee.java b/src/main/java/com/howtodoinjava/core/datatypes/Employee.java new file mode 100644 index 0000000..5568253 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datatypes/Employee.java @@ -0,0 +1,28 @@ +package com.howtodoinjava.core.datatypes; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class Employee { + + public static void main(String[] args) { + Stream tokenStream = Stream.of("A", "B", "C", "D"); + ArrayList tokenList = tokenStream.collect(Collectors.toCollection(ArrayList::new)); + tokenList.add("e"); + System.out.println(tokenList); + + List list = Arrays.asList("A", "B", "C"); + list.add("e"); + System.out.println(list); + + ArrayList arraylist = new ArrayList<>(Arrays.asList("A", "B", "C")); + } + +} + + diff --git a/src/main/java/com/howtodoinjava/core/datetime/ConvertBetweenMonthNameAndNumber.java b/src/main/java/com/howtodoinjava/core/datetime/ConvertBetweenMonthNameAndNumber.java new file mode 100644 index 0000000..16bdd09 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/ConvertBetweenMonthNameAndNumber.java @@ -0,0 +1,66 @@ +package com.howtodoinjava.core.datetime; + +import java.time.Month; +import java.time.format.TextStyle; +import java.util.Arrays; +import java.util.Locale; +import java.util.Optional; + +public class ConvertBetweenMonthNameAndNumber { + + public static void main(String[] args) { + + // MONTH NUMBER -> NAME + + System.out.println(monthNumberToAbbr(1)); + System.out.println(monthNumberToFullName(1)); + System.out.println(monthNumberToName(1)); + + // MONTH ABBR -> Number + + System.out.println(monthNameToNumber("January")); + System.out.println(monthAbbrToNumber("Jan")); + + // MONTH NAME -> NAME + + System.out.println(monthAbbrToFullName("Jan")); + } + + public static String monthNumberToAbbr(int monthNumber) { + return Month.of(monthNumber).getDisplayName( + TextStyle.SHORT, Locale.getDefault() + ); + } + + public static String monthNumberToFullName(int monthNumber) { + return Month.of(monthNumber).getDisplayName( + TextStyle.FULL, Locale.getDefault() + ); + } + + public static String monthNumberToName(int monthNumber) { + return Month.of(monthNumber).name(); + } + + public static int monthNameToNumber(String monthName) { + return Month.valueOf(monthName.toUpperCase()).getValue(); + } + + public static int monthAbbrToNumber(String abbreviation) { + Optional monthOptional = Arrays.stream(Month.values()) + .filter(month -> month.name().substring(0, 3).equalsIgnoreCase(abbreviation)) + .findFirst(); + + return monthOptional.orElseThrow(IllegalArgumentException::new).getValue(); + } + + public static String monthAbbrToFullName(String abbreviation) { + Optional monthOptional = Arrays.stream(Month.values()) + .filter(month -> month.name().substring(0, 3).equalsIgnoreCase(abbreviation)) + .findFirst(); + + return monthOptional.orElseThrow(IllegalArgumentException::new) + .getDisplayName(TextStyle.FULL, Locale.getDefault()); + } + +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/DayPeriodFormatter.java b/src/main/java/com/howtodoinjava/core/datetime/DayPeriodFormatter.java new file mode 100644 index 0000000..5346cd7 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/DayPeriodFormatter.java @@ -0,0 +1,57 @@ +package com.howtodoinjava.core.datetime; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +public class DayPeriodFormatter { + + static LocalTime night = LocalTime.of(21, 0, 0); + static LocalTime morning = LocalTime.of(6, 0, 0); + static LocalTime afternoon = LocalTime.of(12, 0, 0); + static LocalTime evening = LocalTime.of(18, 0, 0); + static LocalTime almostMidnight = LocalTime.of(23, 59, 59); + static LocalTime midnight = LocalTime.of(0, 0, 0); + + public static void main(String[] args) { + + LocalDateTime localDateTime = LocalDateTime.now(); + + System.out.println(DayPeriodFormatter.formatBeforeJava16(localDateTime, ZoneId.systemDefault())); + System.out.println(DayPeriodFormatter.formatSinceJava16(localDateTime, ZoneId.systemDefault())); + } + + public static String formatBeforeJava16(LocalDateTime localDateTime, ZoneId zoneId) { + + ZonedDateTime zdt = localDateTime.atZone(zoneId); + LocalTime lt = zdt.toLocalTime(); + + DateTimeFormatter formatter + = DateTimeFormatter.ofPattern("yyyy-MMM-dd"); + + String dayTime = ""; + + if ((lt.isAfter(night) && lt.isBefore(almostMidnight)) + || lt.isAfter(midnight) && (lt.isBefore(morning))) { + dayTime = " at night"; + } else if (lt.isAfter(morning) && lt.isBefore(afternoon)) { + dayTime = " in the morning"; + } else if (lt.isAfter(afternoon) && lt.isBefore(evening)) { + dayTime = " in the afternoon"; + } else if (lt.isAfter(evening) && lt.isBefore(night)) { + dayTime = " in the evening"; + } + + return zdt.withZoneSameInstant(zoneId).format(formatter) + dayTime; + } + + public static String formatSinceJava16(LocalDateTime localDateTime, ZoneId zoneId) { + + ZonedDateTime zdt = localDateTime.atZone(zoneId); + DateTimeFormatter formatter + = DateTimeFormatter.ofPattern("yyyy-MMM-dd [B]"); + return zdt.withZoneSameInstant(zoneId).format(formatter); + } +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/DisplayDayOfWeekName.java b/src/main/java/com/howtodoinjava/core/datetime/DisplayDayOfWeekName.java new file mode 100644 index 0000000..418a8c5 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/DisplayDayOfWeekName.java @@ -0,0 +1,41 @@ +package com.howtodoinjava.core.datetime; + +import java.text.DateFormatSymbols; +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.format.TextStyle; +import java.util.Calendar; +import java.util.Locale; +import java.util.stream.IntStream; + +public class DisplayDayOfWeekName { + + public static void main(String[] args) { + //1 + String[] weekdays = DateFormatSymbols.getInstance().getWeekdays(); + IntStream.range(0, weekdays.length) + .filter(t -> !weekdays[t].isBlank()) + .mapToObj(t -> String.format("Day: %d -> %s", + t, weekdays[t])) + .forEach(System.out::println); + + Calendar calendar = Calendar.getInstance(); + int dayOfWeekValue = calendar.get(Calendar.DAY_OF_WEEK); + System.out.println(weekdays[dayOfWeekValue]); + + //2 + DayOfWeek[] days = DayOfWeek.values(); + IntStream.range(0, days.length) + .mapToObj(t -> String.format("Day: %d -> %s", + t, days[t])) + .forEach(System.out::println); + + //3 + LocalDate localDate = LocalDate.now(); + DayOfWeek weekOfTheDay = DayOfWeek.from(localDate); + System.out.println(weekOfTheDay.getValue()); + System.out.println(weekOfTheDay.getDisplayName(TextStyle.FULL, Locale.getDefault())); + System.out.println(weekOfTheDay.getDisplayName(TextStyle.FULL, Locale.FRENCH)); + } + +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/ElapsedTimeSinceMidnight.java b/src/main/java/com/howtodoinjava/core/datetime/ElapsedTimeSinceMidnight.java new file mode 100644 index 0000000..2285674 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/ElapsedTimeSinceMidnight.java @@ -0,0 +1,59 @@ +package com.howtodoinjava.core.datetime; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; + +public class ElapsedTimeSinceMidnight { + + public static void main(String[] args) { + System.out.println(getElapsedSecondsSinceMidnight()); + System.out.println(getElapsedMillisSinceMidnight()); + + System.out.println(getElapsedSecondsSinceMidnightAtZone(ZoneOffset.ofHours(-5))); + System.out.println(getElapsedSecondsSinceMidnightAtZone(ZoneId.of("America/New_York"))); + System.out.println(getElapsedSecondsSinceMidnightAtZone(ZoneOffset.UTC)); + + System.out.println(getElapsedSecondsSinceMidnightUsingLocalDateTime()); + System.out.println(getElapsedSecondsSinceMidnightUsingZonedDateTime()); + } + + public static long getElapsedSecondsSinceMidnightAtZone(ZoneId zoneId) { + + LocalTime currentTime = LocalTime.now(zoneId); + return ChronoUnit.SECONDS.between(LocalTime.MIDNIGHT, currentTime); + } + + public static long getElapsedSecondsSinceMidnight() { + LocalTime midnight = LocalTime.MIDNIGHT; + LocalTime currentTime = LocalTime.now(); + return ChronoUnit.SECONDS.between(midnight, currentTime); + } + + public static long getElapsedMillisSinceMidnight() { + LocalTime midnight = LocalTime.MIDNIGHT; + LocalTime currentTime = LocalTime.now(); + return ChronoUnit.MILLIS.between(midnight, currentTime); + } + + public static long getElapsedSecondsSinceMidnightUsingLocalDateTime() { + + LocalDateTime currentTime = LocalDateTime.now(); + LocalDateTime midnight = LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT); + + return ChronoUnit.SECONDS.between(midnight, currentTime); + } + + public static long getElapsedSecondsSinceMidnightUsingZonedDateTime() { + + ZonedDateTime currentTime = ZonedDateTime.now(); + ZonedDateTime midnight = ZonedDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT, ZoneId.systemDefault()); + + return ChronoUnit.SECONDS.between(midnight, currentTime); + } +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/FirstAndLastDay.java b/src/main/java/com/howtodoinjava/core/datetime/FirstAndLastDay.java new file mode 100644 index 0000000..09f2e2d --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/FirstAndLastDay.java @@ -0,0 +1,39 @@ +package com.howtodoinjava.core.datetime; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; + +public class FirstAndLastDay { + + public static void main(String[] args) { + LocalDate today = LocalDate.of(2024, 4, 26); + + //Week + LocalDate firstDayOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); + LocalDate lastDayOfWeek = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); + + System.out.println(firstDayOfWeek); //2024-04-22 + System.out.println(lastDayOfWeek); //2024-04-22 + + //Month + LocalDate firstDayOfMonth = today.withDayOfMonth(1); + LocalDate lastDayOfMonth = today.withDayOfMonth(today.lengthOfMonth()); + + System.out.println(firstDayOfMonth); //2024-04-01 + System.out.println(lastDayOfMonth); //2024-04-30 + + firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth()); + lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth()); + + System.out.println(firstDayOfMonth); //2024-04-01 + System.out.println(lastDayOfMonth); //2024-04-30 + + //Year + LocalDate firstDayOfYear = today.with(TemporalAdjusters.firstDayOfYear()); + LocalDate lastDayOfYear = today.with(TemporalAdjusters.lastDayOfYear()); + + System.out.println(firstDayOfYear); //2024-01-01 + System.out.println(lastDayOfYear); //2024-12-31 + } +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/FirstLastDayOfYear.java b/src/main/java/com/howtodoinjava/core/datetime/FirstLastDayOfYear.java new file mode 100644 index 0000000..4b9e057 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/FirstLastDayOfYear.java @@ -0,0 +1,20 @@ +package com.howtodoinjava.core.datetime; + +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; + +public class FirstLastDayOfYear { + + public static void main(String[] args) { + int year = 2024; + + LocalDate firstDay = LocalDate.of(year, 1, 1); + System.out.println(firstDay); + + LocalDate lastDay = LocalDate.of(year, 12, 31); + System.out.println(lastDay); + + System.out.println(LocalDate.now().with(TemporalAdjusters.firstDayOfYear())); + System.out.println(LocalDate.now().with(TemporalAdjusters.lastDayOfYear())); + } +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/GetQuarterInfo.java b/src/main/java/com/howtodoinjava/core/datetime/GetQuarterInfo.java new file mode 100644 index 0000000..6e63c5f --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/GetQuarterInfo.java @@ -0,0 +1,32 @@ +package com.howtodoinjava.core.datetime; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.temporal.IsoFields; +import java.time.temporal.TemporalAdjusters; +import net.bytebuddy.asm.Advice.Local; + +public class GetQuarterInfo { + + public static void main(String[] args) { + + LocalDate localDate = LocalDate.now(); + + //What is current quarter + int currentQuarter = localDate.get(IsoFields.QUARTER_OF_YEAR); + System.out.println(currentQuarter); + + String currentQuarterStr = localDate.format(DateTimeFormatter.ofPattern("QQQQ")); + System.out.println(currentQuarterStr); + + //Current quarter start date and end date + LocalDate firstDay = localDate.with(IsoFields.DAY_OF_QUARTER, 1L); + LocalDate lastDay = firstDay.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth()); + System.out.println(firstDay); + System.out.println(lastDay); + + //Quarter between two dates + long quarterCount = IsoFields.QUARTER_YEARS.between(firstDay, lastDay); + System.out.println(quarterCount); + } +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/LocaleExamples.java b/src/main/java/com/howtodoinjava/core/datetime/LocaleExamples.java index 71a7cf7..d447b43 100644 --- a/src/main/java/com/howtodoinjava/core/datetime/LocaleExamples.java +++ b/src/main/java/com/howtodoinjava/core/datetime/LocaleExamples.java @@ -1,12 +1,15 @@ package com.howtodoinjava.core.datetime; +import java.math.RoundingMode; import java.text.DateFormat; import java.text.NumberFormat; +import java.text.ParseException; +import java.util.Currency; import java.util.Date; import java.util.Locale; public class LocaleExamples { - public static void main(final String[] args) { + public static void main(final String[] args) throws ParseException { //1 Get Locale Basic Info Locale enUsLocale = new Locale("EN", "US"); @@ -32,11 +35,43 @@ public static void main(final String[] args) { NumberFormat nf = NumberFormat.getInstance(enUsLocale); System.out.println(nf.format(123456789L)); + //Specifying Language Range + Locale.LanguageRange lr = new Locale.LanguageRange("de-*"); + //5 Format Currency - NumberFormat cf = NumberFormat.getCurrencyInstance(locale); + /*NumberFormat cf = NumberFormat.getCurrencyInstance(locale); String currency = cf.format(123.456); - System.out.println(currency); + System.out.println(currency);*/ + + + double amount = 1234.567; + NumberFormat localizedCurrencyFormat = NumberFormat.getCurrencyInstance(Locale.US); + String formattedCurrency = localizedCurrencyFormat.format(amount); + + System.out.println(formattedCurrency); // Output: $1,234.57 + + NumberFormat frCurrencyFormat = NumberFormat.getCurrencyInstance(Locale.FRANCE); + String frFormattedCurrency = frCurrencyFormat.format(amount); + + System.out.println(frFormattedCurrency); // Output: $1,234.57 + + String currencyString = "$1,234.57"; + + try { + Number parsedNumber = localizedCurrencyFormat.parse(currencyString); + double parsedAmount = parsedNumber.doubleValue(); + System.out.println(parsedAmount); // Output: 1234.57 + } catch (ParseException e) { + e.printStackTrace(); + } - //6 Decimal Format + try { + NumberFormat roundedCurrencyFormat = NumberFormat.getCurrencyInstance(); + roundedCurrencyFormat.setRoundingMode(RoundingMode.HALF_UP); + String formattedValue = roundedCurrencyFormat.format(123456.789d); + System.out.println(formattedValue); // Output: 1234.57 + } catch (Exception e) { + e.printStackTrace(); + } } } diff --git a/src/main/java/com/howtodoinjava/core/datetime/LocationBasedDateFormatting.java b/src/main/java/com/howtodoinjava/core/datetime/LocationBasedDateFormatting.java index 8ae4812..1f5a8dd 100644 --- a/src/main/java/com/howtodoinjava/core/datetime/LocationBasedDateFormatting.java +++ b/src/main/java/com/howtodoinjava/core/datetime/LocationBasedDateFormatting.java @@ -1,5 +1,8 @@ package com.howtodoinjava.core.datetime; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -7,17 +10,49 @@ import java.util.Locale; public class LocationBasedDateFormatting { + public static void main(final String[] args) { - ZonedDateTime today = ZonedDateTime.now(); - - DateTimeFormatter format = DateTimeFormatter - .ofLocalizedDateTime(FormatStyle.MEDIUM) - .withLocale(Locale.forLanguageTag("es")) - .withZone(ZoneId.of("UTC")); - //.withLocale(LocaleContextHolder.getLocale()); - - String formmatedDate = format.format(today); - System.out.println(formmatedDate); + Locale locale = Locale.forLanguageTag("es"); + + DateTimeFormatter formatter = DateTimeFormatter + .ofLocalizedDateTime(FormatStyle.MEDIUM) + .withLocale(locale); + + String formattedDate = formatter.format(ZonedDateTime.now()); + System.out.println(formattedDate); // 14 ene 2024, 8:21:54 + + DateTimeFormatter chFormatter = DateTimeFormatter + .ofLocalizedDateTime(FormatStyle.MEDIUM) + .withLocale(Locale.forLanguageTag("zh")); + + formattedDate = chFormatter.format(ZonedDateTime.now()); + System.out.println(formattedDate); // 2024年1月14日 08:21:54 + + Locale.setDefault(Locale.GERMANY); + + String ld = LocalDate.now().format( + DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)); + System.out.println(ld); // 14. Januar 2024 + + String lt = LocalTime.now().format( + DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)); + System.out.println(lt); // 08:14 + + String ldt = LocalDateTime.now().format( + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)); + System.out.println(ldt); // 14.01.2024, 08:14:25 + + // ofLocalizedPattern() examples + + Locale.setDefault(Locale.ENGLISH); + + String ld1 = LocalDate.now().format( + DateTimeFormatter.ofLocalizedPattern("yMM")); + System.out.println(ld1); // 01.2024 + + String ld2 = LocalDate.now().format( + DateTimeFormatter.ofLocalizedPattern("yMMM")); + System.out.println(ld2); // 01.2024 } } diff --git a/src/main/java/com/howtodoinjava/core/datetime/SplitDateRangeIntoEqualIntervals.java b/src/main/java/com/howtodoinjava/core/datetime/SplitDateRangeIntoEqualIntervals.java new file mode 100644 index 0000000..cd28d05 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/SplitDateRangeIntoEqualIntervals.java @@ -0,0 +1,110 @@ +package com.howtodoinjava.core.datetime; + +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; +import static java.time.temporal.ChronoField.YEAR; + +import java.time.DateTimeException; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.Year; +import java.time.YearMonth; +import java.time.chrono.Chronology; +import java.time.chrono.IsoChronology; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAccessor; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class SplitDateRangeIntoEqualIntervals { + + public static void main(String[] args) { + + int equalParts = 15; + LocalDateTime start = LocalDateTime.of(2021, 10, 1, 0, 0, 0); + LocalDateTime end = LocalDateTime.of(2022, 03, 31, 0, 0, 0); + + System.out.println(split_LocalDateTime_Range_In_N_Equal_Intervals(start, end, equalParts)); + System.out.println(split_LocalDate_Range_Into_Months(start.toLocalDate(), end.toLocalDate())); + System.out.println(split_LocalDate_Range_Into_Weeks(start.toLocalDate(), end.toLocalDate())); + } + + public static List split_LocalDateTime_Range_In_N_Equal_Intervals( + LocalDateTime start, LocalDateTime end, int n) { + + Duration range = Duration.between(start, end); + Duration interval = range.dividedBy(n - 1); + List listOfDates = new ArrayList<>(); + LocalDateTime timeline = start; + for (int i = 0; i < n - 1; i++) { + listOfDates.add(timeline); + timeline = timeline.plus(interval); + } + listOfDates.add(end); + return listOfDates; + } + + public static List split_LocalDate_Range_Into_Days( + LocalDate startDate, LocalDate endDate) { + + long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate); + return IntStream.iterate(0, i -> i + 1) + .limit(numOfDaysBetween) + .mapToObj(i -> startDate.plusDays(i)) + .collect(Collectors.toList()); + } + + public static List split_LocalDate_Range_Into_Weeks( + LocalDate startDate, LocalDate endDate) { + + long numOfDaysBetween = ChronoUnit.WEEKS.between(startDate, endDate); + return IntStream.iterate(0, i -> i + 1) + .limit(numOfDaysBetween) + .mapToObj(i -> YearWeek.from(startDate.plusWeeks(i))) + .collect(Collectors.toList()); + } + + public static List split_LocalDate_Range_Into_Months( + LocalDate startDate, LocalDate endDate) { + + long numOfDaysBetween = ChronoUnit.MONTHS.between(startDate, endDate); + return IntStream.iterate(0, i -> i + 1) + .limit(numOfDaysBetween) + .mapToObj(i -> YearMonth.from(startDate.plusMonths(i))) + .collect(Collectors.toList()); + } + + public static List split_LocalDate_Range_Into_Years( + LocalDate startDate, LocalDate endDate) { + + long numOfDaysBetween = ChronoUnit.YEARS.between(startDate, endDate); + return IntStream.iterate(0, i -> i + 1) + .limit(numOfDaysBetween) + .mapToObj(i -> Year.from(startDate.plusYears(i))) + .collect(Collectors.toList()); + } +} + +record YearWeek(int year, int week) { + + public static YearWeek from(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); + try { + if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { + temporal = LocalDate.from(temporal); + } + return new YearWeek(temporal.get(YEAR), temporal.get(ALIGNED_WEEK_OF_YEAR)); + } catch (DateTimeException ex) { + throw new DateTimeException( + STR."Unable to obtain YearWeek from TemporalAccessor: \{temporal} of type \{temporal.getClass().getName()}", ex); + } + } + + @Override + public String toString() { + return STR."\{year}-\{week}"; + } +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/StopWatchExamples.java b/src/main/java/com/howtodoinjava/core/datetime/StopWatchExamples.java new file mode 100644 index 0000000..6b981cf --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/StopWatchExamples.java @@ -0,0 +1,86 @@ +package com.howtodoinjava.core.datetime; + +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.TimeUnit; +import org.apache.commons.lang3.time.StopWatch; + +public class StopWatchExamples { + + public static void main(String[] args) throws InterruptedException { + + // 1- Custom Stopwatch + + Stopwatch stopwatch = new Stopwatch(); + stopwatch.start(); + Thread.sleep(2000L); + stopwatch.stop(); + System.out.println(STR."Elapsed Time : \{stopwatch.getElapsedTime()}"); + System.out.println(STR."Elapsed Time : \{stopwatch.getElapsedTime(TimeUnit.NANOSECONDS)}"); + + // 2 - Apache Commons + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + Thread.sleep(2000L); + stopWatch.stop(); + System.out.println(STR."Elapsed Time : \{stopWatch.getTime()}"); + System.out.println(STR."Elapsed Time in Nano: \{stopWatch.getTime(TimeUnit.NANOSECONDS)}"); + } + + // elapsed time in milliseconds + public long elapsedTimeToMillis(long nanotime) { + + return TimeUnit.MILLISECONDS.convert( + nanotime, TimeUnit.NANOSECONDS); + } + + // elapsed time in seconds + public long elapsedTimeToSeconds(long nanotime) { + + return TimeUnit.SECONDS.convert( + nanotime, TimeUnit.NANOSECONDS); + } +} + +final class Stopwatch { + + private Instant startTime; + private Instant endTime; + private boolean running; + + public void start() { + if (!running) { + startTime = Instant.now(); + running = true; + } else { + System.out.println("Stopwatch is already running. Use stop() before starting again."); + } + } + + public void stop() { + if (running) { + endTime = Instant.now(); + running = false; + } else { + System.out.println("Stopwatch is not running. Use start() before stopping."); + } + } + + public Duration getElapsedDuration() { + if (running) { + return Duration.between(startTime, Instant.now()); + } else { + return Duration.between(startTime, endTime); + } + } + + public long getElapsedTime() { + Duration duration = getElapsedDuration(); + return duration.toMillis(); + } + + public long getElapsedTime(TimeUnit timeUnit) { + return timeUnit.convert(getElapsedTime(), TimeUnit.MILLISECONDS); + } +} diff --git a/src/main/java/com/howtodoinjava/core/datetime/WeeksBetweenDates.java b/src/main/java/com/howtodoinjava/core/datetime/WeeksBetweenDates.java new file mode 100644 index 0000000..8599fe2 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/datetime/WeeksBetweenDates.java @@ -0,0 +1,19 @@ +package com.howtodoinjava.core.datetime; + +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; + +public class WeeksBetweenDates { + + public static void main(String[] args) { + LocalDate startLd = LocalDate.of(2023, 8, 5); + LocalDate endLd = LocalDate.of(2023, 9, 5); + long numWeeks = ChronoUnit.WEEKS.between(startLd, endLd); + System.out.println(numWeeks); + + long daysDifference = ChronoUnit.DAYS.between(startLd, endLd); // 31 + int extraDays = Long.valueOf(daysDifference % 7).intValue(); //3 + System.out.println(extraDays); + } + +} diff --git a/src/main/java/com/howtodoinjava/core/jmh/IntToStringBenchmark.java b/src/main/java/com/howtodoinjava/core/jmh/IntToStringBenchmark.java new file mode 100644 index 0000000..d614ab1 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/jmh/IntToStringBenchmark.java @@ -0,0 +1,75 @@ +package com.howtodoinjava.core.jmh; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@State(Scope.Thread) +public class IntToStringBenchmark { + + private ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current(); + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void methodIntegerToString(Blackhole blackhole) { + int i = threadLocalRandom.nextInt(1_00_000, 9_99_999); + String s = Integer.toString(i); + blackhole.consume(s); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void dmethodIntegerToStringV2(Blackhole blackhole) { + Integer i = threadLocalRandom.nextInt(1_00_000, 9_99_999); + String s = Integer.toString(i); + blackhole.consume(s); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void cmethodStringValueOf(Blackhole blackhole) { + int i = threadLocalRandom.nextInt(1_00_000, 9_99_999); + String s = String.valueOf(i); + blackhole.consume(s); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void bmethodStringFormat(Blackhole blackhole) { + int i = threadLocalRandom.nextInt(1_00_000, 9_99_999); + String s = String.format("%d", i); + blackhole.consume(s); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void amethodStringTemplate(Blackhole blackhole) { + int i = threadLocalRandom.nextInt(1_00_000, 9_99_999); + String s = STR."\{i}"; + blackhole.consume(s); + } + + public static void main(String[] args) throws Exception { + + Options opt = new OptionsBuilder() + .include(IntToStringBenchmark.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/main/java/com/howtodoinjava/core/optional/OptionalExamples.java b/src/main/java/com/howtodoinjava/core/optional/OptionalExamples.java new file mode 100644 index 0000000..4949214 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/optional/OptionalExamples.java @@ -0,0 +1,20 @@ +package com.howtodoinjava.core.optional; + +import java.util.Optional; + +public class OptionalExamples { + + public static void main(String[] args) { + Optional optionalValue = Optional.of("Hello"); + String result = optionalValue.orElse( generateDefaultValue() ); // Using orElse() + System.out.println(STR."Result using orElse(): \{result}"); + + result = optionalValue.orElseGet(() -> generateDefaultValue() ); // Using orElseGet() + System.out.println(STR."Result using orElseGet(): \{result}"); + } + + public static String generateDefaultValue() { + System.out.println("Generating Default Value"); + return "Default Value"; + } +} diff --git a/src/main/java/com/howtodoinjava/core/security/Base64Example.java b/src/main/java/com/howtodoinjava/core/security/Base64Example.java new file mode 100644 index 0000000..ffc27f5 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/security/Base64Example.java @@ -0,0 +1,16 @@ +package com.howtodoinjava.core.security; + +import java.util.Base64; + +public class Base64Example { + + public static void main(String[] args) { + String originalInput = "hello world"; + String encodedString = Base64.getEncoder().withoutPadding().encodeToString(originalInput.getBytes()); + System.out.println(encodedString); + + byte[] decodedBytes = Base64.getDecoder().decode(encodedString); + String decodedString = new String(decodedBytes); + System.out.println(decodedString); + } +} diff --git a/src/main/java/com/howtodoinjava/core/security/Base64FileEncodeExample.java b/src/main/java/com/howtodoinjava/core/security/Base64FileEncodeExample.java new file mode 100644 index 0000000..3dd4396 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/security/Base64FileEncodeExample.java @@ -0,0 +1,29 @@ +package com.howtodoinjava.core.security; + +import jakarta.xml.bind.DatatypeConverter; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Base64; + +public class Base64FileEncodeExample { + + public static void main(String[] args) throws IOException { + //TextFile + File file = new File("c:/temp/output.txt"); + String encoded = Base64.getEncoder() + .encodeToString(Files.readAllBytes(file.toPath())); + System.out.println(encoded); + + byte[] decoded = Base64.getDecoder().decode(encoded); + System.out.println(new String(decoded)); + + //ImageFile + File inImage = new File("c:/temp/avni.jpg"); + File outImage = new File("c:/temp/avni_new.jpg"); + byte[] encodedImageBytes = Base64.getEncoder().encode(Files.readAllBytes(inImage.toPath())); + byte[] decodedImageBytes = Base64.getDecoder().decode(encodedImageBytes); + Files.write(outImage.toPath(), decodedImageBytes); + } + +} diff --git a/src/main/java/com/howtodoinjava/core/security/concurrent/AES256EncryptionTask.java b/src/main/java/com/howtodoinjava/core/security/concurrent/AES256EncryptionTask.java new file mode 100644 index 0000000..067e655 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/security/concurrent/AES256EncryptionTask.java @@ -0,0 +1,64 @@ +package com.howtodoinjava.core.security.concurrent; + +import java.security.SecureRandom; +import java.security.spec.KeySpec; +import java.util.Base64; +import java.util.concurrent.Callable; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; + +public class AES256EncryptionTask implements Callable { + + private static final int KEY_LENGTH = 256; + private static final int ITERATION_COUNT = 65536; + + private String strToEncrypt; + private String secretKey; + private String salt; + + public AES256EncryptionTask(String strToEncrypt, String secretKey, String salt) { + this.strToEncrypt = strToEncrypt; + this.secretKey = secretKey; + this.salt = salt; + } + + @Override + public String call() throws Exception { + return encrypt(strToEncrypt, secretKey, salt); + } + + public String encrypt(String strToEncrypt, String secretKey, String salt) { + + try { + + SecureRandom secureRandom = new SecureRandom(); + byte[] iv = new byte[16]; + secureRandom.nextBytes(iv); + IvParameterSpec ivspec = new IvParameterSpec(iv); + + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), ITERATION_COUNT, + KEY_LENGTH); + SecretKey tmp = factory.generateSecret(spec); + SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES"); + + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec); + + byte[] cipherText = cipher.doFinal(strToEncrypt.getBytes("UTF-8")); + byte[] encryptedData = new byte[iv.length + cipherText.length]; + System.arraycopy(iv, 0, encryptedData, 0, iv.length); + System.arraycopy(cipherText, 0, encryptedData, iv.length, cipherText.length); + + return Base64.getEncoder().encodeToString(encryptedData); + } catch (Exception e) { + // Handle the exception properly + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/com/howtodoinjava/core/security/concurrent/Demo.java b/src/main/java/com/howtodoinjava/core/security/concurrent/Demo.java new file mode 100644 index 0000000..dcb014e --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/security/concurrent/Demo.java @@ -0,0 +1,48 @@ +package com.howtodoinjava.core.security.concurrent; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.stream.Stream; + +public class Demo { + + public static void main(String[] args) { + + // Define your secret key and salt (keep these secure and don't hardcode in production) + String secretKey = "MySecretKey"; + String salt = "MySalt"; + + Random rand = new Random(); + List dataLines = Stream + .generate(() -> "Token Value : " + rand.nextInt(100)) + .limit(100) + .toList(); + + int numberOfThreads = 4; // Adjust based on your system capabilities + ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); + + List> futures = new ArrayList<>(); + for (String dataLine : dataLines) { + // Create new AES256 instance for each line or data chunk + AES256EncryptionTask task = new AES256EncryptionTask(dataLine, secretKey, salt); + futures.add(executor.submit(task)); + } + + // Wait for all tasks to complete and collect results + for (Future future : futures) { + try { + String encryptedData = future.get(); + System.out.println(encryptedData); + // Process the encrypted data, e.g., write to file + } catch (Exception e) { + e.printStackTrace(); + } + } + + executor.shutdown(); + } +} diff --git a/src/main/java/com/howtodoinjava/core/serialization/SerializeObjectToString.java b/src/main/java/com/howtodoinjava/core/serialization/SerializeObjectToString.java new file mode 100644 index 0000000..3e26005 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/serialization/SerializeObjectToString.java @@ -0,0 +1,88 @@ +package com.howtodoinjava.core.serialization; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.google.gson.Gson; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Base64; + +public class SerializeObjectToString { + + public static void main(String[] args) throws IOException, ClassNotFoundException { + //1 Using Core Java + + Person person = new Person(1, "Lokesh"); + String encodedString; + Person deserializedPerson; + + /*String encodedString = SerializationUtils.objectToString(person); + System.out.println(encodedString); + + Person deserializedPerson = (Person) SerializationUtils.stringToObject(encodedString); + System.out.println(deserializedPerson);*/ + + //2 Using Jackson + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(person); + System.out.println(json); + + deserializedPerson = mapper.readValue(json, Person.class); + System.out.println(deserializedPerson); + + //3 Gson + Gson gson = new Gson(); + json = gson.toJson(person); + System.out.println(json); + + deserializedPerson = gson.fromJson(json, Person.class); + System.out.println(deserializedPerson); + + //4 Base64 encoded json + String base64EncodedString = Base64.getEncoder().encodeToString(json.getBytes()); + System.out.println(base64EncodedString); + + String decodedJson = new String(Base64.getDecoder().decode(base64EncodedString)); + deserializedPerson = mapper.readValue(decodedJson, Person.class); + System.out.println(deserializedPerson); + + //xml + + XmlMapper xmlMapper = new XmlMapper(); + String xml = xmlMapper.writeValueAsString(person); + System.out.println(xml); + + deserializedPerson = xmlMapper.readValue(xml, Person.class); + System.out.println(deserializedPerson); + } + + record Person(long id, String name) { + } +} + +class SerializationUtils { + + public static String objectToString(Serializable obj) throws IOException { + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream ois = new ObjectOutputStream(baos)) { + + ois.writeObject(obj); + return Base64.getEncoder().encodeToString(baos.toByteArray()); + } + } + + public static Object stringToObject(String obj) + throws IOException, ClassNotFoundException { + + byte[] data = Base64.getDecoder().decode(obj); + try (ObjectInputStream ois = new ObjectInputStream( + new ByteArrayInputStream(data))) { + return ois.readObject(); + } + } +} diff --git a/src/main/java/com/howtodoinjava/core/streams/FilterAMap.java b/src/main/java/com/howtodoinjava/core/streams/FilterAMap.java index e52075a..ef88b79 100644 --- a/src/main/java/com/howtodoinjava/core/streams/FilterAMap.java +++ b/src/main/java/com/howtodoinjava/core/streams/FilterAMap.java @@ -1,16 +1,21 @@ package com.howtodoinjava.core.streams; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Comparator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; -import lombok.AllArgsConstructor; import lombok.Data; public class FilterAMap { + @SuppressWarnings("unused") public static void main(String[] args) { + Map usersMap = Map.of( 1, new User(1, "Alex"), 2, new User(2, "Allen"), @@ -21,8 +26,8 @@ public static void main(String[] args) { 7, new User(7, "Don"), 8, new User(8, "Dave")); - //1 - List idList = List.of(1,3,5,7); + // Collect Keys filtered by List of Keys + List idList = List.of(1, 3, 5, 7); Map filteredMap1 = usersMap.entrySet() .stream() @@ -31,39 +36,133 @@ public static void main(String[] args) { System.out.println(filteredMap1); + // Collect entries filtered by List of Keys + Map filteredMap2 = usersMap.entrySet() .stream() - .filter(entry -> idList.contains(entry.getValue().getId())) + .filter(entry -> idList.contains(entry.getValue().id())) .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); System.out.println(filteredMap2); - //2 + // Collect Values filtered by List of Keys List usersList1 = usersMap.values() .stream() - .filter(user -> idList.contains(user.getId())) - .collect(Collectors.toUnmodifiableList()); + .filter(user -> idList.contains(user.id())) + .toList(); System.out.println(usersList1); //3 List usersList2 = new ArrayList<>(); - usersMap.entrySet().forEach( entry -> { - if(idList.contains(entry.getValue().getId())) { - usersList2.add(entry.getValue()); + usersMap.forEach((_, value) -> { + if (idList.contains(value.id())) { + usersList2.add(value); } }); System.out.println(usersList2); + + System.out.println("===================="); + + // Using Generic filters + Predicate predicate = key -> key > 4; + Comparator comparator = Comparator.comparing(Function.identity()); + + Map filteredMap = Filters.byKey(usersMap, predicate); + System.out.println(filteredMap); + + Map filteredAndSortedMap = Filters.sortedByKey(usersMap, predicate, comparator); + System.out.println(filteredAndSortedMap); + + Predicate valuePredicate = user -> user.name().startsWith("D"); + Comparator valueComparator = Comparator.comparing(User::name); + + Map filteredMapByValue = Filters.byValue(usersMap, valuePredicate); + System.out.println(filteredMapByValue); + + Map filteredAndSortedMapByValue = Filters.sortedByValue(usersMap, valuePredicate, + valueComparator); + System.out.println(filteredAndSortedMapByValue); + + Map filteredMapByKeyAndValue = Filters.byValue( + Filters.byKey(usersMap, predicate), valuePredicate); + System.out.println(filteredMapByKeyAndValue); + + Map filteredMapByKeyAndValue_V2 = usersMap.entrySet().stream() + .filter((entry) -> entry.getKey() > 4 && entry.getValue().name().startsWith("D")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + System.out.println(filteredMapByKeyAndValue); } + static final class Filters { + + private Filters() { + throw new AssertionError("Cannot be instantiated"); + } + + public static Map byKey(Map map, Predicate predicate) { + + Objects.requireNonNull(map); + Objects.requireNonNull(predicate); + + return map.entrySet() + .stream() + .filter(item -> predicate.test(item.getKey())) + .collect(Collectors.toMap( + Map.Entry::getKey, Map.Entry::getValue)); + } + + public static Map sortedByKey( + Map map, Predicate predicate, Comparator c) { + + Objects.requireNonNull(map); + Objects.requireNonNull(predicate); + Objects.requireNonNull(c); + + return map.entrySet() + .stream() + .filter(item -> predicate.test(item.getKey())) + .sorted(Map.Entry.comparingByKey(c)) + .collect(Collectors.toMap( + Map.Entry::getKey, Map.Entry::getValue, + (_, c2) -> c2, LinkedHashMap::new)); + } + + + public static Map byValue( + Map map, Predicate predicate) { + + Objects.requireNonNull(map); + Objects.requireNonNull(predicate); + + return map.entrySet() + .stream() + .filter(item -> predicate.test(item.getValue())) + .collect(Collectors.toMap( + Map.Entry::getKey, Map.Entry::getValue)); + } + + public static Map sortedByValue(Map map, + Predicate predicate, Comparator c) { + + Objects.requireNonNull(map); + Objects.requireNonNull(predicate); + Objects.requireNonNull(c); + + return map.entrySet() + .stream() + .filter(item -> predicate.test(item.getValue())) + .sorted(Map.Entry.comparingByValue(c)) + .collect(Collectors.toMap( + Map.Entry::getKey, Map.Entry::getValue, + (_, c2) -> c2, LinkedHashMap::new)); + } + } } -@Data -@AllArgsConstructor -class User { - Integer id; - String name; +record User(Integer id, String name) { + } diff --git a/src/main/java/com/howtodoinjava/core/streams/FilteringNestedCollections.java b/src/main/java/com/howtodoinjava/core/streams/FilteringNestedCollections.java new file mode 100644 index 0000000..743343c --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/streams/FilteringNestedCollections.java @@ -0,0 +1,86 @@ +package com.howtodoinjava.core.streams; + +import java.util.List; +import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import lombok.Data; + +public class FilteringNestedCollections { + + public static void main(String[] args) { + + List accStmts = List.of( + new AccountStatement(1, "A001", List.of( + new Transaction(1, 100, "A001"), + new Transaction(2, 60, "A001"), + new Transaction(3, 550, "A001"))), + new AccountStatement(2, "A002", List.of( + new Transaction(4, 200, "A002"), + new Transaction(5, 160, "A002"), + new Transaction(6, 100, "A002"))), + new AccountStatement(3, "A003", List.of( + new Transaction(7, 10, "A003"), + new Transaction(8, 20, "A003"), + new Transaction(9, 3040, "A003")))); + + List transactionsMoreThan500 = accStmts.stream() + .flatMap(stmt -> stmt.getTransactions().stream()) + .filter(transaction -> transaction.getAmount() > 500) + .collect(Collectors.toList()); + + System.out.println(transactionsMoreThan500); + + List transactionsMoreThan500_V2 = accStmts.stream() + .mapMulti((stmt, consumer) -> { + for (Transaction t : stmt.getTransactions()) { + if (t.getAmount() > 500) { + consumer.accept(t); + } + } + }) + .collect(Collectors.toList()); + + System.out.println(transactionsMoreThan500_V2); + + List stmtHavingTransactionsMoreThan500 = accStmts.stream() + .mapMulti((stmt, consumer) -> { + for (Transaction t : stmt.getTransactions()) { + if (t.getAmount() > 500) { + consumer.accept(stmt); + break; + } + } + }) + .collect(Collectors.toList()); + + System.out.println(stmtHavingTransactionsMoreThan500); + + List stmtHavingTransactionsMoreThan500_V2 = accStmts.stream() + .filter( + stmt -> stmt.getTransactions() + .stream() + .anyMatch(transaction -> transaction.getAmount() > 500) + ) + .collect(Collectors.toList()); + + System.out.println(stmtHavingTransactionsMoreThan500_V2); + } +} + +@Data +@AllArgsConstructor +class AccountStatement { + + private long id; + private String accountNumber; + private List transactions; +} + +@Data +@AllArgsConstructor +class Transaction { + + private long id; + private double amount; + private String accountNumber; +} diff --git a/src/main/java/com/howtodoinjava/core/streams/MapMultiExample.java b/src/main/java/com/howtodoinjava/core/streams/MapMultiExample.java new file mode 100644 index 0000000..c44b077 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/streams/MapMultiExample.java @@ -0,0 +1,90 @@ +package com.howtodoinjava.core.streams; + +import java.util.List; +import java.util.stream.Collectors; + +public class MapMultiExample { + + public static void main(String[] args) { + + List numbers = List.of(1, 2, 3); + + List multiples = numbers.stream().mapMulti((num, downstream) -> { + downstream.accept(num); + downstream.accept(num * num); // Add the square of the number + downstream.accept(num * num * num); // Add the cube of the number + }).toList(); + + System.out.println(multiples); // Output: [2, 3, 4, 6, 6, 9, 8, 12, 10, 15] + + // second example + + // Sample list of transactions + List transactions = List.of( + new Transaction("T1", 100, TransactionType.DEPOSIT), + new Transaction("T2", 50, TransactionType.WITHDRAWAL), + new Transaction("T3", 200, TransactionType.WITHDRAWAL)); + + // Process transactions and generate transaction events + List transactionEvents = transactions.stream() + .mapMulti((transaction, downstream) -> { + if (transaction.getType() == TransactionType.DEPOSIT) { + downstream.accept(new TransactionEvent("Deposit", transaction.getAmount())); + } else if (transaction.getType() == TransactionType.WITHDRAWAL) { + downstream.accept(new TransactionEvent("Withdrawal", transaction.getAmount())); + // If withdrawal amount is greater than 100, generate an additional fraud alert event + if (transaction.getAmount() > 100) { + downstream.accept(new TransactionEvent("Fraud Alert", transaction.getAmount())); + } + } + }).toList(); + + // Print the generated transaction events + transactionEvents.forEach(System.out::println); + } + + static class Transaction { + + private String id; + private double amount; + private TransactionType type; + + public Transaction(String id, double amount, TransactionType type) { + this.id = id; + this.amount = amount; + this.type = type; + } + + public String getId() { + return id; + } + + public double getAmount() { + return amount; + } + + public TransactionType getType() { + return type; + } + } + + static class TransactionEvent { + + private String type; + private double amount; + + public TransactionEvent(String type, double amount) { + this.type = type; + this.amount = amount; + } + + @Override + public String toString() { + return "TransactionEvent{" + "type='" + type + '\'' + ", amount=" + amount + '}'; + } + } + + enum TransactionType { + DEPOSIT, WITHDRAWAL + } +} \ No newline at end of file diff --git a/src/main/java/com/howtodoinjava/core/streams/MethodReferenceVsLambdaExamples.java b/src/main/java/com/howtodoinjava/core/streams/MethodReferenceVsLambdaExamples.java new file mode 100644 index 0000000..2f2d1c4 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/streams/MethodReferenceVsLambdaExamples.java @@ -0,0 +1,51 @@ +package com.howtodoinjava.core.streams; + +import java.util.function.Function; +import lombok.Data; + +public class MethodReferenceVsLambdaExamples { + + public static void main(String[] args) { + + System.out.println("Creating method reference"); + Function methodRef = Person::getFullName; + + System.out.println("Creating lambda expression"); + Function lambdaRef = (person) -> person.getFullName(); + + Person person = new Person("Lokesh", "Gupta"); + + System.out.println("a"); + System.out.println(methodRef.apply(person)); + System.out.println(methodRef.apply(person)); + System.out.println(methodRef.apply(person)); + + System.out.println("b"); + System.out.println(lambdaRef.apply(person)); + System.out.println(lambdaRef.apply(person)); + System.out.println(lambdaRef.apply(person)); + + + } + + @Data + static class Person { + private String firstName; + private String lastName; + + public Person() { + System.out.println("Default Constructor called."); + } + + public Person(String firstName, String lastName) { + System.out.println("Custom Constructor called."); + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFullName() { + return STR."\{firstName} \{lastName}"; + } + } +} + diff --git a/src/main/java/com/howtodoinjava/core/streams/StreamContainsAnyContainsAll.java b/src/main/java/com/howtodoinjava/core/streams/StreamContainsAnyContainsAll.java new file mode 100644 index 0000000..4b85a16 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/streams/StreamContainsAnyContainsAll.java @@ -0,0 +1,94 @@ +package com.howtodoinjava.core.streams; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.junit.jupiter.api.Assertions; + +public class StreamContainsAnyContainsAll { + + public static void main(String[] args) { + List cars = Arrays.asList( + new Car("Dacia", "diesel", 100), + new Car("Lexus", "gasoline", 300), + new Car("Ford", "electric", 200) + ); + + Car car1 = new Car("Dacia", "diesel", 100); //Present in original list + Car car2 = new Car("Ford", "electric", 80); + Car car3 = new Car("Chevrolet", "electric", 150); + + Assertions.assertTrue(StreamUtils.contains(cars.stream(), car1)); + Assertions.assertFalse(StreamUtils.contains(cars.stream(), car2)); + + Assertions.assertTrue(StreamUtils.containsAny(cars.stream(), car1, car2)); + Assertions.assertFalse(StreamUtils.containsAny(cars.stream(), car2, car3)); + Assertions.assertTrue(StreamUtils.containsAny(cars.stream(), List.of(car1, car2, car3))); + Assertions.assertTrue(StreamUtils.containsAny(cars.stream(), Stream.of(car1, car2, car3))); + + + Assertions.assertTrue(StreamUtils.containsAll(cars.stream(), car1)); + Assertions.assertFalse(StreamUtils.containsAll(cars.stream(), car1, car3)); + Assertions.assertTrue(StreamUtils.containsAll(cars.stream(), List.of(car1))); + Assertions.assertFalse(StreamUtils.containsAll(cars.stream(), Stream.of(car2))); + } +} + +@Data +@AllArgsConstructor +@NoArgsConstructor +class Car { + + String model; + String fuel; + Integer capacity; +} + +final class StreamUtils { + + private StreamUtils() { + // Private constructor to prevent instantiation + } + + public static boolean contains(Stream stream, T element) { + Objects.requireNonNull(stream); + Objects.requireNonNull(element); + return stream.anyMatch(Predicate.isEqual(element)); + } + + public static boolean containsAny(Stream stream, Collection elements) { + return containsAny(stream, elements.stream()); + } + + public static boolean containsAny(Stream stream, T... elements) { + return containsAny(stream, Stream.of(elements)); + } + + public static boolean containsAny(Stream stream, Stream elements) { + Objects.requireNonNull(stream); + Objects.requireNonNull(elements); + return elements.anyMatch(stream.collect(Collectors.toSet())::contains); + } + + public static boolean containsAll(Stream stream, Collection elements) { + return containsAll(stream, elements.stream()); + } + + public static boolean containsAll(Stream stream, T... elements) { + return containsAll(stream, Stream.of(elements)); + } + + public static boolean containsAll(Stream stream, Stream elements) { + Objects.requireNonNull(stream); + Objects.requireNonNull(elements); + return elements.allMatch(stream.collect(Collectors.toSet())::contains); + } +} diff --git a/src/main/java/com/howtodoinjava/core/streams/TeeingCollectorExample.java b/src/main/java/com/howtodoinjava/core/streams/TeeingCollectorExample.java new file mode 100644 index 0000000..74d62c9 --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/streams/TeeingCollectorExample.java @@ -0,0 +1,8 @@ +package com.howtodoinjava.core.streams; + +public class TeeingCollectorExample { + + public static void main(String[] args) { + + } +} diff --git a/src/main/java/com/howtodoinjava/core/string/MultilineStringExample.java b/src/main/java/com/howtodoinjava/core/string/MultilineStringExample.java new file mode 100644 index 0000000..f74ed3a --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/string/MultilineStringExample.java @@ -0,0 +1,84 @@ +package com.howtodoinjava.core.string; + +import java.util.StringJoiner; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@SuppressWarnings("StringTemplateMigration") +public class MultilineStringExample { + + public static void main(String[] args) { + + //Text Blocks + String content = """ + Line 1 + 'Line 2' + "Line 3" + Line 4 + """; + + System.out.println(content); + + String json = """ + { + "name": "John Doe", + "age": 30, + "city": "New York" + } + """; + System.out.println(json); + + // String Concatenation + + String NEW_LINE = System.getProperty("line.separator"); + + content = "Line 1" + + NEW_LINE + + "'Line 2'" + + NEW_LINE + + "\"Line 3\"" + + NEW_LINE + + "Line 4 "; + + System.out.println(content); + + StringBuffer sb = new StringBuffer(); + + content = sb.append("Line 1") + .append(NEW_LINE) + .append("'Line 2'") + .append(NEW_LINE) + .append("\"Line 3\"") + .append(NEW_LINE) + .append("Line 4 ").toString(); + + System.out.println(content); + + //String Join + content = String.join(NEW_LINE, + "Line 1", + "'Line 2'", + "\"Line 3\"", + "Line 4 "); + + System.out.println(content); + + //StringJoiner + + StringJoiner stringJoiner = new StringJoiner(NEW_LINE); + + content = stringJoiner.add("Line 1") + .add("'Line 2'") + .add("\"Line 3\"") + .add("Line 4 ").toString(); + + System.out.println(content); + + //Stream API + + content = Stream.of("Line 1", "'Line 2'", "\"Line 3\"", "Line 4 ") + .collect(Collectors.joining(NEW_LINE)); + + System.out.println(content); + } +} diff --git a/src/main/java/com/howtodoinjava/core/string/StringConcatenationBenchmark.java b/src/main/java/com/howtodoinjava/core/string/StringConcatenationBenchmark.java new file mode 100644 index 0000000..7a9b9ad --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/string/StringConcatenationBenchmark.java @@ -0,0 +1,82 @@ +package com.howtodoinjava.core.string; + +import java.time.LocalTime; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@State(Scope.Thread) +public class StringConcatenationBenchmark { + + @Param({"10", "100", "1000"}) + private int count; + + private String baseString; + + @Setup + public void setup() { + baseString = "SampleString"; + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public String testStringConcatenation() { + String result = ""; + for (int i = 0; i < count; i++) { + result += baseString; + } + return result; + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public String testStringBuilder() { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < count; i++) { + builder.append(baseString); + } + return builder.toString(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public String testStringBuffer() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < count; i++) { + buffer.append(baseString); + } + return buffer.toString(); + } + + public static void main(String[] args) throws Exception { + + var name = "Alex"; + var time = LocalTime.now(); + + String greeting = "Hello " + name + ", how are you?\nThe current time is " + time + " now!"; + System.out.println(greeting); + + String greetingTemplate = STR."Hello \{name}, how are you?\nThe current time is \{time} now!"; + System.out.println(greetingTemplate); + + Options opt = new OptionsBuilder() + .include(StringConcatenationBenchmark.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} + diff --git a/src/main/java/com/howtodoinjava/core/string/StringIndentExample.java b/src/main/java/com/howtodoinjava/core/string/StringIndentExample.java new file mode 100644 index 0000000..c2c849a --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/string/StringIndentExample.java @@ -0,0 +1,24 @@ +package com.howtodoinjava.core.string; + +public class StringIndentExample { + + public static void main(String[] args) { + String line1 = "ABC".indent(8); + System.out.println(line1.replace(" ", "-")); + + String line2 = "ABC".indent(8).indent(-5); + System.out.println(line2.replace(" ", "-")); + + String textBlock = """ + Line 1 + Line 2"""; + + String indentedBlock = """ + Line 1 + Line 2""".indent(8); + + System.out.println(textBlock.replace(" ", "-")); + System.out.println(indentedBlock.replace(" ", "-")); + } + +} diff --git a/src/main/java/com/howtodoinjava/core/string/TextBlockFormatting.java b/src/main/java/com/howtodoinjava/core/string/TextBlockFormatting.java new file mode 100644 index 0000000..4cea32d --- /dev/null +++ b/src/main/java/com/howtodoinjava/core/string/TextBlockFormatting.java @@ -0,0 +1,68 @@ +package com.howtodoinjava.core.string; + +import java.text.MessageFormat; + +public class TextBlockFormatting { + + public static void main(String[] args) { + + //Expected Output + /*{ + "id": 1001, + "name": "John Doe", + "age": 34 + }*/ + + int id = 1001; + int age = 34; + String name = "John Doe"; + + Object[] formatArguments = { + 1001, // id + "John Doe", // name + 34 // age + }; + + + /*String greeting = """ + Hello, """ + name + """ + Welcome to Java text blocks! + """; + + System.out.println(greeting.toString()); //Prints "Hello,John DoeWelcome to Java text blocks!"*/ + + + + String textBlock = """ + { + "id": %d, + "name": "%s", + "age": %d + } + """; + + String formattedTextBlock1 = String.format(textBlock, formatArguments); + System.out.println(formattedTextBlock1); + + String formattedTextBlock2 = String.format(textBlock, id, name, age); + System.out.println(formattedTextBlock2); + + + String json = """ + '{' + "id": {0, number, #}, + "name": "{1}", + "salary": "{2, number, integer}" + '}' + """; + + Object[] arguments = { + 1001, // id + "John Doe", // name + 34000 // salary + }; + + String formattedTextBlock3 = MessageFormat.format(json, arguments); + System.out.println(formattedTextBlock3); + } +} diff --git a/src/main/java/com/howtodoinjava/jaxb/Main.java b/src/main/java/com/howtodoinjava/jaxb/Main.java index 6d9ea6e..5dc920e 100644 --- a/src/main/java/com/howtodoinjava/jaxb/Main.java +++ b/src/main/java/com/howtodoinjava/jaxb/Main.java @@ -1,10 +1,15 @@ package com.howtodoinjava.jaxb; +import com.howtodoinjava.xml.model.Department; +import com.howtodoinjava.xml.model.Employee; +import java.io.File; +import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; @@ -24,6 +29,16 @@ public static void main(final String[] args) throws JAXBException { JAXBContext context6 = getJAXBContext(Book.class); JAXBContext context7 = getJAXBContext(Book.class); JAXBContext context8 = getJAXBContext(Book.class); + + JAXBContext jaxbContext = JAXBContext.newInstance( Employee.class ); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + + Employee employee = new Employee(1, "Lokesh", "Gupta", "India", new Department(101, "IT")); + + //Overloaded methods to marshal to different outputs + jaxbMarshaller.marshal(employee, System.out); + jaxbMarshaller.marshal(employee, new File("output.xml")); + jaxbMarshaller.marshal(employee, new StringWriter()); } @SuppressWarnings("rawtypes") diff --git a/src/main/java/com/howtodoinjava/jaxb/MarshalListExample.java b/src/main/java/com/howtodoinjava/jaxb/MarshalListExample.java new file mode 100644 index 0000000..ad6963e --- /dev/null +++ b/src/main/java/com/howtodoinjava/jaxb/MarshalListExample.java @@ -0,0 +1,67 @@ +package com.howtodoinjava.jaxb; + +import com.howtodoinjava.xml.model.Employee; +import jakarta.xml.bind.Unmarshaller; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; + +public class MarshalListExample { + + public static void main(String[] args) throws JAXBException { + Employees employees = new Employees(); + + //Add the employees in list + Employee emp1 = new Employee(1, "Lokesh", "Gupta", null, null); + Employee emp2 = new Employee(1, "John", "McLean", null, null); + employees.getEmployees().add(emp1); + employees.getEmployees().add(emp2); + + //Write to XML + JAXBContext jaxbContext = JAXBContext.newInstance(Employees.class); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + + jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + + //Marshal the employees list in console + jaxbMarshaller.marshal(employees, System.out); + + //Marshal the employees list in file + jaxbMarshaller.marshal(employees, new File("out.xml")); + + //unmarshal example + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + + //We had written this file in marshalling example + Employees emps = (Employees) jaxbUnmarshaller.unmarshal(new File("out.xml")); + + for (Employee emp : emps.getEmployees()) { + + System.out.println(emp.getId()); + System.out.println(emp.getFirstName()); + } + } +} + +@XmlRootElement(name = "employees") +@XmlAccessorType(XmlAccessType.FIELD) +class Employees { + + @XmlElement(name = "employee") + private List employees = new ArrayList<>(); + + public List getEmployees() { + return employees; + } + + public void setEmployees(List employees) { + this.employees = employees; + } +} diff --git a/src/main/java/com/howtodoinjava/jaxb/NoDefaultConstructor.java b/src/main/java/com/howtodoinjava/jaxb/NoDefaultConstructor.java new file mode 100644 index 0000000..1da0b1e --- /dev/null +++ b/src/main/java/com/howtodoinjava/jaxb/NoDefaultConstructor.java @@ -0,0 +1,95 @@ +package com.howtodoinjava.jaxb; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlTransient; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.io.StringReader; +import java.io.StringWriter; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +public class NoDefaultConstructor { + + public static void main(String[] args) throws JAXBException { + Address address = new Address("Line 1", "Line 2", "New Delhi", "India", new PinCode("110075")); + JAXBContext jaxbContext = JAXBContext.newInstance(Address.class); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + StringWriter stringWriter = new StringWriter(); + jaxbMarshaller.marshal(address, stringWriter); + String XML = stringWriter.toString(); + System.out.println(XML); + + String xmlAddress = """ + +
+ Line 1 + Line 2 + New Delhi + India + + 110075 + +
+ """; + + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + Address newAddress = (Address) jaxbUnmarshaller.unmarshal(new StringReader(xmlAddress)); + System.out.println(newAddress); + } +} + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = "Address") +@XmlAccessorType(XmlAccessType.FIELD) +class Address { + String line1; + String line2; + String city; + String country; + //@XmlTransient + @XmlJavaTypeAdapter(PinCodeAdapter.class) + PinCode pinCode; +} +@Data +class PinCode { + String code; + + public PinCode(String code){ + this.code = code; + } +} + +@Data +class XmlPinCode { + + String code; + public XmlPinCode(){ + } + + public XmlPinCode(String code){ + this.code = code; + } +} + +class PinCodeAdapter extends XmlAdapter { + + @Override + public PinCode unmarshal(XmlPinCode v) throws Exception { + return new PinCode(v.getCode()); + } + + @Override + public XmlPinCode marshal(PinCode v) throws Exception { + return new XmlPinCode(v.getCode()); + } +} diff --git a/src/main/java/com/howtodoinjava/jaxb/ReadWriteXML.java b/src/main/java/com/howtodoinjava/jaxb/ReadWriteXML.java new file mode 100644 index 0000000..189a964 --- /dev/null +++ b/src/main/java/com/howtodoinjava/jaxb/ReadWriteXML.java @@ -0,0 +1,37 @@ +package com.howtodoinjava.jaxb; + +import com.howtodoinjava.xml.model.Employee; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; +import java.io.StringReader; + +public class ReadWriteXML { + + public static void main(String[] args) { + + // Convert XML String to Java Object + + String xmlString = "" + + " " + + " 101" + + " IT" + + " " + + " India" + + " Lokesh" + + " 1" + + " Gupta" + + ""; + + JAXBContext jaxbContext; + try { + jaxbContext = JAXBContext.newInstance(Employee.class); + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + Employee employee = (Employee) jaxbUnmarshaller.unmarshal(new StringReader(xmlString)); + System.out.println(employee); + } catch (JAXBException e) { + e.printStackTrace(); + } + + } +} diff --git a/src/main/java/com/howtodoinjava/jaxb/XmlTypeAdapterOverInterface.java b/src/main/java/com/howtodoinjava/jaxb/XmlTypeAdapterOverInterface.java new file mode 100644 index 0000000..d004555 --- /dev/null +++ b/src/main/java/com/howtodoinjava/jaxb/XmlTypeAdapterOverInterface.java @@ -0,0 +1,61 @@ +package com.howtodoinjava.jaxb; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.io.StringReader; +import java.io.StringWriter; +import java.time.LocalDateTime; +import java.time.temporal.Temporal; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +public class XmlTypeAdapterOverInterface { + + public static void main(String[] args) throws JAXBException { + JAXBContext jaxbContext = JAXBContext.newInstance(BatchJob.class); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + StringWriter stringWriter = new StringWriter(); + jaxbMarshaller.marshal(new BatchJob(LocalDateTime.now()), stringWriter); + String XML = stringWriter.toString(); + System.out.println(XML); + + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + BatchJob newBatchJob = (BatchJob) jaxbUnmarshaller.unmarshal(new StringReader(XML)); + System.out.println(newBatchJob); + } +} + +@Data +@AllArgsConstructor +@NoArgsConstructor +@XmlRootElement(name = "BatchJob") +@XmlAccessorType(XmlAccessType.FIELD) +class BatchJob { + + @XmlJavaTypeAdapter(TemporalAdapter.class) + Temporal startTime; +} + +class TemporalAdapter extends XmlAdapter { + + @Override + public Temporal unmarshal(String v) throws Exception { + return LocalDateTime.parse(v); + } + + @Override + public String marshal(Temporal v) throws Exception { + return v.toString(); + } +} + + + diff --git a/src/main/java/com/howtodoinjava/reflection/CallingInterfaceMethodWithoutImplementing.java b/src/main/java/com/howtodoinjava/reflection/CallingInterfaceMethodWithoutImplementing.java new file mode 100644 index 0000000..b1e5f80 --- /dev/null +++ b/src/main/java/com/howtodoinjava/reflection/CallingInterfaceMethodWithoutImplementing.java @@ -0,0 +1,96 @@ +package com.howtodoinjava.reflection; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; + +public class CallingInterfaceMethodWithoutImplementing { + + public static void main(String[] args) { + + //Since Java 16 + + Movable movableProxy = (Movable) Proxy.newProxyInstance( + Movable.class.getClassLoader(), + new Class[]{Movable.class}, (o, m, p) -> { + if (m.isDefault()) { + return InvocationHandler.invokeDefault(o, m, p); + } + return null; + }); + + // invoke interface methods + movableProxy.move(); + String returnedValue = movableProxy.moveWithParamAndReturn("lion"); + System.out.println(returnedValue); + + //Java 15 and Before + + Movable movableProxy2 = (Movable) Proxy.newProxyInstance( + Movable.class.getClassLoader(), + new Class[]{Movable.class}, (o, m, p) -> { + if (m.isDefault()) { + // Adjust the method type as per the default method's signature + MethodType methodType; + if (m.getName().equals("move")) { + methodType = MethodType.methodType(void.class); + } else if (m.getName().equals("moveWithParamAndReturn")) { + methodType = MethodType.methodType(String.class, String.class); + } else { + throw new UnsupportedOperationException("Unknown default method: " + m.getName()); + } + return MethodHandles.lookup() + .findSpecial(Movable.class, m.getName(), + methodType, + Movable.class) + .bindTo(o) + .invokeWithArguments(p); + } + return null; + }); + + movableProxy2.move(); + returnedValue = movableProxy2.moveWithParamAndReturn("lion"); + System.out.println(returnedValue); + + //JDK 8 + + Movable movableProxy3 = (Movable) Proxy.newProxyInstance( + Movable.class.getClassLoader(), + new Class[]{Movable.class}, (o, m, p) -> { + if (m.isDefault()) { + Constructor cntr = Lookup.class + .getDeclaredConstructor(Class.class); + cntr.setAccessible(true); + return cntr.newInstance(Movable.class) + .in(Movable.class) + .unreflectSpecial(m, Movable.class) + .bindTo(o) + .invokeWithArguments(p); + } + return null; + }); + + movableProxy3.move(); + returnedValue = movableProxy3.moveWithParamAndReturn("lion"); + System.out.println(returnedValue); + } + +} + +interface Movable { + + default void move() { + System.out.println("Inside Movable.move()"); + } + + default String moveWithParamAndReturn(String param) { + System.out.println("Inside Movable.moveWithParamAndReturn()"); + return STR."\{param}-returned"; + } + + void moveToImplement(); +} diff --git a/src/main/java/com/howtodoinjava/regex/StartsWithEndsWith.java b/src/main/java/com/howtodoinjava/regex/StartsWithEndsWith.java new file mode 100644 index 0000000..9738499 --- /dev/null +++ b/src/main/java/com/howtodoinjava/regex/StartsWithEndsWith.java @@ -0,0 +1,33 @@ +package com.howtodoinjava.regex; + +import java.util.List; +import java.util.regex.*; + +public class StartsWithEndsWith { + + public static void main(String[] args) { + + List lines = List.of( + "The cat is cute", + "The category is empty", + "The noncategory is also empty"); + + Pattern pattern = Pattern.compile("\\bcat\\b", Pattern.CASE_INSENSITIVE); + + for(String line: lines) { + Matcher matcher = pattern.matcher(line); + while (matcher.find()) { + //System.out.println(STR."Match found: \{matcher.group()}"); + } + } + + pattern = Pattern.compile("\\b\\w*cat\\w*\\b"); + + for(String line: lines) { + Matcher matcher = pattern.matcher(line); + while (matcher.find()) { + System.out.println(STR."Match found: \{matcher.group()}"); + } + } + } +} diff --git a/src/main/java/com/howtodoinjava/xml/model/Employee.java b/src/main/java/com/howtodoinjava/xml/model/Employee.java index 6c2c99f..bb722ec 100644 --- a/src/main/java/com/howtodoinjava/xml/model/Employee.java +++ b/src/main/java/com/howtodoinjava/xml/model/Employee.java @@ -2,18 +2,16 @@ import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessorType; -import jakarta.xml.bind.annotation.XmlAttribute; -import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; import java.io.Serializable; -@XmlRootElement(name="employee") +@XmlRootElement(name = "employee") @XmlAccessorType(XmlAccessType.FIELD) public class Employee implements Serializable { private static final long serialVersionUID = 1L; - @XmlAttribute + //@XmlAttribute private Integer id; private String firstName; private String lastName; @@ -24,7 +22,7 @@ public Employee() { super(); } - public Employee(int id, String fName, String lName, Department department) { + public Employee(int id, String fName, String lName, String location, Department department) { super(); this.id = id; this.firstName = fName; @@ -75,7 +73,6 @@ public void setLocation(String location) { @Override public String toString() { - return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", department=" - + department + "]"; + return STR."Employee{id=\{id}, firstName='\{firstName}\{'\''}, lastName='\{lastName}\{'\''}, location='\{location}\{'\''}, department=\{department}\{'}'}"; } } \ No newline at end of file