map数据的分组,list数据排序 数据筛选
sfit0144 (李四) 2015-01-10 18:00:25
1
Sfit0734 (Sfit0734) 2015-01-10 18:00:38
go home
sfit0144 (李四) 2015-01-10 18:09:52
下班
261340 (叶在宗) 2015-01-10 18:10:05
图片: {5F4C20B4-134F-4014-801D-8FFBA58587E9}.png
sfit0513 (蒋大有) 2015-01-10 18:43:55
下班
sfit0122 (雷一果) 2015-01-10 19:06:16
下班
将上面数据分析成下面格式,上面数据也是存在于文件当中,下面数据也是分析完后最后也放在文件当中
打卡日期 姓名 上班打卡 下班打卡
2015-01-10 何科 2015-01-10 19:46:05
2015-01-10 刘俊 2015-01-10 20:39:00
2015-01-10 匡磊 2015-01-10 19:43:52
2015-01-10 叶在宗 2015-01-10 18:10:05
2015-01-10 李四 2015-01-10 18:00:25 2015-01-10 18:09:52
2015-01-10 蒋大有 2015-01-10 18:43:55
2015-01-10 雷一果 2015-01-10 19:06:16
2015-01-13 何科 2015-01-13 09:22:58 2015-01-13 19:01:07
2015-01-13 刘俊 2015-01-13 09:26:34 2015-01-13 19:28:37
下面是代码:
public class MessageHistory { Map<String, MessageSenderInfo> lines = new HashMap<String, MessageSenderInfo>();
String outputPath;
public static void main(String[] args) {
MessageHistory messageHistory = new MessageHistory();
messageHistory.multiReadMessage();
messageHistory.outputCardRecordsToFile();
} public MessageHistory() {
outputPath = System.getProperty("user.dir")+File.separator+formatDate(new Date()) + "—打卡记录.txt";
File f = new File(outputPath);
if(f.exists()){
f.delete();
}
} /**
* 消息文件以work开头
* 读取文件
*/
public void multiReadMessage(){
File dir = new File(System.getProperty("user.dir"));
if(dir.getParentFile().exists()){
for(File file:dir.listFiles()){
if(file.getName().trim().matches("^work.*\\.txt$")){
System.out.println("start read "+file.getAbsolutePath());
readMessage(file.getAbsolutePath());
}
}
}
} public void lineToMap(String line) {
if (line.matches("^[A-Za-z0-9]{6}.*")) {
int index = line.indexOf("(");
int lastIndex = line.lastIndexOf(")");
if (index > 0 && lastIndex > 0) {
String workCode = line.substring(0, index);
String name = line.substring(index + 1, lastIndex);
String dateStr = line.substring(lastIndex + 1).trim();
Date date = parseDate(dateStr);
String key = formatDate(date) + "--" + workCode;
MessageSenderInfo recoderBean = lines.get(key);
if (recoderBean == null) {
recoderBean = new MessageSenderInfo(workCode, name);
recoderBean.setAtWorkTime(date);
} else {
if (recoderBean.getOffWorkTime() == null) {
recoderBean.setOffWorkTime(date);
}else{
if(date.getTime() < recoderBean.getAtWorkTime().getTime()){
recoderBean.setAtWorkTime(date);
}else if(date.getTime() > recoderBean.getOffWorkTime().getTime()){
recoderBean.setOffWorkTime(date);
}
} }
lines.put(key, recoderBean);
}
}
} public List<Map.Entry<String,MessageSenderInfo>> sortMessage(){
List<Map.Entry<String,MessageSenderInfo>> list = new ArrayList<Map.Entry<String,MessageSenderInfo>>(lines.entrySet());
Collections.sort(list, new MessageComparator());
return list;
}
/**
* 输出到文件
*/
public void outputCardRecordsToFile() {
printHeader();
System.out.println("总记录:"+lines.size());
List<Map.Entry<String,MessageSenderInfo>> list = sortMessage();
for (Map.Entry<String, MessageSenderInfo> e : list) {
MessageSenderInfo messageSenderInfo = e.getValue();
String line = formatDate(messageSenderInfo.getAtWorkTime()) + " "+
formatStringLen(messageSenderInfo.getName(),8) + " " ;
if(messageSenderInfo.getOffWorkTime() == null){
if(getHour(messageSenderInfo.getAtWorkTime()) >= 12){
line += formatStringLen("",21);
}
line+=formatLongDate(messageSenderInfo.getAtWorkTime());
}else
if(messageSenderInfo.getOffWorkTime() != null){
line += formatLongDate(messageSenderInfo.getAtWorkTime()) + " " ;
line+=formatLongDate(messageSenderInfo.getOffWorkTime());
}
writeLine(outputPath, line);
}
}
/**
* 打印头部
*/
public void printHeader(){
String line = formatStringLen("打卡日期",12)+
formatStringLen("姓名",10)+
formatStringLen("上班打卡",21)+
formatStringLen("下班打卡",21);
writeLine(outputPath, line);
} /**
* 格式化字符串长度
* @param s
* @param len
* @return
*/
public String formatStringLen(String s, int len) {
if (len > s.getBytes().length) {
StringBuilder sBuilder = new StringBuilder(s);
for (int i = 0; i < len - s.getBytes().length; i++) {
sBuilder.append(" ");
}
return sBuilder.toString();
}
return s;
} public void writeLine(String path, String s) {
File f = new File(path);
OutputStream os = null;
try {
os = new FileOutputStream(f, true);
Writer wirte = new OutputStreamWriter(os, "UTF-8");
BufferedWriter bufferedWriter = new BufferedWriter(wirte);
bufferedWriter.write(s);
bufferedWriter.newLine();
bufferedWriter.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
os = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} public void readMessage(String path) {
InputStream ins = null;
BufferedReader buf = null;
try {
ins = new FileInputStream(path);
buf = new BufferedReader(new InputStreamReader(ins, codeString(path)));
String line = null;
while ((line = buf.readLine()) != null) {
lineToMap(line.trim());
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ins != null) {
try {
ins.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} /**
* 排序比较
* @author sfit0734
*
*/
class MessageComparator implements Comparator<Map.Entry<String,MessageSenderInfo>> {
@Override
public int compare(Map.Entry<String,MessageSenderInfo> e1, Map.Entry<String,MessageSenderInfo> e2) {
MessageSenderInfo m1 = e1.getValue();
MessageSenderInfo m2 = e2.getValue();
String dateStr = formatDate(m1.getAtWorkTime());
String dateStr1 = formatDate(m2.getAtWorkTime()); int result = dateStr.compareTo(dateStr1);
if(result != 0){
return result;
}else{
return m1.getName().compareTo(m2.getName());
}
}
}; public Date parseDate(String dataStr) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//String dateString = formatter.format(currentTime);
Date date = null;
try {
date = formatter.parse(dataStr);
} catch (ParseException e) { e.printStackTrace();
}
return date;
} public String formatDate(Date date) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String dateString = formatter.format(date); return dateString;
} public String formatLongDate(Date date) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = formatter.format(date); return dateString;
}
/**
* 获取小时
* @param d
* @return
*/
public int getHour(Date d){
Calendar cal=Calendar.getInstance();
cal.setTime(d); return cal.get(Calendar.HOUR_OF_DAY);
} /**
* 判断文件的编码格式
* @param fileName :file
* @return 文件编码格式
* @throws IOException
* @throws Exception
*/
public String codeString(String fileName) throws IOException {
BufferedInputStream bin = new BufferedInputStream(
new FileInputStream(fileName));
int p = (bin.read() << 8) + bin.read();
String code = null; switch (p) {
case 0xefbb:
code = "UTF-8";
break;
case 0xfffe:
code = "Unicode";
break;
case 0xfeff:
code = "UTF-16BE";
break;
default:
code = "GBK";
} return code;
} class MessageSenderInfo {
String workCode;
String name;
Date atWorkTime;
Date offWorkTime; public MessageSenderInfo() {
super();
// TODO Auto-generated constructor stub
} public MessageSenderInfo(String workCode, String name) {
super();
this.workCode = workCode;
this.name = name; } public String getWorkCode() {
return workCode;
} public void setWorkCode(String workCode) {
this.workCode = workCode;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Date getAtWorkTime() {
return atWorkTime;
} public void setAtWorkTime(Date atWorkTime) {
this.atWorkTime = atWorkTime;
} public Date getOffWorkTime() {
return offWorkTime;
} public void setOffWorkTime(Date offWorkTime) {
this.offWorkTime = offWorkTime;
}
}
}
map数据的分组,list数据排序 数据筛选的更多相关文章
- [转]WPF and Silverlight 学习笔记(二十五):使用CollectionView实现对绑定数据的排序、筛选、分组
在第二十三节,我们使用CollectionView实现了对于绑定数据的导航,除导航功能外,还可以通过CollectionView对数据进行类似于DataView的排序.筛选等功能. 一.数据的排序: ...
- 开始VS 2012中LightSwitch系列的第4部分:太多信息了!使用查询来排序和筛选数据
[原文发表地址] Beginning LightSwitch in VS 2012 Part 4: Too much information! Sorting and Filtering Data ...
- MySQL 对分组后的同类数据进行拼接字符串
MySQL 对分组后的同类数据进行拼接字符串 写后台方法时遇到个问题,需要将表内同一订单号的操作记录流水进行简单拼接输出,不想取出来再操作,找了个mysql的方法直接操作 //group_concat ...
- oracle 根据字段分组取第一条数据及rank函数说明
当前有这样一个需求,根据外键对子表数据进行分组,取每组中的一条数据就行了,如图: 如:COMMANDID = 26的有两条,只取一条数据. sql语句: select * from(select SY ...
- mybatis从数据库中取数据且分组,返回分组数据
mapper.xml文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PU ...
- Java将数据进行分组处理
将传人的数据进行分组,使用map保存每组的数据. /** * 将取出的数据进行分组 * @param list * @return */ public Map<Integer,Object> ...
- 用 Python 排序数据的多种方法
用 Python 排序数据的多种方法 目录 [Python HOWTOs系列]排序 Python 列表有内置就地排序的方法 list.sort(),此外还有一个内置的 sorted() 函数将一个可迭 ...
- mysql 查询数据时按照A-Z顺序排序返回结果集
mysql 查询数据时按照A-Z顺序排序返回结果集 $sql = "SELECT * , ELT( INTERVAL( CONV( HEX( left( name, 1 ) ) , 16, ...
- MFC listcontrol 分列 添加行数据 点击列头排序
适用于 对话框程序 1.在工具箱中拖出 ListControl,然后右键-属性,view-Report 让你的ListControl变成这幅模样! 2.添加ListControl控件的control类 ...
- IOS第七天(3:UiTableView 模型和数据的分组的显示)
*************UiTableView模型和数据的分组的显示 #import "HMViewController.h" #import "HMHero.h&qu ...
随机推荐
- [luoguP3172] [CQOI2015]选数(递推+容斥原理)
传送门 不会莫比乌斯反演,不会递推. 但是我会看题解. 先将区间[L,H]变成(L-1,H],这样方便处理 然后求这个区间内gcd为k的方案数 就是求区间((L-1)/k,H/k]中gcd为1的方案数 ...
- P1122 最大子树和 (树形DP)
题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...
- java面试题之能创建volatile数组吗?
答:能,只不过只是一个指向数组的引用,而不是整个数组,如果改变了引用指向的数组,将会受到volatile的保护,但是如果多个线程同时改变数组的元素,volatile关键字就不能起到保护的作用.
- JConsole手册
一篇Sun官方网站上介绍JConsole使用的文章,前段时间性能测试的时候大概翻译了一下以便学习,今天整理一下发上来,有些地方也不知道怎么翻,就保留了原文,可能还好理解点,呵呵,水平有限,翻的不好,大 ...
- R语言入门视频笔记--5--自定义函数
自定义函数 你可以输出一段代码,创建一个你自己定义的函数 蛋是如果你两个自定义函数的名字重复的话,后面的会把前面的替换掉 举个栗子: hanshu1 <- function(x) sqrt(v ...
- hadoop 学习(二)
我们很荣幸能够见证Hadoop十年从无到有,再到称王.感动于技术的日新月异时,希望通过这篇内容深入解读Hadoop的昨天.今天和明天,憧憬下一个十年. 本文分为技术篇.产业篇.应用篇.展望篇四部分 技 ...
- 迈出从3K到1W的重要一步——掌握设计模式
IT职场的小菜经常有这样的疑问: 为什么一个相似的功能,大牛一会儿就搞定,然后悠闲地品着下午茶逛淘宝:而自己加班加点搞到天亮还做不完. 为什么用户提出需求变更后,大牛只需潇洒地敲敲键盘,改改配置:而自 ...
- Ionic 学习笔记
本文为原创,转载请注明出处: cnzt 文章:cnzt-p http://www.cnblogs.com/zt-blog/p/7831153.html 注: 本篇学习笔记基于Ionic 3 ...
- flask结合令牌桶算法实现上传和下载速度限制
限流.限速: 1.针对flask的单个路由进行限流,主要场景是上传文件和下载文件的场景 2.针对整个应用进行限流,方法:利用nginx网关做限流 本文针对第一中情况,利用令牌桶算法实现: 这个方法:h ...
- 第二讲_图像数据处理Image Data Processing
第二讲_图像数据处理Image Data Processing 深度模型出现后被弱化,但是思想的影子在深度模型中可以看到的 图片存储原理 RGB颜色空间:三通道(b,g,r),加法混色 CMY(K): ...