当前位置: 代码迷 >> J2SE >> 高分!java 依据第一个文件内容从第二个文件读取
  详细解决方案

高分!java 依据第一个文件内容从第二个文件读取

热度:191   发布时间:2016-04-24 00:38:07.0
高分!java 根据第一个文件内容从第二个文件读取
我有两个文件 一个叫id.txt
里面有很多行的数字
12
13
14
59
219
。。。
另一个叫list.txt
里面是这样的
12 [29,39,18,59]
13 [18.49,59,219]
14 [8,18,39]
59 [481]
..
希望输出的就是在list.txt里面 方括号中的信息在id.txt中也出现
比如id里面有59 那么12对应的输出应该是
12 [59]
13 [59,219]

我现在也写出来一个程序 但是速度非常慢 因为我的list.txt 大约有300M左右 而 id.txt也有10M 希望求高手帮我改进一下,或者重新写一个!在线等!

import java.io.*;
import java.util.*;
import java.lang.*;
public class trythis{ 
  public static void main(String args[])throws IOException
  File id = new File("id.txt");
  Scanner in = new Scanner(id);
  File friendship = new File("list.txt");
  Scanner inF= new Scanner(friendship);
   
  ArrayList<String> idArray = new ArrayList();
  //String [] userID;  
  //int size = 6;
  while (in.hasNextLine()){
  idArray.add(in.nextLine());  
  }
   
  String [] userFriend;
  Map<String, ArrayList> map_root = new HashMap<String, ArrayList>();
  while (inF.hasNextLine())
  {
  userFriend=inF.nextLine().split("\t");
  String friendList = userFriend[1].substring(userFriend[1].indexOf("[") + 1, userFriend[1].lastIndexOf("]"));
 
  String[] friends = friendList.split(",");
  ArrayList<String> als=new ArrayList();
  for(int i=0;i<friends.length;i++){
  als.add(friends[i]);
  }
  // System.out.println(als);
  map_root.put(userFriend[0],als);
   
  }
  // System.out.println(map_root);
  Map<String, ArrayList> map_rs = new HashMap<String, ArrayList>();
  for (String key : map_root.keySet()){
  ArrayList<String> resultList =new ArrayList(); 
  for (Iterator i = idArray.iterator(); i.hasNext();) { 
  Object temp = i.next(); 
  if (map_root.get(key).contains(temp)) { 
  resultList.add(temp.toString());
   
  } 
  map_rs.put(key, resultList);
  } 
  }  
  StringBuffer buf=new StringBuffer();
  for(String key:map_rs.keySet()){
  buf.append(key+" "+map_rs.get(key)+"\r\n");
  }
  FileOutputStream os=new FileOutputStream(new File("friends.txt"));
  os.write(buf.toString().getBytes(), 0, buf.toString().getBytes().length);  
  }
   
  }


------解决方案--------------------
几个关注点:
◎ 流式输入与流式输出,降低内存开销;
◎ 借助Hash提供快速检索,降低查找速度;
◎ 定期输出处理进度,避免盲目等待。


给点伪代码设计:
1、将id.txt中所有数字,读取入 HashSet ids 中
2、输出第一步的时间开销
3、准备一个复用的 StringBuilder sb
4、用 Scanner sc 打开 list.txt 文件
5、用 FileWriter fw 打开 friends.txt 文件
6、循环 sc.hasNextLine()
7、==拆解成字符数组friends(这里如果不拆解,直接按位处理性能更高);
8、==遍历字符数组->fid
9、----检查ids中是否存在该fid,存在则保存入sb
10、==检查sb长度是否>0
11、----将sb信息写入fw中
12、----将sb清空:sb.setLength(0)
13、==每1W笔处理,就输出一个时间
14、关闭fw,关闭sc

------解决方案--------------------
简单写了一个代码,有注释,楼主可以参考一下。
Java code
package net.csdn.bbs.mrsworf;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.util.HashSet;public class FindFriends {    interface FriendFinder{        void findFriends(File idFile, File listFile, File targetFile) throws IOException, IllegalAccessException;    }        static class EasyFriendFinder implements FriendFinder{        private boolean ignoreWrongFormat = true;//是否忽略List文件中数据的格式错误        private long wrongFormatCount = 0;//List文件中,数据格式错误的行数。        public void findFriends(File idFile, File listFile, File targetFile) throws IOException, IllegalAccessException {            // 由于ID文件大约10M,一般不会爆掉内存,所以,完全读取到内存中来            HashSet<String> idCache = new HashSet<String>();            BufferedReader reader = new BufferedReader(new FileReader(idFile));            String line = null;            try{                while((line=reader.readLine())!=null){                    if(line.trim().length()<=0)continue;                    idCache.add(line.trim());                }            }finally{                reader.close();            }            //读取List文件中的内容,同时,生成目标文件。            reader = new BufferedReader(new FileReader(listFile));            BufferedWriter writer = new BufferedWriter(new FileWriter(targetFile));            try{                while((line=reader.readLine())!=null){                    //解析List文件中每一行的数据。 样例:12 [29,39,18,59]                    int index = line.indexOf('[');//创建一个行级索引,辅助数据解析。                    int index_ = line.lastIndexOf(']');//创建另一个行级索引,辅助数据解析。                    if(index<0){                        wrongFormatCount++;                        if(ignoreWrongFormat)continue;//是否忽略List文件中数据的格式错误,如果不忽略则抛出异常,中断执行。                        else throw new IllegalAccessException("数据格式不正确,没找到'['字符:"+line);                    }                    if(index_<0){                        wrongFormatCount++;                        if(ignoreWrongFormat)continue;//是否忽略List文件中数据的格式错误,如果不忽略则抛出异常,中断执行。                        else throw new IllegalAccessException("数据格式不正确,没找到']'字符:"+line);                    }                    String id = line.substring(0,index).trim();                    String allFriends = line.substring(index+1,index_);//所有的friend_id,以逗号分开。                    String friends []  = allFriends.split("\\,|\\,");//以逗号为分隔符,拆分字符串                    writer.write(id);writer.write(' ');writer.write('[');                    for(int i=0;i<friends.length;i++){                        if(idCache.contains(friends[i].trim())){                            if(i>0)writer.write(',');                            writer.write(friends[i]);                        }                    }                    writer.write(']');writer.newLine();                }            }finally{                writer.close();                reader.close();//当writer.close()出现异常时,该语句将不会被执行,这是个BUG,楼主可以优化一下。            }        }        public boolean isIgnoreWrongFormat() {            return ignoreWrongFormat;        }        public void setIgnoreWrongFormat(boolean ignoreWrongFormat) {            this.ignoreWrongFormat = ignoreWrongFormat;        }        public long getWrongFormatCount() {            return wrongFormatCount;        }    }        /**     * 测试用例     */    public static void main(String[] args) {        final String IdFile = "id.txt";        final String ListFile = "list.txt";        final String TargetFile = "friends.txt";                FriendFinder finder = new EasyFriendFinder();        try {            finder.findFriends(new File(IdFile),new File(ListFile),new File(TargetFile));        } catch (IOException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }}
  相关解决方案