All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.greatbit.utils.collection.CollectionUtils Maven / Gradle / Ivy

package ru.greatbit.utils.collection;

import ru.greatbit.utils.serialize.JsonSerializer;
import ru.greatbit.utils.string.StringUtils;

import java.util.*;

/**
 * Created by azee on 4/29/14.
 */
public class CollectionUtils {

    /**
     * Merge lists
     * @param first - List
     * @param second - List
     * @param  - Object class
     * @return - List
     */
    public static  List mergeLists(List first, List second){
        Map dataMap = listToMap(first);

        for (T object : second){
            dataMap.put(object, object);
        }

        List resultObject = new LinkedList();
        for (T object : dataMap.keySet()){
            resultObject.add(object);
        }
        return resultObject;
    }

    /**
     * Merge lists of object
     * Objects are compared by serialisation value
     * @param first - The first list of objects
     * @param second - The second list of objects
     * @return - Merged list of objects
     * @param  - Object class
     * @throws Exception - Serialization exceptions
     */
    public static  List mergeListsByValue(List first, List second) throws Exception {
        Map dataMap = listToMD5Map(first);

        for (T object : second){
            dataMap.put(StringUtils.getMd5String(JsonSerializer.marshal(object)), object);
        }

        List resultObject = new LinkedList();
        for (String key : dataMap.keySet()){
            resultObject.add(dataMap.get(key));
        }
        return resultObject;
    }



    /**
     * Get differences of lists
     * Objects should override hashCode and equals so they could be
     * compared in HashMap to find differences
     * @param first - List
     * @param second - List
     * @param  - Object class
     * @return Difference object
     */
    public static Difference getDiff(List first, List second){
        return getDiff(listToMap(first), listToMap(second));
    }

    /**
     * Get differences of lists
     * Uses serialised objects md5 - it will work slower
     * but can process objects if hashCode and equals can't be overridden
     * @param first - first list
     * @param second - second list
     * @return - Difference object
     * @param  - Object class
     * @throws Exception - Serialization exception
     */
    public static Difference getDiffAnyObject(List first, List second) throws Exception {
        return getDiff(listToMD5Map(first), listToMD5Map(second));
    }

    /**
     * Return a difference from 2 maps
     * @param firstMap - First map do diff
     * @param secondMap - Second map do diff
     * @param  - Key class
     * @param  - Value class
     * @return - Difference object
     */
    private static Difference getDiff(Map firstMap, Map secondMap){
        Difference difference = new Difference();

        for (K object : secondMap.keySet()){
            V value = firstMap.get(object);
            if (value == null){
                difference.getAdded().add(secondMap.get(object));
            } else {
                difference.getEqual().add(value);
            }
        }

        for (K object : firstMap.keySet()){
            V value = secondMap.get(object);
            if (value == null){
                difference.getRemoved().add(firstMap.get(object));
            }
        }
        return difference;
    }

    /**
     * Load a list to a map
     * @param input - List
     * @param  - Object class
     * @return - Map
     */
    public static  Map listToMap(List input){
        Map dataMap = new HashMap();
        for (V object : input){
            dataMap.put(object, object);
        }
        return dataMap;
    }

    /**
     * Load a list to a map, use serialised objects md5 - it will work slower
     * but can process objects if hashCode and equals can't be overridden
     * @param input - List of objects
     * @return - Map of objects by md5 key
     * @param  - Object class
     * @throws Exception - Serialization exceptions
     */
    public static  Map listToMD5Map(List input) throws Exception {
        Map dataMap = new HashMap();
        for (T object : input){
            dataMap.put(StringUtils.getMd5String(JsonSerializer.marshal(object)), object);
        }
        return dataMap;
    }

    /**
     * Used to remove values from lists that don't support remove method
     * @param input - List
     * @param index - Index to remove
     * @param  - Object class
     * @return - Result list with removed item
     */
    public static  List removeByIndex(List input, int index) {
        List result = new LinkedList(input);
        result.remove(index);

        //Doing that to keep original input class
        if (input.getClass().getName().equals("java.util.Arrays$ArrayList")){
            input = (List) Arrays.asList(result.toArray());
        } else {
            input.clear();
            input.addAll(result);
        }
        return input;
    }

    /**
     * Remove duplicate values of list from map
     * @param values - Map of values
     * @param  - Object class
     * @param  - Key
     * @return - Result Map without duplcates
     */
    public static  Map> removeDuplicateValues(Map> values) {
        if (values == null){
            return values;
        }
        Map> newValues = new LinkedHashMap>();
        for (K key : values.keySet()) {
            newValues.put(key, removeDuplicateValues(values.get(key)));
        }
        return newValues;
    }

    /**
     * Remove duplicate values of list from list
     * @param values - List of values to filter
     * @param  - Object class
     * @return - Filtered list
     */
    public static  List removeDuplicateValues(List values) {
        if (values == null){
            return values;
        }
        return new ArrayList(new HashSet(values));
    }


    /**
     * Reorder a list of elements by another list. Trying to keep absolute order of initial list
     * but reorder regarding to provided relative order list.
     * E.g. initial was [1, 2, 3, 4, 5] - calling reorder with list [2, 5, 4] will generate list
     * [1, 2, 3, 5, 4]
     * @param elements - initial list
     * @param order - list describing relative order
     * @param  - Class of comparable object
     * @return - new reordered list
     */
    public static  List reorder(List elements, List order){
        final Map orderMap = new LinkedHashMap<>();
        for (int i = 0; i < order.size(); i++){
            orderMap.put(order.get(i), new Long(i));
        }

        //Can't use 0(NLogN) sort (quick or merge) - need to compare each element with each
        for (int i = 0; i < elements.size(); i++){
            for (int j = i + 1; j < elements.size(); j++){
                if (compare(elements.get(i), elements.get(j), orderMap) > 0){
                    swap(elements, i, j);
                }
            }
        }
        return elements;
    }

    /**
     * Compare objects values from map by provided keys
     * @param o1
     * @param o2
     * @param orderMap
     * @param 
     * @return
     */
    private static int compare(T o1, T o2, Map orderMap) {
        Long order1 = orderMap.get(o1);
        Long order2 = orderMap.get(o2);
        if (order1 != null && order2 != null){
            return order1.compareTo(order2);
        }
        return o1.compareTo(o2);
    }

    /**
     * Swap two elements in list
     * @param elements - list of elements
     * @param i - index of first element
     * @param j - index of second element
     * @param  - elements class
     */
    public static  void swap(List elements, int i, int j) {
        T buff = elements.get(j);
        elements.set(j, elements.get(i));
        elements.set(i, buff);
    }



}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy