问题:海量日志数据,提取出某日访问百度次数最多的那个IP。
解决办法:
1.数据量太大,采用“分而治之(hash映射)”的策略
2.将大数据根据hash法映射到不同的小文件中
3.hash map(key,value)统计每个key的的出现次数(针对划分后的小文件操作),并返回小文件中最大的一条map值
4.在所有小文件中找到最大的map值,就是最终要的访问次数最多的ip值。
注:代码中的ip值用随机数随机生成。
代码:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class text1 {
//通过随机数获得ip
public void get_IP(String filename){
try {
PrintWriter out=new PrintWriter(filename);
Random r=new Random();
for(int i=0;i<1000;i++){
String s="192.168.";
s+=r.nextInt(10)+"."+r.nextInt(10);
//System.out.println(s.hashCode());
out.println(s);
}
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//创建txt文件,并将大文件根据hashcode的值划分到10个小文件中
public void set_file(String filename){
try {
FileReader filereader=new FileReader(filename);
BufferedReader buffer=new BufferedReader(filereader);
PrintWriter[] out=new PrintWriter[10];
for(int i=0;i<10;i++){
out[i]=new PrintWriter(filename+i);
}
String IP=null;
while((IP=buffer.readLine())!=null){
IP=buffer.readLine();
int hash=IP.hashCode()%10;
hash=(hash>=0?hash:hash+10);
out[hash].println(IP);
}
for(int i=0;i<10;i++)
out[i].close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Map.Entry<String, Integer> stat(String filename){
Map.Entry<String, Integer> maxEntry=null;
try {
FileReader filereader=new FileReader(filename);
BufferedReader buffer=new BufferedReader(filereader);
//统计每个key的value值
Map<String,Integer> map=new HashMap<String,Integer>();
String IP=null;
while((IP=buffer.readLine())!=null){
IP=buffer.readLine();
if(map.containsKey(IP)){
map.put(IP, map.get(IP)+1);
}
else
map.put(IP, 1);
}
//找当前文件中出现次数最多的ip
for(Map.Entry<String, Integer> maps:map.entrySet()){
if(maxEntry==null||maps.getValue()>maxEntry.getValue()){
maxEntry=maps;
}
}
buffer.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return maxEntry;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
text1 t=new text1();
String filename="G:\\123\\123.txt";
t.get_IP(filename);
t.set_file(filename);
List<Map.Entry<String,Integer>>l=new ArrayList<Map.Entry<String,Integer>>();
for(int i=0;i<10;i++)
l.add(t.stat(filename+i));
Map.Entry<String,Integer>maxEntry=l.get(0);
for(int j=1;j<10;j++){
if(l.get(j).getValue()>maxEntry.getValue())
maxEntry=l.get(j);
}
System.out.println(maxEntry.getKey());
System.out.println(maxEntry.getValue());
}
}
代码中遇到的知识点:
1. PrintWriter
PrintWriter out= new PrintWriter(filename);
out.println(s);
out.close();
ps:多个PrintWriter
PrintWriter[] out= new PrintWriter[10];
for(int i=0;i<10;i++){
out[i]= new PrintWriter(filename+i);
}
2.随机数
Random r= new Random();
s+=r.nextInt(10)+ "."+r.nextInt(10);随机数为10以下的数
3.读文件
FileReader filereader= new FileReader(filename);
BufferedReader buffer=new BufferedReader(filereader);
while((IP=buffer.readLine())!=null)
IP=buffer.readLine();
4.计算hash值
int hash=IP.hashCode()%10;
hash=(hash>=0?hash:hash+10);
5.hashmap统计每个entry的value
Map <String,Integer> map=new HashMap<String,Integer>();
String IP= null;
while((IP=buffer.readLine())!=null){
IP=buffer.readLine();
if(map.containsKey(IP)){
map.put(IP, map.get(IP)+1);
}
else
map.put(IP, 1);
}
}
6.寻找map中value最大的entry
Map.Entry<String, Integer> maxEntry=null;
for(Map.Entry<String, Integer> maps:map.entrySet()){
if(maxEntry==null||maps.getValue()>maxEntry.getValue()){
maxEntry=map;
}
}