package com.example.util;
import com.google.common.collect.Lists;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.Collator;
import java.util.*;
import java.util.function.Function;
/**
* List工具
*
* @author bin
* @create 2019-11-06 14:08
**/
public class ListUtils {
/**
* 判断list是否为空
* @param list
* @return
*/
public static boolean isEmpty(List list){
if (list == null || list.isEmpty())
return true;
return false;
}
/**
* 提取对象的摸个属性
*
* @param list
* @param listExtract
* @param <T>
* @return
*/
public static <T, V> List<V> extract(List<T> list, Function<T, V> listExtract) {
if (isEmpty(list)) {
return new ArrayList<>();
}
List<V> result = new ArrayList<>(list.size());
for (T t : list) {
V v = listExtract.apply(t);
if (v != null)
result.add(v);
}
return result;
}
/**
* 设置对象的某个属性
*/
public static <T, V> void setPropertyValue(List<T> list, List<V> valueList, CollectionPropertyFunction<T, V> listExtract) {
for (int i= 0 ; i < list.size(); i++ ) {
T t = list.get(i);
V v = valueList.get(i);
listExtract.apply(t, v);
}
}
/**
* 批量设置对象的某个属性
*/
public static <T, V> void setPropertySameValue(List<T> list, V value, CollectionPropertyFunction<T, V> listExtract) {
for (int i= 0 ; i < list.size(); i++ ) {
T t = list.get(i);
listExtract.apply(t, value);
}
}
public static <T, K> Map<K,List<T>> map(List<T> list, Function<T, K> listMapKey) {
Map<K, List<T>> result = new HashMap<>(list.size());
for (T t : list) {
K k = listMapKey.apply(t);
if (k != null){
List<T> v= result.get(k);
if (v == null){
v=new ArrayList<>();
result.put(k,v);
}
v.add(t);
}
}
return result;
}
/**
* 对象拷贝
*
* @param list
* @param listMapKey
* @param <T>
* @return
*/
public static <T, K, V> Map<K, V> map(List<T> list, Function<T, K> listMapKey, Function<T, V> listMapValue) {
Map<K, V> result = new HashMap<>();
for (T t : list) {
K k = listMapKey.apply(t);
V v = listMapValue.apply(t);
if (k != null && v != null)
result.put(k, v);
}
return result;
}
public static <T, K> Map<K,T> toMap(List<T> list, Function<T, K> listMapKey) {
Map<K, T> result = new HashMap<>(list.size());
for (T t : list) {
K k = listMapKey.apply(t);
if (k != null){
result.put(k, t);
}
}
return result;
}
public static <T, K> Map<K, Integer> toMapFlag(List<T> list, Function<T, K> listMapKey) {
Map<K, Integer> result = new HashMap<>(list.size());
for (T t : list) {
K k = listMapKey.apply(t);
if (k != null){
result.put(k, 1);
}
}
return result;
}
public static <T, K, V> Map<K, V> toMapKV(List<T> list, Function<T, K> listMapKey, Function<T, V> listMapValue) {
Map<K, V> result = new HashMap<>(list.size());
for (T t : list) {
K k = listMapKey.apply(t);
V v = listMapValue.apply(t);
if (k != null){
result.put(k, v);
}
}
return result;
}
/**
* 将一组数据平均分成n组
* @param source
* @param n
* @param <T>
* @return
*/
public static <T> List<List<T>> averageAssign(List<T> source, int n){
List<List<T>> result=new ArrayList<List<T>>();
//(先计算出余数)
int remaider=source.size()%n;
//然后是商
int number=source.size()/n;
//偏移量
int offset=0;
for(int i=0;i<n;i++){
List<T> value=null;
if(remaider>0){
value=source.subList(i*number+offset, (i+1)*number+offset+1);
remaider--;
offset++;
}else{
value=source.subList(i*number+offset, (i+1)*number+offset);
}
result.add(value);
}
return result;
}
/**
* 将一组数据固定分组,每组n个元素
* @param source 要分组的数据源
* @param n 每组n个元素
* @param <T>
* @return
*/
public static <T> List<List<T>> fixedGrouping(List<T> source, int n) {
if (null == source || source.size() == 0 || n <= 0)
return Collections.EMPTY_LIST;
List<List<T>> result = new ArrayList<List<T>>();
int sourceSize = source.size();
int size = (source.size() / n) + 1;
for (int i = 0; i < size; i++) {
List<T> subset = new ArrayList<T>();
for (int j = i * n; j < (i + 1) * n; j++) {
if (j < sourceSize) {
subset.add(source.get(j));
}
}
result.add(subset);
}
return result;
}
/***
* 方法一对集合进行深拷贝 注意需要对泛型类进行序列化(实现Serializable)
*
* @param srcList
* @param <T>
* @return
*/
public static <T> List<T> depCopy(List<T> srcList) {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
try {
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(srcList);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream inStream = new ObjectInputStream(byteIn);
List<T> destList = (List<T>) inStream.readObject();
return destList;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return new ArrayList<>();
}
/**
* 把一个大的list拆分成多个小的list
* @param list
* @param size
* @param <T>
* @return
*/
public static <T> Map<Integer,List<T>> splitListToMap(List<T> list, int size){
Map<Integer,List<T>> result = new HashMap<>();
if(list != null && !list.isEmpty() && size > 0){
int i = 1;
List<T> splitList = new ArrayList<>();
for (T one : list) {
splitList.add(one);
if(splitList != null && splitList.size() == size){
result.put(i,splitList);
splitList = new ArrayList<>();
i ++;
}
}
if(splitList != null && !splitList.isEmpty()){
result.put(i,splitList);
}
}
return result;
}
/**
* 分割List
* @param list 待分割的list
* @param pageSize 每段list的大小
* @return List<<List<T>>
*/
public static <T> List<List<T>> splitList(List<T> list, int pageSize) {
int listSize = list.size();
int page = (listSize + (pageSize-1))/ pageSize;
List<List<T>> listArray = new ArrayList<List<T>>();
for(int i=0;i<page;i++) {
List<T> subList = new ArrayList<T>();
for(int j=0;j<listSize;j++) {
int pageIndex = ( (j + 1) + (pageSize-1) ) / pageSize;
if(pageIndex == (i + 1)) {
subList.add(list.get(j));
}
if( (j + 1) == ((j + 1) * pageSize) ) {
break;
}
}
listArray.add(subList);
}
return listArray;
}
public static <T> boolean isNotEmpty(List<T> list) {
if (isEmpty(list)) {
return false;
}
return true;
}
/**
* 获取俩个集合不相同的元素
* @param list1
* @param list2
* @return
*/
public static List getDiffElemList(List list1, List list2){
List listAll = new ArrayList();
List resultList= new ArrayList();
listAll.addAll(list1);
listAll.addAll(list2);
for (int i = 0; i < listAll.size(); i++) {
if(list1.contains(listAll.get(i)) && list2.contains(listAll.get(i))){
continue;
}else{
resultList.add(listAll.get(i));
}
}
return resultList;
}
/**
* 交集
*
* @param list1
* @param list2
* @param <T>
* @return
*/
public static <T> List<T> union(List<T> list1, List<T> list2) {
List<T> list1Copy = new ArrayList<>();
list1Copy.addAll(list1);
List<T> list2Copy = new ArrayList<>();
list2Copy.addAll(list2);
list1Copy.retainAll(list2Copy);
return list1Copy;
}
/**
* 差集
*
* @param list1
* @param list2
* @param <T>
* @return
*/
public static <T> List<T> subtract(List<T> list1, List<T> list2) {
List<T> list1Copy = new ArrayList<>();
list1Copy.addAll(list1);
List<T> list2Copy = new ArrayList<>();
list2Copy.addAll(list2);
list1Copy.removeAll(list2Copy);
return list1Copy;
}
public static <F> List<List<F>> spiltListAverageByEveryNum(List<F> sourceList){
return spiltListAverageByEveryNum(sourceList,50);
}
/**
* 把一个大的数组 平均拆分n个小的数组
* @param sourceList 要拆分的数组
* @param everyListNum 拆成的每个小数组容量
* @param <F>
* @return
*/
public static <F> List<List<F>> spiltListAverageByEveryNum(List<F> sourceList,Integer everyListNum){
int indexListSize = sourceList.size();
int listNum = indexListSize / everyListNum;
int leftNum = indexListSize % everyListNum;
if(leftNum >0){
listNum = listNum + 1;
}
return spiltListAverage(sourceList,listNum);
}
/**
* 把一个大的数组 平均拆分n个小的数组
* @param sourceList 要拆分的数组
* @param spiltNum 拆成小的数组个数
* @return 小的数组集合
*/
public static <F> List<List<F>> spiltListAverage(List<F> sourceList,Integer spiltNum){
List<List<F>> result = new ArrayList<>();
if(isEmpty(sourceList) || spiltNum == null || spiltNum <=0){
return result;
}
int indexListSize = sourceList.size();
int everyWeekCount = indexListSize / spiltNum;
// 平均完以后多出来的,放入前几个
int externalCount = indexListSize % spiltNum;
// 当前周的数字
int theSpiltNum = 1;
List indexRespDTOList = new ArrayList<>();
// 所有的指标平均分配,
for (int i = 0; i < indexListSize; i++) {
indexRespDTOList.add(sourceList.get(i));
// 拆分出来的每一个放的数量 余数为几就在前几个多放一个
int theWeekCount = theSpiltNum <= externalCount ? (everyWeekCount + 1) : everyWeekCount;
// 每一个的放满了,就新开一周
if(indexRespDTOList.size() == theWeekCount){
result.add(Lists.newArrayList(indexRespDTOList));
theSpiltNum ++;
indexRespDTOList.clear();
}
}
return result;
}
public static <T> Set<T> toSet(T[] t){
if (t == null || t.length <= 0) {
return new HashSet<>();
}
Set<T> result = new HashSet<>(t.length);
for (int i = 0; i< t.length; i++) {
result.add(t[i]);
}
return result;
}
/**
* list对对象中的字段进行排序
* @param list 待排序的列表
* @param orderType 排序{0,无序,1,ASC升序;2,DESC降序}
* @param orderByName 实体排序的字段
* */
public static <T> List<T> orderForList(List<T> list, Integer orderType, String orderByName) {
// 不需要排序
if (orderType == 0) {
return list;
}
if (isEmpty(list) || list.size() <= 1) {
return list;
}
//首字母转大写
String newStr = orderByName.substring(0, 1).toUpperCase() + orderByName.replaceFirst("\\w", "");
String methodStr = "get" + newStr;
Field declaredField = null;
boolean stringType = true;
// 排序类型的获取
try {
declaredField = list.get(0).getClass().getDeclaredField(orderByName);
Class<?> type = declaredField.getType();
if (type.equals(Integer.class) || type.equals(Float.class) || type.equals(Double.class) || type.equals(BigDecimal.class)) {
stringType = false;
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
final boolean flag = stringType;
Collections.sort(list, new Comparator<T>() {
@Override
public int compare(T obj1, T obj2) {
int retVal = 0;
try {
Method method1 = ((T) obj1).getClass().getMethod(methodStr, null);
Method method2 = ((T) obj2).getClass().getMethod(methodStr, null);
// 倒序
if (orderType == 2) {
// 是否按字符串比较
if (flag) {
// 字符串按 中英文 排序方式
Comparator<Object> chinaSort = Collator.getInstance(Locale.CHINA);
retVal = ((Collator) chinaSort).compare(method2.invoke(((T) obj1), null).toString(), method1.invoke(((T) obj2), null).toString());
// retVal = method2.invoke(((T) obj2), null).toString().compareTo(method1.invoke(((T) obj1), null).toString());
} else {
retVal = Double.valueOf(method2.invoke(((T) obj2), null).toString()).compareTo(Double.valueOf(method1.invoke(((T) obj1), null).toString()));
}
}
// 正序
if (orderType == 1) {
if (flag) {
// 字符串按 中英文 排序方式
Comparator<Object> chinaSort = Collator.getInstance(Locale.CHINA);
retVal = ((Collator) chinaSort).compare(method1.invoke(((T) obj1), null).toString(), method2.invoke(((T) obj2), null).toString());
// retVal = method1.invoke(((T) obj1), null).toString().compareTo(method2.invoke(((T) obj2), null).toString());
} else {
retVal = Double.valueOf(method1.invoke(((T) obj1), null).toString()).compareTo(Double.valueOf(method2.invoke(((T) obj2), null).toString()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return retVal;
}
});
return list;
}
}
package com.xrosstools.xunit.sample;
@FunctionalInterface
public interface CollectionPropertyFunction<T, V> {
void apply(T t, V v);
}