在文件 nameList.txt 中按下图格式存放着超过50万人的姓名与身份证信息。请使用您熟悉的编程语言(Java或C/C++)编写一段程序, 将出生日期落在1995年1月1日与1999年12月31日之间的个人信息取出,按年龄从大到小排列并输出到另一个txt文件中。 请重点考虑程序的健壮性和排序效率

小生想到思路:

  1. 先读取文本内容;

  2. 将头信息读取出来,并记录住;

  3. 将真实数据按照行进行读取并封装到 javabean 中:每读取一行,将这行的数据用javabean封装,将这个javabean添加到 list 列表中:

  4. 将得到的 list 列表进行排序,按照出生日期排序,这题正好:出生日期可以作为数字来看待,数字小的就是出生早的;

  5. 将头信息和 list 列表再输出到指定文件中

注意:

题目是要求50万条数据记录进行读取排序,所以一定要想到包装类IO

还有就是要考虑健壮性和排序效率,健壮性,最完美的设计就是无论传递给程序什么javabean,程序都能把读到的数据封装成这个javabean

小生想到的就是动态代理和泛型。

具体实现代码如下(小生这里没有采用包装类了):

 package com.hy.demo;

 import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import com.hy.demo.UserComparator.SortType; public class DemoTest {
public static void main(String[] args) {
String inpathName = "D:/Workspaces/eclipse-marks-2/hire/src/name_list.txt"; String content = getFileContent(inpathName); // 得到用户数据列表
List<User> userList = getList(content, 3,"19950101","19991231");
// 按照出生日期排序用户列表
String context = orderByUser(userList, SortType.ASC);
// 获取头信息
String header = getHeader(content, 3);
String outpathName = "D:/Workspaces/eclipse-marks-2/hire/src/a.txt";
write(header, context, outpathName);
} public static void write(String header,String context,String outPathName) {
FileOutputStream fos =null;
try {
fos = new FileOutputStream(outPathName);
fos.write(header.getBytes());
fos.write(context.getBytes()); fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fos!=null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} } /**
* 对用户列表排序,并输出成文本格式
* @param list
* @param sortType ASC:按照出生日期升序,DESC:按照出生降序
* @return
*/
public static String orderByUser(List<User> list,SortType sortType) {
if(list!=null && list.size()>0) {
Collections.sort(list, new UserComparator(sortType));
StringBuffer sb = new StringBuffer(); for(int i=0;i<list.size();i++) {
User user = list.get(i);
sb.append(user.getName()).append(" \t\t");
sb.append(user.getGener()).append("\t\t");
sb.append(user.getIdCard()).append("\t\t");
sb.append(user.getAddress()).append("\r\n");
}
return sb.toString();
}
return null;
} /**
* 读取文本,获取数据源
*
* @param path
* @return
*/
public static String getFileContent(String path) {
File file = new File(path);
// 分配新的直接字节缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);
StringBuffer stringBuffer = new StringBuffer(1024);
try {
FileInputStream fileInputStream = new FileInputStream(file);
// 用于读取、写入、映射和操作文件的通道。
FileChannel fileChannel = fileInputStream.getChannel();
// 编码字符集和字符编码方案的组合,用于处理中文,可以更改
Charset charset = Charset.forName("UTF-8");
while (fileChannel.read(byteBuffer) != -1) {
// 反转此缓冲区
byteBuffer.flip();
CharBuffer charBuffer = charset.decode(byteBuffer);
stringBuffer.append(charBuffer.toString());
byteBuffer.clear();
}
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return stringBuffer.toString();
} /**
* 获取数据列表
* @param <T>
* @param content
* @param num 指定头信息含有多少行
* @return
*/
public static List getList(String content, int num,String start, String end) { // 将文本行信息按照行截取
String[] strs = content.split("\r\n"); if(num>strs.length) {
throw new RuntimeException("文本头行数参数不能大于文本总行数!");
} // 接收数据,按照行接收
List<User> list = new ArrayList<User>();
Integer date;
for (int i = num; i < strs.length; i++) {
// 将每一行的数据封装到User对象中
String[] userParams = strs[i].split("\t\t");
User user = new User();
user.setName(userParams[0]);
user.setGener(userParams[1]);
user.setIdCard(userParams[2]);
user.setAddress(userParams[3]);
// 将每一行数据添加到列表中 // 选择出生日期区间
if(start!=null&&!"".equals(start) && end!=null&&!"".equals(end)) {
date = Integer.parseInt(user.getIdCard().substring(6, 14));
if(date>= Integer.parseInt(start)&&date<=Integer.parseInt(end) ) {
list.add(user);
}
}
}
return list;
} /**
* 获取头信息
* @param context 指定要获取的文本内容
* @param num 指定获前几行
* @return
*/
public static String getHeader(String context, int num) {
// 将文本行信息按照行截取
String[] strs = context.split("\r\n");
// 接收头信息
StringBuffer headStringBuffer = new StringBuffer(); for (int i = 0; i < num; i++) {
headStringBuffer.append(strs[i]).append("\r\n");
}
// 获取头信息
return headStringBuffer.toString();
} }

javabean封装类:

public class User {
private String name;
private String gener;
private String idCard;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGener() {
return gener;
}
public void setGener(String gener) {
this.gener = gener;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [name=" + name + ", gener=" + gener + ", idCard=" + idCard + ", address=" + address + "]";
} }

javabean比较器:

public class UserComparator implements Comparator<User> {

    public enum SortType {
ASC, DESC
} public UserComparator(SortType sortType) {
this.sortType = sortType;
} private SortType sortType; @Override
public int compare(User o1, User o2) {
int o1Date = Integer.parseInt(o1.getIdCard().substring(6, 14));
int o2Date = Integer.parseInt(o2.getIdCard().substring(6, 14));
switch (sortType) {
case ASC:
if (o1Date > o2Date) {
return 1;
} else if (o1Date < o2Date) {
return -1;
}
break;
case DESC:
if (o1Date > o2Date) {
return -1;
} else if (o1Date > o2Date) {
return 1;
}
break; default:
break;
}
return 0;
} }

读者们,如果有更好思路和细节处理,欢迎留言讨论,谢谢!

遇到一道经典的java面试题的更多相关文章

  1. OpenJDK源码研究笔记(五)-缓存Integer等类型的频繁使用的数据和对象,大幅度提升性能(一道经典的Java笔试题)

    摘要 本文先给出一个看似很简单实则有深意的Java笔试面试题,引出JDK内部的缓存. JDK内部的缓存,主要是为了提高Java程序的性能. 你能答对这道"看似简单,实则有深意"的J ...

  2. 一道经典的Java面试题:equals ,== 和hashcode()的区别

    一句话区别:==比较的是内存地址,equals比较的是值内容 结论: 从以下三点展开: 基本数据类型.字符串.对象 对于基本数据类型:只有==,没有equals. 对于字符串:==比较的是内存地址,e ...

  3. 10个经典的Java面试题

    这里有10个经典的Java面试题,也为大家列出了答案.这是Java开发人员面试经常容易遇到的问题,相信你了解和掌握之后一定会有所提高.让我们一起来看看吧. 1.Java的HashMap是如何工作的? ...

  4. 10个经典的Java面试题集合

    这里有10个经典的Java面试题,也为大家列出了答案.这是Java开发人员面试经常容易遇到的问题,相信你了解和掌握之后一定会有所提高.让我们一起来看看吧. 1.Java的HashMap是如何工作的? ...

  5. 100多道经典的JAVA面试题及答案解析

    面向对象编程(OOP) Java是一个支持并发.基于类和面向对象的计算机编程语言.下面列出了面向对象软件开发的优点: 代码开发模块化,更易维护和修改. 代码复用. 增强代码的可靠性和灵活性. 增加代码 ...

  6. OpenJDK源码研究笔记(二)-Comparable和Comparator2个接口的作用和区别(一道经典的Java笔试面试题)

    Comparable和Comparator是JDK中定义的2个比较接口,很相似,但又有所不同. 这2个接口的作用和区别也是Java中的常见经典面试题. 下面我们就来详细介绍下这2个接口的定义.作用.区 ...

  7. 一道简单的 Java 笔试题,但值得很多人反思!

    前言 面试别人,对我来说是一件新奇事,以前都是别人面试我.我清楚地知道,我在的地域与公司,难以吸引到中国的一流软件人才.所以,我特地调低了期望,很少问什么深入的技术问题,只问一些广泛的.基础的.我只要 ...

  8. 一道经典的js面试题

    # 声明:学习编程语言最好的方式就是通过实例学习 ## 下面是我在博客上看到的一道js面试题,可以说非常经典,下面会以最简单的方式让你理解题目:```bashfunction Foo() { getN ...

  9. 15 道超经典大厂 Java 面试题!重中之重

    从超高频的后端面试题出发,指明学习方向 大家好,我是鱼皮. 还记得我的老弟小阿巴么?他目前正值大一暑假,在家自学编程(刷短视频)中. 他整个大一期间基本都在学习前端.后来,我带他写了一次后端,结果就崩 ...

随机推荐

  1. BZOJ3629(JLOI2014)聪明的燕姿

    (⊙﹏⊙)我交了好久,有坑啊...(如果没有匹配的话,即输出0种情况要记得换行...) 就是搜索,加上一点数论,并不太难... #include<cstdio> #include<c ...

  2. iOS 社交化分享功能

    iOS 开发过程中可能会遇到需要进行第三方分享的需求,比如向QQ,微信,微博等分享 如下图 我们今天要讲到的方式是使用了一个第三方工具: http://www.sharesdk.cn 一,注册账号 去 ...

  3. json与javabean之间的转化

    接着上一个http://www.cnblogs.com/ya-qiang/p/9009134.html随笔,继续介绍json与java对象之间的转化 一.java普通对象和json字符串的互转 jav ...

  4. safari 浏览器 input textarea select 等不能响应用户输入

    解决办法 -webkit-user-select:auto; /*webkit浏览器*/ user-select:auto; -o-user-select:auto; -ms-user-select: ...

  5. 【工具篇】抓包中的王牌工具—Fiddler (1-环境搭建)

    导言 在现在高速发展的互联网时代,抓包工具被广泛应用在软件开发的项目中,Fiddler可谓是当下主流的抓包工具之一.测试人员用它来抓包.回放测试记录,构造发包测试用例,开发人员用来定位问题,其强大的功 ...

  6. Java编程思想 - 并发

    前言 Q: 为什么学习并发? A: 到目前为止,你学到的都是有关顺序编程的知识,即程序中的所有事物在任意时刻都只能执行一个步骤. A: 编程问题中相当大的一部分都可以通过使用顺序编程来解决,然而,对于 ...

  7. 再谈腾讯云centos服务器不能登录的解决过程

    上篇文章谈到腾讯云centos服务器不能登录,通过查看监控信息,cpu使用过高,再腾讯云页面使用VNC方式直接登录,然后根据提示信息,关闭导致内存溢出的进程,从而解决问题. 1 问题再现 昨天刚解决了 ...

  8. Python与家国天下

    导读:Python猫是一只喵星来客,它爱地球的一切,特别爱优雅而无所不能的 Python.我是它的人类朋友豌豆花下猫,被授权润色与发表它的文章.如果你是第一次看到这个系列文章,那我强烈建议,请先看看它 ...

  9. sqlite数据库如何远程连接?

    sqlite数据库如何远程连接代码如下:QSqlDatabase db =QSqlDatabase::addDatabase("QSQLITE"); db.setHostName( ...

  10. 不同数据库的表迁移SqlServer

    INSERT INTO table  SELECT *  FROM  OPENDATASOURCE ('SQLOLEDB', 'Data Source=172.168.44.146;User ID=s ...