package com.uama.utils;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
/**
* 集合操作工具类
*
* @since 1.0
*/
public class CollectionUtil {
private CollectionUtil() {
throw new IllegalStateException("Utility class");
}
/**
* 判断集合是否非空
*/
public static boolean isNotEmpty(Collection<?> collection) {
return CollectionUtils.isNotEmpty(collection);
}
/**
* 判断集合是否为空
*/
public static boolean isEmpty(Collection<?> collection) {
return CollectionUtils.isEmpty(collection);
}
public static <T> List<T> deepCopy(List<T> src) {
// Modified By Fangxm 2017.07.21 使用1.8的特性stream()来拷贝
// ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
// ObjectOutputStream out = new ObjectOutputStream(byteOut);
// out.writeObject(src);
//
// ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
// ObjectInputStream in = new ObjectInputStream(byteIn);
// @SuppressWarnings("unchecked")
// List<T> dest = (List<T>) in.readObject();
// return dest;
if (src == null) {
return null;
}
return src.stream().collect(Collectors.toList());
}
/**
* 获取交集
* 交集的获取方法:
* 例:
* 集合A:{1,2,3}
* 集合B:{3,4}
* 先获取集合A和集合B的差集C:{1,2}
* 再获取集合A和差集C的差集D:{3},差集D就是交集
* Added By Fangxm 2017.06.06
* @param from 集合A
* @param src 集合B
* @return
* @throws ClassNotFoundException
* @throws IOException
*/
// Deleted By Fangxm 2017.11.27 之前的做法太粗暴了, 用removeAll的效率并不是很好, 改用Map的做法
// public static <T> List<T> intersection(List<T> from, List<T> src) {
// if (src == null || src.isEmpty()) {
// return null;
// }
// if (from == null || from.isEmpty()) {
// return null;
// }
// List<T> dest = deepCopy(from);
// List<T> dif = differenceSet(from, src);
// dest.removeAll(dif);
// return dest;
// }
public static <T> List<T> intersection(final List<T> a, final List<T> b) {
if (a == null || a.isEmpty()) {
return null;
}
if (b == null || b.isEmpty()) {
return null;
}
ArrayList<T> list = new ArrayList<>();
Map<T, Integer> mapa = getCardinalityMap(a);
Map<T, Integer> mapb = getCardinalityMap(b);
Set<T> elts = new HashSet<>(a);
elts.addAll(b); // addAll时会自动去重
Iterator<T> it = elts.iterator();
while (it.hasNext()) {
T obj = it.next();
// 由于去过重了, list要add的次数是两者的较小值
for (int i = 0, m = Math.min(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; i++) {
list.add(obj);
}
}
return list;
}
/**
* 返回拥有相同obj的数量
* @param coll
* @return
*/
public static <T> Map<T, Integer> getCardinalityMap(final List<T> coll) {
Map<T, Integer> count = new HashMap<>();
for (Iterator<T> it = coll.iterator(); it.hasNext();) {
T obj = it.next();
Integer c = count.get(obj);
if (c == null) {
count.put(obj, 1);
} else {
count.put(obj, c.intValue() + 1);
}
}
return count;
}
private static final <T> int getFreq(final T obj, final Map<T, Integer> freqMap) {
Integer count = freqMap.get(obj);
if (count != null) {
return count.intValue();
}
return 0;
}
/**
* 获取差集
* 例:
* 集合A:{1,2,3}
* 集合B:{3,4}
* 集合A和集合B的差集C:{1,2}
* Added By Fangxm 2017.06.06
*/
public static <T> List<T> differenceSet(List<T> from, List<T> src) {
if (src == null || src.isEmpty()) {
return from;
}
if (from == null || from.isEmpty()) {
return from;
}
List<T> dest = deepCopy(from);
return removeAll(dest, src);
}
/**
* 一个比ArrayList效率更高的方法, ArrayList的removeAll会循环套循环, 处理效率会随着减数的变大而降低
* 改成用Map来处理, 可以有效降低处理次数
* 返回差集
* @param src 被减数
* @param tar 减数
* @return
*/
public static <T> List<T> removeAll(List<T> src, List<T> tar) {
if (src == null || src.isEmpty()) {
return src;
}
if (tar == null || tar.isEmpty()) {
return src;
}
ArrayList<T> list = new ArrayList<>();
Map<T, Integer> mapa = getCardinalityMap(src);
Map<T, Integer> mapb = getCardinalityMap(tar);
Set<T> elts = new HashSet<>(src);
Iterator<T> it = elts.iterator();
while (it.hasNext()) {
T obj = it.next();
int srcCount = getFreq(obj, mapa);
int tarCount = getFreq(obj, mapb);
if (srcCount > 0 && tarCount <= 0) {
for (int i = 0; i < srcCount; i++) {
list.add(obj);
}
}
}
src.clear();
src.addAll(list);
return list;
}
/**
* 根据指定的key对List<Map<K, V>> list进行排序(只支持数字)
* @param list
* @param sortKey
*/
public static <K, V> void sortNum(List<Map<K, V>> list, final K sortKey) {
Collections.sort(list, new Comparator<Map<K, V>>() {
public int compare(Map<K, V> arg0, Map<K, V> arg1) {
// 先取出String,再转换成BigDecimal来比较大小
BigDecimal b0 = new BigDecimal(MapUtil.getString(arg0, sortKey));
BigDecimal b1 = new BigDecimal(MapUtil.getString(arg1, sortKey));
return b0.compareTo(b1);
}
});
}
/**
* 计算指定key的平均值
* @param list
* @param sortKey
* @return
*/
public static <K, V> BigDecimal calculateAvg(List<Map<K, V>> list, final K sortKey) {
return calculateAvg(list, sortKey, 2, BigDecimal.ROUND_HALF_EVEN);
}
public static <K, V> BigDecimal calculateAvg(List<Map<K, V>> list, final K sortKey, final int scale, final int roundingMode) {
BigDecimal avg = new BigDecimal(0);
if (list != null && !list.isEmpty()) {
BigDecimal sum = new BigDecimal(0);
for (Map<K, V> m : list) {
String num = MapUtil.getString(m, sortKey);
if (StringUtils.isBlank(num)) {
continue;
}
sum = sum.add(new BigDecimal(num));
}
return sum.divide(new BigDecimal(list.size()), scale, roundingMode);
}
return avg;
}
}
CollectionUtil集合工具类
猜你喜欢
转载自blog.csdn.net/wang_snake/article/details/80672066
今日推荐
周排行