Rick

Rick
Rick

Wednesday, March 26, 2014

Boon Remix: How to Clone Collection in Java - Deep copy of ArrayList and HashSet with Boon

How to Clone Collection in Java - Deep copy of ArrayList and HashSet with Boon

Please visit and read this article. This is a remix of this: How to Clone Collection in Java - Deep copy of ArrayList and HashSet.
Boon has many utility methods to convert objects into maps, lists, JSON, etc. It also has many collection utility methods.
Programmer, none that I have ever met, have mistakenly used copy constructors by by various collection classes, as a way to clone Collection e.g. List, Set, ArrayList, HashSet or any other implementation. Or they write a lot of boiler plate code and spend a lot of time doing things to copy lists.
The key point is to remember is that the built-in collection lib does not do a deep copy.
If you have code using the original collection modifies an employee, that change could be reflected in the cloned collection. Similarly if an employee is modified in cloned collection, it will also appeared as modified in original collection.
This is less than desirable. A solution to avoid this problem is deep cloning of collection, which means recursively cloning object, until you reached to primitive or Immutable. But that takes a lot of work. Boon has an easier solution. Boon has a copy function that does a deep copy for you. In fact Boon has hundreds of such utility functions. Don't waste your time with cloning, use Boon and develop Java apps with a smile on your face.

deep copy using Set

        Set<Employee> original, copy;

        original = set(
                new Employee( "Joe", "Manager" ),
                new Employee( "Tim", "Developer" ),
                new Employee( "Frank", "Developer" ));

        copy = deepCopy( original );

        setCollectionProperty(original, "designation", "staff");


        puts("Original Set after modification", original);

        puts("Copy of Set after modification",  copy);


Output
Original Set after modification [Joe:staff, Tim:staff, Frank:staff] 
Copy of Set after modification [Joe:Manager, Tim:Developer, Frank:Developer] 

The above code is functionally equivalent to the article How to Clone Collection in Java - Deep copy of ArrayList and HashSet. But it is smaller and we did not have to implement the clone method. The deepCopy will even copy other properties which are instances of other domain objects even if those domain objects are in lists or arrays.

deep copy using List

        List<Employee> original, copy;

        original = list(
                new Employee("Joe", "Manager"),
                new Employee("Tim", "Developer"),
                new Employee("Frank", "Developer"));

        copy = deepCopy( original );

        setCollectionProperty(original, "designation", "staff");

Original List after modification [Joe:staff, Tim:staff, Frank:staff] 
Copy of List after modification [Joe:Manager, Tim:Developer, Frank:Developer] 
This just scratches the surface of what Boon can do.
Stop by the Boon wiki. Book Wiki
/*
 * Copyright 2013-2014 Richard M. Hightower
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *          http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * __________                              _____          __   .__
 * \______   \ ____   ____   ____   /\    /     \ _____  |  | _|__| ____    ____
 *  |    |  _//  _ \ /  _ \ /    \  \/   /  \ /  \\__  \ |  |/ /  |/    \  / ___\
 *  |    |   (  <_> |  <_> )   |  \ /\  /    Y    \/ __ \|    <|  |   |  \/ /_/  >
 *  |______  /\____/ \____/|___|  / \/  \____|__  (____  /__|_ \__|___|  /\___  /
 *         \/                   \/              \/     \/     \/       \//_____/
 *      ____.                     ___________   _____    ______________.___.
 *     |    |____ ___  _______    \_   _____/  /  _  \  /   _____/\__  |   |
 *     |    \__  \\  \/ /\__  \    |    __)_  /  /_\  \ \_____  \  /   |   |
 * /\__|    |/ __ \\   /  / __ \_  |        \/    |    \/        \ \____   |
 * \________(____  /\_/  (____  / /_______  /\____|__  /_______  / / ______|
 *               \/           \/          \/         \/        \/  \/
 */

package com.examples;

import org.junit.Test;

import java.util.List;
import java.util.Set;

import static org.boon.Boon.puts;
import static org.boon.Ok.okOrDie;
import static org.boon.Sets.deepCopy;
import static org.boon.Sets.set;
import static org.boon.Lists.list;
import static org.boon.Lists.deepCopy;
import static org.boon.Str.add;
import static org.boon.core.reflection.BeanUtils.setCollectionProperty;
import static org.boon.core.reflection.BeanUtils.copy;

public class DeepCopyRemix {



    public static class Employee {
        private String name;
        private String designation;

        public Employee(String name, String designation) {
            this.name = name;
            this.designation = designation;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDesignation() {
            return designation;
        }

        public void setDesignation(String designation) {
            this.designation = designation;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Employee employee = (Employee) o;

            if (designation != null ? !designation.equals(employee.designation) : employee.designation != null)
                return false;
            if (name != null ? !name.equals(employee.name) : employee.name != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = name != null ? name.hashCode() : 0;
            result = 31 * result + (designation != null ? designation.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return add(name, ":", designation);
        }
    }



    public static void main2 (String... args) {

        Set<Employee> original, copy;

        original = set(
                new Employee( "Joe", "Manager" ),
                new Employee( "Tim", "Developer" ),
                new Employee( "Frank", "Developer" ));

        copy = deepCopy( original );

        setCollectionProperty(original, "designation", "staff");


        puts("Original Set after modification", original);

        puts("Copy of Set after modification",  copy);




        Employee employee = new Employee("Joe", "Manager");
        Employee copyEmployee = copy(employee);


        okOrDie("not same object", employee != copyEmployee);

        okOrDie("not same object", copy.iterator().next() != original.iterator().next());
    }


    public static void main (String... args) {

        List<Employee> original, copy;

        original = list(
                new Employee("Joe", "Manager"),
                new Employee("Tim", "Developer"),
                new Employee("Frank", "Developer"));

        copy = deepCopy( original );

        setCollectionProperty(original, "designation", "staff");

        original.iterator().next().setDesignation("staff");

        puts("Original List after modification", original);

        puts("Copy of List after modification",  copy);

        okOrDie("not same object", copy.iterator().next() != original.iterator().next());


    }


    @Test
    public void test() {
        DeepCopyRemix.main();

        DeepCopyRemix.main2();
    }


}

Boon. Code Java with pleasure.

Thoughts

Thoughts? Write me at richard high tower AT g mail dot c-o-m (Rick Hightower).

Further Reading:

If you are new to boon start here:

Why Boon?

Easily read in files into lines or a giant string with one method call. Works with files, URLs, class-path, etc. Boon IO support will surprise you how easy it is. Boon has Slice notation for dealing with Strings, Lists, primitive arrays, Tree Maps, etc. If you are from Groovy land, Ruby land, Python land, or whatever land, and you have to use Java then Boon might give you some relief from API bloat. If you are like me, and you like to use Java, then Boon is for you too. Boon lets Java be Java, but adds the missing productive APIs from Python, Ruby, and Groovy. Boon may not be Ruby or Groovy, but its a real Boon to Java development.

Core Boon Philosophy

Core Boon will never have any dependencies. It will always be able to run as a single jar. This is not just NIH, but it is partly. My view of what Java needs is more inline with what Python, Ruby and Groovy provide. Boon is an addition on top of the JVM to make up the difference between the harder to use APIs that come with Java and the types of utilities that are built into Ruby, Python, PHP, Groovy etc. Boon is a Java centric view of those libs. The vision of Boon and the current implementation is really far apart.

Contact Info
JMeter vs. Gatling: Fact Checking: SHILL! ASTROTURFING SHILL!