From 45da250fffffffae062047e43973416232872624 Mon Sep 17 00:00:00 2001 From: clininger Date: Mon, 8 Oct 2018 07:33:16 +0700 Subject: [PATCH] BAEL-2184 Converting a Collection to ArrayList --- .../convertcollectiontoarraylist/Foo.java | 52 +++++++ .../FooUnitTest.java | 144 ++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 core-java-collections/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java create mode 100644 core-java-collections/src/test/java/com/baeldung/convertcollectiontoarraylist/FooUnitTest.java diff --git a/core-java-collections/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java b/core-java-collections/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java new file mode 100644 index 0000000000..3123295641 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java @@ -0,0 +1,52 @@ +package com.baeldung.convertcollectiontoarraylist; + +/** + * This POJO is the element type of our collection. It has a deepCopy() method. + * + * @author chris + */ +public class Foo { + + private int id; + private String name; + private Foo parent; + + public Foo() { + } + + public Foo(int id, String name, Foo parent) { + this.id = id; + this.name = name; + this.parent = parent; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Foo getParent() { + return parent; + } + + public void setParent(Foo parent) { + this.parent = parent; + } + + public Foo deepCopy() { + return new Foo(this.id, this.name, + this.parent != null ? this.parent.deepCopy() : null); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/convertcollectiontoarraylist/FooUnitTest.java b/core-java-collections/src/test/java/com/baeldung/convertcollectiontoarraylist/FooUnitTest.java new file mode 100644 index 0000000000..fd07848383 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/convertcollectiontoarraylist/FooUnitTest.java @@ -0,0 +1,144 @@ +package com.baeldung.convertcollectiontoarraylist; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import static java.util.stream.Collectors.toCollection; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author chris + */ +public class FooUnitTest { + private static Collection srcCollection = new HashSet<>(); + + public FooUnitTest() { + } + + @BeforeClass + public static void setUpClass() { + int i = 0; + Foo john = new Foo(i++, "John", null); + Foo mary = new Foo(i++, "Mary", null); + Foo sam = new Foo(i++, "Sam", john); + Foo alice = new Foo(i++, "Alice", john); + Foo buffy = new Foo(i++, "Buffy", sam); + srcCollection.add(john); + srcCollection.add(mary); + srcCollection.add(sam); + srcCollection.add(alice); + srcCollection.add(buffy); + } + + /** + * Section 3. Using the ArrayList Constructor + */ + @Test + public void testConstructor() { + ArrayList newList = new ArrayList<>(srcCollection); + verifyShallowCopy(srcCollection, newList); + } + + /** + * Section 4. Using the Streams API + */ + @Test + public void testStream() { + ArrayList newList = srcCollection.stream().collect(toCollection(ArrayList::new)); + verifyShallowCopy(srcCollection, newList); + } + + /** + * Section 5. Deep Copy + */ + @Test + public void testStreamDeepCopy() { + ArrayList newList = srcCollection.stream() + .map(foo -> foo.deepCopy()) + .collect(toCollection(ArrayList::new)); + verifyDeepCopy(srcCollection, newList); + } + + /** + * Section 6. Controlling the List Order + */ + @Test + public void testSortOrder() { + assertFalse("Oops: source collection is already sorted!", isSorted(srcCollection)); + ArrayList newList = srcCollection.stream() + .map(foo -> foo.deepCopy()) + .sorted(Comparator.comparing(Foo::getName)) + .collect(toCollection(ArrayList::new)); + assertTrue("ArrayList is not sorted by name", isSorted(newList)); + } + + /** + * Verify that the contents of the two collections are the same + * @param a + * @param b + */ + private void verifyShallowCopy(Collection a, Collection b) { + assertEquals("Collections have different lengths", a.size(), b.size()); + Iterator iterA = a.iterator(); + Iterator iterB = b.iterator(); + while (iterA.hasNext()) { + // use '==' to test instance identity + assertTrue("Foo instances differ!", iterA.next() == iterB.next()); + } + } + + /** + * Verify that the contents of the two collections are the same + * @param a + * @param b + */ + private void verifyDeepCopy(Collection a, Collection b) { + assertEquals("Collections have different lengths", a.size(), b.size()); + Iterator iterA = a.iterator(); + Iterator iterB = b.iterator(); + while (iterA.hasNext()) { + Foo nextA = iterA.next(); + Foo nextB = iterB.next(); + // should not be same instance + assertFalse("Foo instances are the same!", nextA == nextB); + // but should have same content + assertFalse("Foo instances have different content!", fooDiff(nextA, nextB)); + } + } + + /** + * Return true if the contents of a and b differ. Test parent recursively + * @param a + * @param b + * @return False if the two items are the same + */ + private boolean fooDiff(Foo a, Foo b) { + if (a != null && b != null) { + return a.getId() != b.getId() + || !a.getName().equals(b.getName()) + || fooDiff(a.getParent(), b.getParent()); + } + return !(a == null && b == null); + } + + /** + * @param c collection of Foo + * @return true if the collection is sorted by name + */ + private boolean isSorted(Collection c) { + String prevName = null; + for (Foo foo : c) { + if (prevName == null || foo.getName().compareTo(prevName) > 0) { + prevName = foo.getName(); + } else { + return false; + } + } + return true; + } +}