zoukankan      html  css  js  c++  java
  • 遇到一道经典的java面试题

    在文件 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

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

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

      1 package com.hy.demo;
      2 
      3 import java.io.File;
      4 import java.io.FileInputStream;
      5 import java.io.FileNotFoundException;
      6 import java.io.FileOutputStream;
      7 import java.io.IOException;
      8 import java.lang.reflect.Constructor;
      9 import java.nio.ByteBuffer;
     10 import java.nio.CharBuffer;
     11 import java.nio.channels.FileChannel;
     12 import java.nio.charset.Charset;
     13 import java.util.ArrayList;
     14 import java.util.Collections;
     15 import java.util.List;
     16 
     17 import com.hy.demo.UserComparator.SortType;
     18 
     19 public class DemoTest {
     20     public static void main(String[] args) {
     21         String inpathName = "D:/Workspaces/eclipse-marks-2/hire/src/name_list.txt";
     22 
     23         String content = getFileContent(inpathName);
     24 
     25         // 得到用户数据列表
     26         List<User> userList = getList(content, 3,"19950101","19991231");
     27         // 按照出生日期排序用户列表
     28         String context = orderByUser(userList, SortType.ASC);
     29         // 获取头信息
     30         String header = getHeader(content, 3);
     31         String outpathName = "D:/Workspaces/eclipse-marks-2/hire/src/a.txt";
     32         write(header, context, outpathName);
     33     }
     34     
     35     public static void write(String header,String context,String outPathName) {
     36         FileOutputStream fos =null;
     37         try {
     38             fos = new FileOutputStream(outPathName);
     39             fos.write(header.getBytes());
     40             fos.write(context.getBytes());
     41             
     42             fos.flush();
     43         } catch (IOException e) {
     44             e.printStackTrace();
     45         } finally {
     46             if(fos!=null) {
     47                 try {
     48                     fos.close();
     49                 } catch (IOException e) {
     50                     e.printStackTrace();
     51                 }
     52             }
     53         }
     54         
     55     }
     56     
     57     /**
     58      * 对用户列表排序,并输出成文本格式
     59      * @param list
     60      * @param sortType ASC:按照出生日期升序,DESC:按照出生降序
     61      * @return
     62      */
     63     public static String orderByUser(List<User> list,SortType sortType) {
     64         if(list!=null && list.size()>0) {
     65             Collections.sort(list, new UserComparator(sortType));
     66             StringBuffer sb = new StringBuffer();
     67             
     68             for(int i=0;i<list.size();i++) {
     69                 User user = list.get(i);
     70                 sb.append(user.getName()).append("   		");
     71                 sb.append(user.getGener()).append("		");
     72                 sb.append(user.getIdCard()).append("		");
     73                 sb.append(user.getAddress()).append("
    ");
     74             }
     75             return sb.toString();
     76         }
     77         return null;
     78     }
     79 
     80     /**
     81      * 读取文本,获取数据源
     82      * 
     83      * @param path
     84      * @return
     85      */
     86     public static String getFileContent(String path) {
     87         File file = new File(path);
     88         // 分配新的直接字节缓冲区
     89         ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);
     90         StringBuffer stringBuffer = new StringBuffer(1024);
     91         try {
     92             FileInputStream fileInputStream = new FileInputStream(file);
     93             // 用于读取、写入、映射和操作文件的通道。
     94             FileChannel fileChannel = fileInputStream.getChannel();
     95             // 编码字符集和字符编码方案的组合,用于处理中文,可以更改
     96             Charset charset = Charset.forName("UTF-8");
     97             while (fileChannel.read(byteBuffer) != -1) {
     98                 // 反转此缓冲区
     99                 byteBuffer.flip();
    100                 CharBuffer charBuffer = charset.decode(byteBuffer);
    101                 stringBuffer.append(charBuffer.toString());
    102                 byteBuffer.clear();
    103             }
    104             fileInputStream.close();
    105         } catch (FileNotFoundException e) {
    106             e.printStackTrace();
    107         } catch (IOException e) {
    108             e.printStackTrace();
    109         }
    110         return stringBuffer.toString();
    111     }
    112 
    113     /**
    114      * 获取数据列表
    115      * @param <T>
    116      * @param content    
    117      * @param num    指定头信息含有多少行
    118      * @return
    119      */
    120     public static List getList(String content, int num,String start, String end) {
    121         
    122         // 将文本行信息按照行截取
    123         String[] strs = content.split("
    ");
    124         
    125         if(num>strs.length) {
    126             throw new RuntimeException("文本头行数参数不能大于文本总行数!");
    127         }
    128         
    129         // 接收数据,按照行接收
    130         List<User> list = new ArrayList<User>();
    131         Integer date;
    132         for (int i = num; i < strs.length; i++) {
    133             // 将每一行的数据封装到User对象中
    134             String[] userParams = strs[i].split("		");
    135             User user = new User();
    136             user.setName(userParams[0]);
    137             user.setGener(userParams[1]);
    138             user.setIdCard(userParams[2]);
    139             user.setAddress(userParams[3]);
    140             // 将每一行数据添加到列表中
    141             
    142             // 选择出生日期区间
    143             if(start!=null&&!"".equals(start) && end!=null&&!"".equals(end)) {
    144                 date = Integer.parseInt(user.getIdCard().substring(6, 14));
    145                 if(date>= Integer.parseInt(start)&&date<=Integer.parseInt(end) ) {
    146                     list.add(user);
    147                 }
    148             }
    149         }
    150         return list;
    151     }
    152 
    153     /**
    154      * 获取头信息
    155      * @param context    指定要获取的文本内容
    156      * @param num    指定获前几行
    157      * @return
    158      */
    159     public static String getHeader(String context, int num) {
    160         // 将文本行信息按照行截取
    161         String[] strs = context.split("
    ");
    162         // 接收头信息
    163         StringBuffer headStringBuffer = new StringBuffer();
    164 
    165         for (int i = 0; i < num; i++) {
    166             headStringBuffer.append(strs[i]).append("
    ");
    167         }
    168         // 获取头信息
    169         return headStringBuffer.toString();
    170     }
    171 
    172 }

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

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

  • 相关阅读:
    ios实例开发精品源码文章推荐
    Citrix 服务器虚拟化之二十七 XenApp6.5发布服务器桌面
    TOJ3651确定比赛名次
    TOJ3649欧拉回路
    强连通分量(LRJ训练指南)
    汉语-词语-体谅:百科
    汉语-词语-关心:百科
    汉语-词语-懒惰:百科
    汉语-词语-平静:百科
    汉语-词语-遗迹:百科
  • 原文地址:https://www.cnblogs.com/mujingyu/p/8763533.html
Copyright © 2011-2022 走看看