今天在百度知道看到这么一个问题
原问题链接:http://zhidao.baidu.com/question/219278917.html#here
读取TXT文件的格式为:字母 数字
如: TOM 100
JACK 200
BILL 50
CATHY 150
然后按照数字大小排序(由大到小)
输出TXT文件格式为:
JACK 200
CATHY 150
TOM 100
BILL 50
问题补充:
最后一行输出平均值=总和/人数
如:平均值=(200+150+100+50)/4=125
输出为一个新生成的TXT文件,不改变原文件
如读取文件为test.txt, 输出文件为text1.txt
觉得蛮有意思的,就动手做了个,大家也和我一起来
1.首先在D盘建了个name.txt文件,里面内容写上
TOM 100
JACK 200
BILL 50
CATHY 150
2.java 读取文件内容
我新建了个FeLongIoTest.class,新建了个读取文件内容通用方法
/**
* 读取文件内容
*
* @param path
* 路径
* @return 文件内容string
* @author 金鑫
* @version 3.0 时间:2010年1月23日 14:56:44
*/
public static String getFileContent(String path){
File file = new File(path);
//分配新的直接字节缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(186140);
StringBuffer stringBuffer = new StringBuffer(186140);
try{
FileInputStream fileInputStream = new FileInputStream(file);
//用于读取、写入、映射和操作文件的通道。
FileChannel fileChannel = fileInputStream.getChannel();
//编码字符集和字符编码方案的组合,用于处理中文,可以更改
Charset charset = Charset.forName("GBK");
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();
}
3.测试下这个方法行不行
@Test
public void test(){
String file = "D:/name.txt";
String content = getFileContent(file);
System.out.println(content);
}
输出:
TOM 100
JACK 200
BILL 50
CATHY 150
JACK 200
BILL 50
CATHY 150
ok的,我上面@Test 用了junit4.7, 没用过的你们可以换成main函数
4.数据可以读到了,应为题目中要排序,那么下一步就要把这些数据转换成集合
我这里用到了泛型, 建了一个User 实体类,存放名字和数据
package com.feilong.common.io;
/**
* 用户
*
* @author <a href="mailto:venusdrogon@163.com">金鑫</a>
* @version 1.0 2011-1-25 上午10:03:47
*/
public class User{
/**
* 姓名
*/
private String name;
/**
* 数字
*/
private int count;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getCount(){
return count;
}
public void setCount(int count){
this.count = count;
}
}
5.怎么把读到的数据转成list 呢? 这么来
讲解: 使用\r\n 把每行分割成数组
因为题目中要输出最后一句统计的字符串,所以我建了个StringBuilder 装相关数据(这地方别用+直接相连,性能不高)
@Test
public void test(){
String file = "D:/name.txt";
String content = getFileContent(file);
//将内容以换行符转成数组
String[] rowsContents = content.split("\r\n");
//内容总共行数
int rowCount = rowsContents.length;
//总和
int sum = 0;
//最后一句话的数字 (200+150+100+50)
StringBuilder lastRowOutBuilder = new StringBuilder();
//集合 存储数据,这题最快的方法是用map 存储值,考虑到 扩展(是否姓名有重复,是否以后会增加属性字段)
List<User> userList = new ArrayList<User>();
for (int i = 0; i < rowCount; i++){
String rowContent = rowsContents[i];
String[] nameAndCount = rowContent.split(" ");
User user = new User();
user.setName(nameAndCount[0]);
int count = Integer.parseInt(nameAndCount[1]);
user.setCount(count);
userList.add(user);
sum += count;
lastRowOutBuilder.append(count);
if (i != rowCount - 1){
lastRowOutBuilder.append("+");
}
}
}
最后一句话拼接技巧: 循环的最后不加+号
把这个list 可以输出测试下,数据已经进去了
6.这下要到排序了
按照数字大小排序(由大到小)
因为list 本身不能排序的,需要使用Collections.sort,需要list 以及Comparator 两个参数
新建UserComparator 类,实现Comparator 接口
我在类里面增加了 排序枚举SortType,方便扩展(要是那一天改成从小到大,只要参数变一下就可以了)
import java.util.Comparator;
/**
* user 排序
*
* @author <a href="mailto:venusdrogon@163.com">金鑫</a>
* @version 1.0 2011-1-25 上午10:48:13
*/
public class UserComparator implements Comparator{
/**
*排序方式
*
* @author <a href="mailto:venusdrogon@163.com">金鑫</a>
* @version 1.0 2011-1-25 上午10:59:02
*/
public enum SortType{
asc, desc
}
private SortType sortType;
public UserComparator(SortType sortType){
this.sortType = sortType;
}
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object arg0,Object arg1){
User user0 = (User) arg0;
User user1 = (User) arg1;
int count0 = user0.getCount();
int count1 = user1.getCount();
switch (sortType) {
case asc:
if (count0 > count1){
return 1;
}else if (count0 < count1){
return -1;
}
break;
case desc:
if (count0 > count1){
return -1;
}else if (count0 < count1){
return 1;
}
break;
default:
break;
}
return 0;
}
}
排序调用
Collections.sort(userList, new UserComparator(SortType.desc));
8.再把排序好了的list 以及最后一句话 拼接成字符串
StringBuilder builder = new StringBuilder();
for (int i = 0; i < userList.size(); i++){
User user = userList.get(i);
builder.append(user.getName());
builder.append(" ");
builder.append(user.getCount());
builder.append("\r");
}
String outString = "平均值=(" + lastRowOutBuilder.toString() + ")/" + rowCount + "=" + sum / rowCount + "";
builder.append(outString);
System.out.println(builder.toString());
9.最后到输出到 文件了
我新建了个write 方法
/**
* 将字符串写到文件中
*
* @param filePath
* 文件路径
* @param content
* 字符串内容
*/
public static void write(String filePath,String content){
try{
//向文本输出流打印对象的格式化表示形式
//会自动创建文件,替换覆盖文字(非追加)
PrintWriter printWriter = new PrintWriter(filePath);
printWriter.write(content);
printWriter.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
调用
write("D:/2.txt", builder.toString());
10. 这段完整代码
@Test
public void test(){
String file = "D:/name.txt";
String content = getFileContent(file);
//将内容以换行符转成数组
String[] rowsContents = content.split("\r\n");
//内容总共行数
int rowCount = rowsContents.length;
//总和
int sum = 0;
//最后一句话的数字 (200+150+100+50)
StringBuilder lastRowOutBuilder = new StringBuilder();
//集合 存储数据,这题最快的方法是用map 存储值,考虑到 扩展(是否姓名有重复,是否以后会增加属性字段)
List<User> userList = new ArrayList<User>();
for (int i = 0; i < rowCount; i++){
String rowContent = rowsContents[i];
String[] nameAndCount = rowContent.split(" ");
User user = new User();
user.setName(nameAndCount[0]);
int count = Integer.parseInt(nameAndCount[1]);
user.setCount(count);
userList.add(user);
sum += count;
lastRowOutBuilder.append(count);
if (i != rowCount - 1){
lastRowOutBuilder.append("+");
}
}
//排序
Collections.sort(userList, new UserComparator(SortType.desc));
StringBuilder builder = new StringBuilder();
for (int i = 0; i < userList.size(); i++){
User user = userList.get(i);
builder.append(user.getName());
builder.append(" ");
builder.append(user.getCount());
builder.append("\r");
}
String outString = "平均值=(" + lastRowOutBuilder.toString() + ")/" + rowCount + "=" + sum / rowCount + "";
builder.append(outString);
System.out.println(builder.toString());
write("D:/2.txt", builder.toString());
}
所有的完整代码,我传了附件
这是用纯java自带的类做的,当然有更简单的,比如使用common-io