From 2449c8117a6ddc87b76043cbd6a1ec10d1073329 Mon Sep 17 00:00:00 2001 From: Andrew Shcherbakov Date: Wed, 12 Jun 2019 07:18:14 +0200 Subject: [PATCH 1/5] Create a package for the article code --- .../main/java/com/baeldung/folding/Main.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java new file mode 100644 index 0000000000..47ae11c80c --- /dev/null +++ b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java @@ -0,0 +1,21 @@ +package com.baeldung.folding; + +import java.util.stream.IntStream; + +public class Main { + public static void main(String... arg) { + final String key = "Java language"; + + toAsciiCodes(key).forEach(c -> System.out.println(c)); + // toAsciiCodes(key).reduce(new ArrayList(), (accum, i) -> i); + // List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + // numbers.stream() + // .reduce(new ArrayList(), (k, v) -> new ArrayList()); + // System.out.println(result); + } + + public static IntStream toAsciiCodes(String key) { + return key.chars(); + } + +} From 97c1f79f32ebf9fff60efacc41a92ee4dff976be Mon Sep 17 00:00:00 2001 From: Andrew Shcherbakov Date: Sat, 15 Jun 2019 11:20:32 +0200 Subject: [PATCH 2/5] Implement illustration for the folding technique --- .../com/baeldung/folding/FoldingHash.java | 77 +++++++++++++++++++ .../baeldung/folding/FoldingHashUnitTest.java | 57 ++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java create mode 100644 core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java new file mode 100644 index 0000000000..a04513ed55 --- /dev/null +++ b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java @@ -0,0 +1,77 @@ +package com.baeldung.folding; + +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * Calculate a hash value for the strings using the folding technique. + * + * The implementation serves only to the illustration purposes and is far + * from being the most efficient. + * + * @author veontomo + * + */ +public class FoldingHash { + + /** + * Calculate the hash value of a given string + * @param str + * @param groupSize + * @param maxValue + * @return + */ + public int hash(String str, int groupSize, int maxValue) { + final int[] codes = this.toAsciiCodes(str); + return IntStream.range(0, str.length()) + .filter(i -> i % groupSize == 0) + .mapToObj(i -> extract(codes, i, groupSize)) + .map(block -> concatenate(block)) + .reduce(0, (a, b) -> (a + b) % maxValue); + } + + /** + * Returns a new array of given length whose elements are take from + * the original one starting from the offset. + * + * If the original array has not enough elements, the returning array will contain + * element from the offset till the end of the original array. + * + * @param numbers + * @param offset + * @param length + * @return + */ + public int[] extract(int[] numbers, int offset, int length) { + final int defect = numbers.length - (offset + length); + final int s = defect < 0 ? length + defect : length; + int[] result = new int[s]; + for (int index = 0; index < s; index++) { + result[index] = numbers[index + offset]; + } + return result; + } + + /** + * Concatenate the numbers into a single number. + * Assume that the procedure does not suffer from the overflow. + * @param numbers + * @return + */ + public int concatenate(int[] numbers) { + final String merged = IntStream.of(numbers) + .mapToObj(number -> "" + number) + .collect(Collectors.joining()); + return Integer.parseInt(merged, 10); + } + + /** + * Convert the string into its characters' ascii codes. + * @param str + * @return + */ + private int[] toAsciiCodes(String str) { + return str.chars() + .toArray(); + } +} diff --git a/core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java b/core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java new file mode 100644 index 0000000000..b8e9adf435 --- /dev/null +++ b/core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java @@ -0,0 +1,57 @@ +package com.baeldung.folding; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class FoldingHashUnitTest { + + @Test + public void givenStringJavaLanguage_whenSize2Capacity100000_then48933() throws Exception { + final FoldingHash hasher = new FoldingHash(); + final int value = hasher.hash("Java language", 2, 100_000); + assertEquals(value, 48933); + } + + + @Test + public void givenStringVaJaLanguage_whenSize2Capacity100000_thenSameAsJavaLanguage() throws Exception { + final FoldingHash hasher = new FoldingHash(); + final int java = hasher.hash("Java language", 2, 100_000); + final int vaja = hasher.hash("vaJa language", 2, 100_000); + assertTrue(java == vaja); + } + + + @Test + public void givenSingleElementArray_whenOffset0Size2_thenSingleElement() throws Exception { + final FoldingHash hasher = new FoldingHash(); + final int[] value = hasher.extract(new int[] {5}, 0, 2); + assertArrayEquals(new int[] {5}, value); + } + + @Test + public void givenFiveElementArray_whenOffset0Size3_thenFirstThreeElements() throws Exception { + final FoldingHash hasher = new FoldingHash(); + final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 0, 3); + assertArrayEquals(new int[] {1, 2, 3}, value); + } + + @Test + public void givenFiveElementArray_whenOffset1Size2_thenTwoElements() throws Exception { + final FoldingHash hasher = new FoldingHash(); + final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 1, 2); + assertArrayEquals(new int[] {2, 3}, value); + } + + @Test + public void givenFiveElementArray_whenOffset2SizeTooBig_thenElementsToTheEnd() throws Exception { + final FoldingHash hasher = new FoldingHash(); + final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 2, 2000); + assertArrayEquals(new int[] {3, 4, 5}, value); + } + + +} From 41502a75076abe89de6ca331fbc66209812a38d5 Mon Sep 17 00:00:00 2001 From: Andrew Shcherbakov Date: Sat, 15 Jun 2019 11:31:19 +0200 Subject: [PATCH 3/5] Clean the main method of the folding technique code snippet --- .../com/baeldung/folding/FoldingHash.java | 2 +- .../main/java/com/baeldung/folding/Main.java | 24 ++++++++----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java index a04513ed55..3cb0d55ca7 100644 --- a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java +++ b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java @@ -9,7 +9,7 @@ import java.util.stream.IntStream; * The implementation serves only to the illustration purposes and is far * from being the most efficient. * - * @author veontomo + * @author A.Shcherbakov * */ public class FoldingHash { diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java index 47ae11c80c..dec5b4850a 100644 --- a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java +++ b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java @@ -1,21 +1,17 @@ package com.baeldung.folding; -import java.util.stream.IntStream; - +/** + * Code snippet for article "A Guide to the Folding Technique". + * + * @author A.Shcherbakov + * + */ public class Main { public static void main(String... arg) { - final String key = "Java language"; - - toAsciiCodes(key).forEach(c -> System.out.println(c)); - // toAsciiCodes(key).reduce(new ArrayList(), (accum, i) -> i); - // List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); - // numbers.stream() - // .reduce(new ArrayList(), (k, v) -> new ArrayList()); - // System.out.println(result); - } - - public static IntStream toAsciiCodes(String key) { - return key.chars(); + FoldingHash hasher = new FoldingHash(); + final String str = "Java language"; + System.out.println(hasher.hash(str, 2, 100_000)); + System.out.println(hasher.hash(str, 3, 1_000)); } } From 56984861789f4c2d194a41ac3e7aa55f13539ecb Mon Sep 17 00:00:00 2001 From: Andrew Shcherbakov Date: Sat, 15 Jun 2019 19:40:15 +0200 Subject: [PATCH 4/5] Add Javadoc to method arguments and format the code --- .../com/baeldung/folding/FoldingHash.java | 25 ++++++++--------- .../main/java/com/baeldung/folding/Main.java | 2 +- .../baeldung/folding/FoldingHashUnitTest.java | 27 +++++++++---------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java index 3cb0d55ca7..0ea128c1d9 100644 --- a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java +++ b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java @@ -15,11 +15,12 @@ import java.util.stream.IntStream; public class FoldingHash { /** - * Calculate the hash value of a given string - * @param str - * @param groupSize - * @param maxValue - * @return + * Calculate the hash value of a given string. + * + * @param str Assume it is not null + * @param groupSize the group size in the folding technique + * @param maxValue defines a max value that the hash may acquire (exclusive) + * @return integer value from 0 (inclusive) to maxValue (exclusive) */ public int hash(String str, int groupSize, int maxValue) { final int[] codes = this.toAsciiCodes(str); @@ -37,9 +38,9 @@ public class FoldingHash { * If the original array has not enough elements, the returning array will contain * element from the offset till the end of the original array. * - * @param numbers - * @param offset - * @param length + * @param numbers original array. Assume it is not null. + * @param offset index of the element to start from. Assume it is less than the size of the array + * @param length max size of the resulting array * @return */ public int[] extract(int[] numbers, int offset, int length) { @@ -53,9 +54,9 @@ public class FoldingHash { } /** - * Concatenate the numbers into a single number. + * Concatenate the numbers into a single number as if they were strings. * Assume that the procedure does not suffer from the overflow. - * @param numbers + * @param numbers integers to concatenate * @return */ public int concatenate(int[] numbers) { @@ -66,8 +67,8 @@ public class FoldingHash { } /** - * Convert the string into its characters' ascii codes. - * @param str + * Convert the string into its characters' ASCII codes. + * @param str input string * @return */ private int[] toAsciiCodes(String str) { diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java index dec5b4850a..3b055a0dbe 100644 --- a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java +++ b/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java @@ -7,11 +7,11 @@ package com.baeldung.folding; * */ public class Main { + public static void main(String... arg) { FoldingHash hasher = new FoldingHash(); final String str = "Java language"; System.out.println(hasher.hash(str, 2, 100_000)); System.out.println(hasher.hash(str, 3, 1_000)); } - } diff --git a/core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java b/core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java index b8e9adf435..43e33d8378 100644 --- a/core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java +++ b/core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java @@ -14,44 +14,41 @@ public class FoldingHashUnitTest { final int value = hasher.hash("Java language", 2, 100_000); assertEquals(value, 48933); } - - + @Test public void givenStringVaJaLanguage_whenSize2Capacity100000_thenSameAsJavaLanguage() throws Exception { final FoldingHash hasher = new FoldingHash(); final int java = hasher.hash("Java language", 2, 100_000); final int vaja = hasher.hash("vaJa language", 2, 100_000); assertTrue(java == vaja); - } - + } @Test public void givenSingleElementArray_whenOffset0Size2_thenSingleElement() throws Exception { final FoldingHash hasher = new FoldingHash(); - final int[] value = hasher.extract(new int[] {5}, 0, 2); - assertArrayEquals(new int[] {5}, value); + final int[] value = hasher.extract(new int[] { 5 }, 0, 2); + assertArrayEquals(new int[] { 5 }, value); } - + @Test public void givenFiveElementArray_whenOffset0Size3_thenFirstThreeElements() throws Exception { final FoldingHash hasher = new FoldingHash(); - final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 0, 3); - assertArrayEquals(new int[] {1, 2, 3}, value); + final int[] value = hasher.extract(new int[] { 1, 2, 3, 4, 5 }, 0, 3); + assertArrayEquals(new int[] { 1, 2, 3 }, value); } @Test public void givenFiveElementArray_whenOffset1Size2_thenTwoElements() throws Exception { final FoldingHash hasher = new FoldingHash(); - final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 1, 2); - assertArrayEquals(new int[] {2, 3}, value); + final int[] value = hasher.extract(new int[] { 1, 2, 3, 4, 5 }, 1, 2); + assertArrayEquals(new int[] { 2, 3 }, value); } @Test public void givenFiveElementArray_whenOffset2SizeTooBig_thenElementsToTheEnd() throws Exception { final FoldingHash hasher = new FoldingHash(); - final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 2, 2000); - assertArrayEquals(new int[] {3, 4, 5}, value); + final int[] value = hasher.extract(new int[] { 1, 2, 3, 4, 5 }, 2, 2000); + assertArrayEquals(new int[] { 3, 4, 5 }, value); } - - + } From 9edcaa30d5b7619cf1dd649c5601208f3363fb03 Mon Sep 17 00:00:00 2001 From: Andrew Shcherbakov Date: Tue, 18 Jun 2019 21:22:13 +0200 Subject: [PATCH 5/5] Move the code into algorithms-miscellaneous-3 --- .../src/main/java/com/baeldung/folding/FoldingHash.java | 0 .../src/main/java/com/baeldung/folding/Main.java | 0 .../src/test/java/com/baeldung/folding/FoldingHashUnitTest.java | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {core-java-modules/core-java-security => algorithms-miscellaneous-3}/src/main/java/com/baeldung/folding/FoldingHash.java (100%) rename {core-java-modules/core-java-security => algorithms-miscellaneous-3}/src/main/java/com/baeldung/folding/Main.java (100%) rename {core-java-modules/core-java-security => algorithms-miscellaneous-3}/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java (100%) diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/FoldingHash.java similarity index 100% rename from core-java-modules/core-java-security/src/main/java/com/baeldung/folding/FoldingHash.java rename to algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/FoldingHash.java diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/Main.java similarity index 100% rename from core-java-modules/core-java-security/src/main/java/com/baeldung/folding/Main.java rename to algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/Main.java diff --git a/core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java b/algorithms-miscellaneous-3/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java similarity index 100% rename from core-java-modules/core-java-security/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java rename to algorithms-miscellaneous-3/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java