应用场景:
需要在浏览器打开本地文件进行详情展示并且可以根据某列进行排序,但是文件内容可能有上千三万条数据,html浏览器自带的排序功能比较卡(千条以上数据根据某一列排序大概需要5s左右),所以采用后端对文件进行排序。
文件格式:
SortFileUtil工具类:
public class SortFileUtil {
/**
* 对文件内容进行排序
*
* @param readFile 文件内容List<List<Object>>
* @param page 当前页
* @param pageSize 显示多少行数据
* @param sortLine 参照排序的列-索引
* @param sortType true正序、false倒叙
* @return 排序后的List<List<Object>>数据
*/
public static List<List<Object>> sortFile(List<List<Object>> readFile, int page, int pageSize, int sortLine, boolean sortType) {
// 封装每行数据,key=行标识 value=行数据
//Map<Integer, List<SortEntity>> map = new HashMap<>();
Map<Integer, List<Object>> map = new HashMap<>();
// 封装排序的列,key=行标识,value=数据
Map<Integer, Double> sortLineMap = new HashMap<>();
// 每行数据的标识码
int lineIdentification = 0;
// 变量封装到Sortentity中
for (List list : readFile) {
if (lineIdentification == 0) {
lineIdentification++;
continue;
} else {
lineIdentification++;
}
// 封装每行数据
List<Object> lineEntity = new ArrayList();
int lineLength = 0;
for (Object obj : list) {
lineEntity.add(obj);
// 排序的列
if (lineLength == sortLine) {
sortLineMap.put(lineIdentification, Double.valueOf(obj.toString()));
}
lineLength++;
}
map.put(lineIdentification, lineEntity);
}
// 封装最终排序后的数据
List<List<Object>> dataList = new ArrayList();
// 对列数据进行排序
List<Map.Entry<Integer, Double>> list = mapCompareSort(sortLineMap, sortType);
// 获取排序后的列标识,从封装每行数据map中获取原始数据
for (Map.Entry<Integer, Double> mapping : list) {
//System.out.println(mapping.getKey() + ":" + mapping.getValue());
List<Object> sortEntities = map.get(mapping.getKey());
dataList.add(sortEntities);
}
// 开启分页
if (page > 0 && pageSize > 0){
return dataList.subList((page - 1) * pageSize, pageSize > dataList.size() ? dataList.size() : pageSize);
}
return dataList;
}
/**
* 对map进行排序
*
* @param map 列数据
* @param sortType true=正序、false=倒叙
* @return 排序后的List数据
*/
private static List<Map.Entry<Integer, Double>> mapCompareSort(Map<Integer, Double> map, boolean sortType) {
// 这里将map.entrySet()转换成list
List<Map.Entry<Integer, Double>> list = new ArrayList<Map.Entry<Integer, Double>>(map.entrySet());
// 然后通过比较器来实现排序
Collections.sort(list, new Comparator<Map.Entry<Integer, Double>>() {
// 排序
@Override
public int compare(Map.Entry<Integer, Double> o1, Map.Entry<Integer, Double> o2) {
if (sortType) {
// 升序
return o1.getValue().compareTo(o2.getValue());
} else {
// 降序
return o2.getValue().compareTo(o1.getValue());
}
}
});
return list;
}
}
使用:
ReadStrategyContent()是使用之前写过的策略类读取的文件:
public static void main(String[] args) {
// >>>>>> 模拟前端传过来的数据 <<<<<<
int page = 1; // 当前页
int pageSize = 20; // 显示多少条(行)数据
int sortLine = 13; // 对哪一列数据进行排序 - 取列的索引
boolean sortType = false; // true=正序、false=倒叙
// 读取本地文件数据内容
ReadStrategyContent readStrategyContent = new ReadStrategyContent();
List<List<Object>> readFile = readStrategyContent.getReadFile("C:\\Users\\cq\\Desktop\\Result20200618102706105.dat", 10000);
// 对数据排序
List<List<Object>> lists = SortFileUtil.sortFile(readFile, page, pageSize, sortLine, sortType);
// 打印数据
for (List<Object> list1 : lists) {
for (Object sortObj : list1) {
System.out.print(sortObj +" ");
}
System.out.println();
}
}