
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