package fr.openwide.core.commons.util.collections;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.google.common.base.Equivalence;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public final class CollectionUtils {
private CollectionUtils() { }
/**
* Replaces all elements in <code>dst</code> by those in <code>src</code>.
* <p>This method is view-proof : it will work as expected even if <code>src</code> is a view of <code>dst</code>,
* i.e. if <code>src</code>'s content depends on <code>dst</code>'s (see for example
* {@link Collections#unmodifiableCollection(Collection)}, {@link Sets#union(java.util.Set, java.util.Set)}, ...).
* <p>In the process, this method may copy the elements of <code>src</code> in a new collection,
* hence it is not advisable to use it on large collections or in frequently called methods.
* @param dst The collection whose content is to be replaced. Not null.
* @param src The collection whose content is to be copied to <code>dst</code>, or null to simply clear <code>dst</code>.
*/
public static <T> void replaceAll(Collection<T> dst, Collection<? extends T> src) {
if (src == null) {
dst.clear();
} else {
Collection<T> elements = Lists.newArrayList(src);
dst.clear();
dst.addAll(elements);
}
}
/**
* Same as {@link CollectionUtils#replaceAll(Collection, Collection)}, but for {@link Map Maps}
*/
public static <K, V> void replaceAll(Map<K, V> dst, Map<? extends K, ? extends V> src) {
if (src == null) {
dst.clear();
} else {
Map<K, V> elements = Maps.newLinkedHashMap(src);
dst.clear();
dst.putAll(elements);
}
}
/**
* <strong>WARNING:</strong> very low efficiency (O(N*N))
* @return A list containing the elements of source that are not in filter, using <code>equivalence</code> to distinguish different elements.
*/
public static <T> List<T> difference(Iterable<? extends T> source, Iterable<? extends T> filter, Equivalence<? super T> equivalence) {
final List<T> result = new LinkedList<T>();
if (source != null && filter != null) {
sourceLoop: for (T sourceElement : source) {
for (T filterElement : filter) {
if (equivalence.equivalent(sourceElement, filterElement)) {
continue sourceLoop;
}
}
result.add(sourceElement);
}
} else if (source != null && filter == null) {
Iterables.addAll(result, source);
}
return result;
}
/**
* <strong>WARNING:</strong> very low efficiency (O(N*N))
* @return A list containing the elements of source that are also in filter, using <code>equivalence</code> to distinguish different elements.
*/
public static <T> List<T> intersection(Iterable<? extends T> source, Iterable<? extends T> filter, Equivalence<? super T> equivalence) {
final List<T> result = new LinkedList<T>();
if (source != null && filter != null) {
sourceLoop: for (T sourceElement : source) {
for (T filterElement : filter) {
if (equivalence.equivalent(sourceElement, filterElement)) {
result.add(sourceElement);
continue sourceLoop;
}
}
}
}
return result;
}
}