CollectionUtil集合工具类

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;
	}

}

猜你喜欢

转载自blog.csdn.net/wang_snake/article/details/80672066
今日推荐